Skip to content

Commit

Permalink
updated physics engine to simplify and recompiled rainflow
Browse files Browse the repository at this point in the history
  • Loading branch information
dannyko committed Sep 14, 2014
1 parent 8cfb438 commit 5a1098a
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 88 deletions.
8 changes: 4 additions & 4 deletions src/game/objects/abstract/element.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ class $z.Element
$z.Utils.set(@, config) if config?
@ # return this element instance

update: (elapsedTime) -> # helper to combine these three operations into one loop for efficiency
@tick?(@, elapsedTime) # the physics function takes the instance (self) as an input argument to avoid making unnecessary closures or deep-copies of the function
@draw()
return
# update: (elapsedTime) -> # helper to combine these three operations into one loop for efficiency
# @tick?(@, elapsedTime) # the physics function takes the instance (self) as an input argument to avoid making unnecessary closures or deep-copies of the function
# @draw()
# return

scale: (scalingFactor = 10, dur = undefined, callback = ->) ->
if dur?
Expand Down
66 changes: 34 additions & 32 deletions src/physics/modules/physics.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ class $z.Physics # numerical integration module for solving differential equatio
@fps = 240 # set physics framerate to be 4x the standard requestAnimationFrame rate (60 fps) to reduce the likelihood large per-frame displacements (jumps)
@elapsedTime = 0 # keeps track of how much time has elapsed since the last animation frame was called
@tick = 1000 / Physics.fps # the natural/target frame length/duration for this game/visualization (per web animation standards)
@maxElapsedTime = 100 * @tick # longest allowed duration between frames
@Nstep = 2
@off = true # a boolean switch determining whether or not to run the physics engine
@game = null # initialize reference to game instance associated with the physics engine
@callbacks = []
Expand Down Expand Up @@ -36,47 +38,41 @@ class $z.Physics # numerical integration module for solving differential equatio
@integrate = (t) ->
return true if Physics.off
# requestAnimFrame(Physics.integrate) # keep running the loop
elapsedTime = t - Physics.timestamp
Physics.elapsedTime = elapsedTime
if Physics.debug
fps = 1000 / elapsedTime # instantaneous frames per second (noisy)
console.log('Physics.integrate:', 'dt: ', elapsedTime, 't: ', t, 'timestamp: ', Physics.timestamp, 'dt_chk: ', t - Physics.timestamp, 'fps: ' + fps)
Physics.timestamp = t
Physics.update(elapsedTime)
return Physics.off

@update = (elapsedTime = Physics.elapsedTime) ->
Nstep = 2 # Math.floor(elapsedTime / Physics.tick) # compute number of integral steps to take (slower computer implies more physics steps per frame)
Nmax = 600
if Nstep > Nmax
Physics.elapsedTime = t - Physics.timestamp
if Physics.elapsedTime > Physics.maxElapsedTime
dur = 2000
Physics.stop()
$z.Game.instance.message(
'CPU SPEED ERROR'
-> $z.Game.instance.stop()
dur
)
step = 0 # initialize step counter
while step < Nstep # adjust the number of steps to take depending on the machine speed - slower machines should take more steps to maintain game difficulty
Physics.step()
$z.Collision.detect() # detect all collisions between active elements and execute their corresonding reactions
Physics.run_callbacks()
++step
# fractional time step:
#error = (elapsedTime - Nstep * Physics.tick) / Physics.tick # relative error in animation speed due to noise
#dt = Physics.tick * error # scale timestep of physics to compensate for noise in framerate
#Physics.step(dt)
if Physics.debug
fps = 1000 / elapsedTime # instantaneous frames per second (noisy)
console.log('Physics.integrate:', 'dt: ', elapsedTime, 't: ', t, 'timestamp: ', Physics.timestamp, 'dt_chk: ', t - Physics.timestamp, 'fps: ' + fps)
Physics.timestamp = t
Physics.update()
return Physics.off

@update = ->
Physics.step()
$z.Collision.detect() # detect all collisions between active elements and execute their corresonding reactions
Physics.draw_all()
Physics.run_callbacks()

@step = (elapsedTime = Physics.tick) -> # one full step of the physics engine - update all elements, resolve collisions, etc.
index = $z.Collision.list.length # update after requestAnimFrame to match 60 fps most closely when falling back to setTimeout (see http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/)
while (index--) # iterate backwards to avoid indexing/variable array length issues, caused by removing elements from the array as we go
if $z.Collision.list[index].is_removed
$z.Utils.index_pop($z.Collision.list, index).sleep() # place this element into the object pool for potential reuse later
else
$z.Collision.list[index].update(elapsedTime)
if Physics.debug
console.log('Physics.update', 'index:', index, 'fps:', fps, 'r.x:', $z.Collision.list[index].r.x, 'r.y:', $z.Collision.list[index].r.y)
@step = () -> # one full step of the physics engine - update all elements, resolve collisions, etc.
stepCount = 0
while stepCount < Physics.Nstep
stepCount++
index = $z.Collision.list.length # update after requestAnimFrame to match 60 fps most closely when falling back to setTimeout (see http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/)
while (index--) # iterate backwards to avoid indexing/variable array length issues, caused by removing elements from the array as we go
if $z.Collision.list[index].is_removed
$z.Utils.index_pop($z.Collision.list, index).sleep() # place this element into the object pool for potential reuse later
else
element = $z.Collision.list[index]
element.tick(element, Physics.elapsedTime / Physics.Nstep)
if Physics.debug
console.log('Physics.update', 'index:', index, 'fps:', fps, 'r.x:', $z.Collision.list[index].r.x, 'r.y:', $z.Collision.list[index].r.y)

@run_callbacks = ->
index = Physics.callbacks.length
Expand All @@ -85,6 +81,12 @@ class $z.Physics # numerical integration module for solving differential equatio
bool = Physics.callbacks[index](Physics.timestamp) # execute the callback
$z.Utils.index_pop(Physics.callbacks, index) if bool # returning a value of true means we can remove this callback

@draw_all = ->
index = $z.Collision.list.length
while (index--) # backwards to avoid reindexing issues from splice inside element.cleanup()
element = $z.Collision.list[index]
element.draw()

@start = ->
return unless Physics.off # don't start twice
Physics.off = false
Expand Down
104 changes: 53 additions & 51 deletions test/rainflow/lib/rainflow.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion test/rainflow/src/rainflow.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ class $z.Rainflow extends $z.Game
new_drop = ->
$z.Factory.spawn($z.Drop, config.pop()).start()
if config.length is 0
console.log('clearing')
clear()
$z.Game.instance.raining = false
int = setInterval(new_drop, dur)
Expand Down

0 comments on commit 5a1098a

Please sign in to comment.