mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-26 05:53:39 -04:00
60 FPS and support for independent world/surface frame rates.
This commit is contained in:
parent
1b0f15b5f3
commit
af510c7cc7
6 changed files with 46 additions and 15 deletions
|
@ -210,8 +210,11 @@ class Angel
|
|||
@purgatoryTimer = null
|
||||
if @worker
|
||||
worker = @worker
|
||||
_.defer -> worker.terminate()
|
||||
@worker.removeEventListener 'message', @onWorkerMessage
|
||||
onWorkerMessage = @onWorkerMessage
|
||||
_.delay ->
|
||||
worker.terminate()
|
||||
worker.removeEventListener 'message', onWorkerMessage
|
||||
, 1000
|
||||
@worker = null
|
||||
@
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ module.exports = class LevelLoader extends CocoClass
|
|||
onSupermodelError: ->
|
||||
msg = $.i18n.t('play_level.level_load_error',
|
||||
defaultValue: "Level could not be loaded.")
|
||||
@$el.html('<div class="alert">' + msg + '</div>')
|
||||
$('body').append('<div class="alert">' + msg + '</div>')
|
||||
|
||||
onSupermodelLoadedOne: (e) ->
|
||||
@update()
|
||||
|
|
|
@ -140,8 +140,8 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@show()
|
||||
return @updateActionDirection() unless action.animation or action.container
|
||||
m = if action.container then "gotoAndStop" else "gotoAndPlay"
|
||||
@imageObject[m] action.name
|
||||
@imageObject.framerate = action.framerate or 20
|
||||
@imageObject[m] action.name
|
||||
reg = @getOffset 'registration'
|
||||
@imageObject.regX = -reg.x
|
||||
@imageObject.regY = -reg.y
|
||||
|
|
|
@ -36,6 +36,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
worldLoaded: false
|
||||
scrubbing: false
|
||||
debug: false
|
||||
frameRate: 60
|
||||
|
||||
defaults:
|
||||
wizards: true
|
||||
|
@ -190,7 +191,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
createjs.Tween.removeTweens(@)
|
||||
@currentFrame = @scrubbingTo
|
||||
|
||||
@scrubbingTo = parseInt(progress * @world.totalFrames)
|
||||
@scrubbingTo = Math.floor(progress * @world.totalFrames)
|
||||
@scrubbingPlaybackSpeed = Math.sqrt(Math.abs(@scrubbingTo - @currentFrame) * @world.dt / (scrubDuration or 0.5))
|
||||
if scrubDuration
|
||||
t = createjs.Tween
|
||||
|
@ -227,7 +228,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@onFrameChanged()
|
||||
|
||||
getCurrentFrame: ->
|
||||
return Math.max(0, Math.min(parseInt(@currentFrame), @world.totalFrames - 1))
|
||||
return Math.max(0, Math.min(Math.floor(@currentFrame), @world.totalFrames - 1))
|
||||
|
||||
getProgress: -> @currentFrame / @world.totalFrames
|
||||
|
||||
|
@ -344,8 +345,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@stage.addEventListener 'stagemousedown', @onMouseDown
|
||||
@canvas.on 'mousewheel', @onMouseWheel
|
||||
@hookUpChooseControls() if @options.choosing
|
||||
console.log "Setting fps", @world.frameRate unless @world.frameRate is 30
|
||||
createjs.Ticker.setFPS @world.frameRate
|
||||
createjs.Ticker.setFPS @frameRate
|
||||
|
||||
showLevel: ->
|
||||
return if @dead
|
||||
|
@ -467,16 +467,16 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@trailmaster.tick() if @trailmaster
|
||||
# Skip some frame updates unless we're playing and not at end (or we haven't drawn much yet)
|
||||
frameAdvanced = (@playing and @currentFrame < @world.totalFrames) or @totalFramesDrawn < 2
|
||||
++@currentFrame if frameAdvanced
|
||||
@currentFrame += @world.frameRate / @frameRate if frameAdvanced
|
||||
@updateSpriteSounds() if frameAdvanced
|
||||
break unless Dropper.drop()
|
||||
|
||||
# these are skipped for dropped frames
|
||||
@updateState @currentFrame isnt oldFrame
|
||||
@drawCurrentFrame()
|
||||
@drawCurrentFrame e
|
||||
@onFrameChanged()
|
||||
@updatePaths() if (@totalFramesDrawn % 2) is 0 or createjs.Ticker.getMeasuredFPS() > createjs.Ticker.getFPS() - 5
|
||||
Backbone.Mediator.publish('surface:ticked', {dt: @world.dt})
|
||||
@updatePaths() if (@totalFramesDrawn % 4) is 0 or createjs.Ticker.getMeasuredFPS() > createjs.Ticker.getFPS() - 5
|
||||
Backbone.Mediator.publish('surface:ticked', {dt: 1 / @frameRate})
|
||||
mib = @stage.mouseInBounds
|
||||
if @mouseInBounds isnt mib
|
||||
Backbone.Mediator.publish('surface:mouse-' + (if mib then "over" else "out"), {})
|
||||
|
@ -484,6 +484,11 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
|
||||
updateSpriteSounds: ->
|
||||
@world.getFrame(@getCurrentFrame()).restoreState()
|
||||
current = Math.max(0, Math.min(@currentFrame, @world.totalFrames - 1))
|
||||
if current - Math.floor(current) > 0.01
|
||||
next = Math.ceil current
|
||||
ratio = current % 1
|
||||
@world.frames[next].restorePartialState ratio if next > 1
|
||||
@spriteBoss.updateSounds()
|
||||
|
||||
updateState: (frameChanged) ->
|
||||
|
@ -492,9 +497,9 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@spriteBoss.update frameChanged
|
||||
@dimmer?.setSprites @spriteBoss.sprites
|
||||
|
||||
drawCurrentFrame: ->
|
||||
drawCurrentFrame: (e) ->
|
||||
++@totalFramesDrawn
|
||||
@stage.update()
|
||||
@stage.update e
|
||||
|
||||
# paths - TODO: move to SpriteBoss? but only update on frame drawing instead of on every frame update?
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ module.exports = class ThangState
|
|||
|
||||
restore: ->
|
||||
# Restore trackedProperties' values to @thang, retrieving them from @trackedPropertyValues if needed. Optimize it.
|
||||
return @ if @thang._state is @
|
||||
return @ if @thang._state is @ and not @thang.partialState
|
||||
unless @hasRestored # Restoring in a deserialized World for first time
|
||||
props = []
|
||||
for prop, propIndex in @trackedPropertyKeys
|
||||
|
@ -81,6 +81,26 @@ module.exports = class ThangState
|
|||
else # Restoring later times
|
||||
for prop, propIndex in @trackedPropertyKeys
|
||||
@thang[prop] = @props[propIndex]
|
||||
@thang.partialState = false
|
||||
@
|
||||
|
||||
restorePartial: (ratio) ->
|
||||
inverse = 1 - ratio
|
||||
for prop, propIndex in @trackedPropertyKeys when prop is "pos" or prop is "rotation"
|
||||
if @hasRestored
|
||||
value = @props[propIndex]
|
||||
else
|
||||
type = @trackedPropertyTypes[propIndex]
|
||||
storage = @trackedPropertyValues[propIndex]
|
||||
value = @getStoredProp propIndex, type, storage
|
||||
if prop is "pos"
|
||||
@thang.pos = @thang.pos.copy()
|
||||
@thang.pos.x = inverse * @thang.pos.x + ratio * value.x
|
||||
@thang.pos.y = inverse * @thang.pos.y + ratio * value.y
|
||||
@thang.pos.z = inverse * @thang.pos.z + ratio * value.z
|
||||
else if prop is "rotation"
|
||||
@thang.rotation = inverse * @thang.rotation + ratio * value
|
||||
@thang.partialState = true
|
||||
@
|
||||
|
||||
serialize: (frameIndex, trackedPropertyIndices, trackedPropertyTypes, trackedPropertyValues, specialValuesToKeys, specialKeysToValues) ->
|
||||
|
|
|
@ -25,6 +25,9 @@ module.exports = class WorldFrame
|
|||
#console.log "Frame", @time, "restoring state for", thang.id, "and saying it don't exist"
|
||||
thang.exists = false
|
||||
|
||||
restorePartialState: (ratio) ->
|
||||
thangState.restorePartial ratio for thangID, thangState of @thangStateMap
|
||||
|
||||
restoreStateForThang: (thang) ->
|
||||
thangState = @thangStateMap[thang.id]
|
||||
if not thangState
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue