Skip to content

Instantly share code, notes, and snippets.

@basicxman
Created April 16, 2012 03:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save basicxman/2396255 to your computer and use it in GitHub Desktop.
Save basicxman/2396255 to your computer and use it in GitHub Desktop.
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
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