Created
April 16, 2012 03:45
-
-
Save basicxman/2396255 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class GameEngine | |
constructor: -> | |
@bg = document.getElementById("bg").getContext("2d") | |
@fg = document.getElementById("fg").getContext("2d") | |
@gW = 5000 | |
@gH = 3750 | |
@vW = @fg.canvas.width | |
@vH = @fg.canvas.height | |
@dX = (@gW - @vW) / -2 | |
@dY = (@gH - @vH) / -2 | |
@decay = 1.05 | |
@panMultiplier = -8 | |
@deadband = 0.005 | |
@objects = [] | |
this.addEventListeners() | |
this.initCanvas() | |
this.startAnimation() | |
@game = new Game(this) | |
# Game initialization. | |
addEventListeners: -> | |
@fg.canvas.addEventListener "mousedown", (e) => | |
this.mouseDown(e) | |
@fg.canvas.addEventListener "mousemove", (e) => | |
this.mouseMove(e) | |
for event in ["mouseup", "mouseout"] | |
@fg.canvas.addEventListener event, ((e) => this.resetDrag()) | |
initCanvas: -> | |
@bg.canvas.style.background = "#000" | |
startAnimation: -> | |
anim = => | |
this.update() | |
this.draw() | |
requestAnimFrame(anim) | |
anim() | |
# Events | |
mouseDown: (e) -> | |
# Only the left mouse button should be used for dragging. | |
if e.button != 0 | |
return | |
# Regardless of whether we reach a drag event in 100mS, momentum should | |
# stop from any previous pan event. | |
@velX = @velY = undefined | |
@timeout = setTimeout((=> this.startDrag(e)), 100) | |
mouseMove: (e) -> | |
if not @isDragging | |
return | |
# Store a circular buffer of three movement events, using the current event | |
# and previous event isn't representative enough for velocity calculations. | |
this.bufferAdvance(@bufDragTime, e.timeStamp) | |
this.bufferAdvance(@bufDragX, e.offsetX) | |
this.bufferAdvance(@bufDragY, e.offsetY) | |
if @bufDragX[2]? and @bufDragX[1]? | |
this.pan(@bufDragX[1] - @bufDragX[2], @bufDragY[1] - @bufDragY[2]) | |
startDrag: -> | |
@isDragging = true | |
this.bufferReset() | |
resetDrag: -> | |
if @bufDragTime? and @bufDragTime[0]? and @bufDragTime[2]? | |
t = @bufDragTime[2] - @bufDragTime[0] | |
rise = @bufDragY[2] - @bufDragY[0] | |
run = @bufDragX[2] - @bufDragX[0] | |
@velX = run / t | |
@velY = rise / t | |
clearTimeout(@timeout) | |
@isDragging = false | |
this.bufferReset() | |
pan: (x, y) -> | |
# Change position offset and ensure map boundaries are met. | |
@dX = Math.min(Math.max(@dX - x, -(@gW - @vW)), 0) | |
@dY = Math.min(Math.max(@dY - y, -(@gH - @vH)), 0) | |
# Update current viewport coordinates and ask objects to update their draw | |
# state. | |
@vX1 = -@dX | |
@vY1 = -@dY | |
@vX2 = @vX1 + @vW | |
@vY2 = @vY1 + @vH | |
for obj in @objects | |
obj.checkIfInScene() | |
panMomentum: -> | |
if @velX == undefined or @velY == undefined | |
return | |
this.pan(@panMultiplier * @velX, @panMultiplier * @velY) | |
@velX /= @decay | |
@velY /= @decay | |
if (Math.abs(@velX) < @deadband) | |
@velX = undefined | |
if (Math.abs(@velY) < @deadband) | |
@velY = undefined | |
# Utilities | |
bufferReset: -> | |
@bufDragTime = [undefined, undefined, undefined] | |
@bufDragX = [undefined, undefined, undefined] | |
@bufDragY = [undefined, undefined, undefined] | |
bufferAdvance: (buffer, value) -> | |
buffer[0] = buffer[1] | |
buffer[1] = buffer[2] | |
buffer[2] = value | |
# Periodic calls. | |
update: -> | |
this.panMomentum() | |
for object in @objects | |
if object.inScene or object.updateOffScene | |
object.update() | |
draw: -> | |
@fg.clearRect(0, 0, @vW, @vH) | |
for object in @objects | |
if object.inScene | |
object.draw(@fg) | |
window.game = new GameEngine |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SpaceStation extends GameObject | |
constructor: (engine) -> | |
super(engine) | |
@health = 1000 | |
@width = 100 | |
@height = 100 | |
@x = engine.gW / 2 - @width / 2 | |
@y = engine.gH / 2 - @height / 2 | |
checkIfInScene: -> | |
@inScene = (@x >= @engine.vX1 - @width / 2) and (@x < @engine.vX2 + @width / 2) and (@y >= @engine.vY1 - @height / 2) and (@y < @engine.vY2 + @height / 2) | |
update: -> | |
return | |
draw: (ctx) -> | |
vX = @x - Math.abs(@engine.dX) | |
vY = @y - Math.abs(@engine.dY) | |
ctx.save() | |
ctx.strokeStyle = "rgba(119, 187, 255, 0.5)" | |
ctx.translate(vX, vY) | |
ctx.rotate(Math.PI / 4) | |
ctx.beginPath() | |
ctx.arc(0, 0, 10, 0, Math.PI * 2, true) | |
ctx.stroke() | |
ctx.strokeRect(@width / -2, @height / -2, @width, @height) | |
ctx.restore() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment