Migrating surface to webgl. It sorta works!

This commit is contained in:
Scott Erickson 2014-09-25 10:47:53 -07:00
parent 358b36c1bf
commit c7e7066aef
11 changed files with 136 additions and 82 deletions

View file

@ -204,15 +204,15 @@ module.exports = class LevelLoader extends CocoClass
nameModelMap = _.zipObject nameModelTuples nameModelMap = _.zipObject nameModelTuples
@spriteSheetsToBuild ?= [] @spriteSheetsToBuild ?= []
for thangTypeName in thangsToLoad # for thangTypeName in thangsToLoad
thangType = nameModelMap[thangTypeName] # thangType = nameModelMap[thangTypeName]
continue if not thangType or thangType.isFullyLoaded() # continue if not thangType or thangType.isFullyLoaded()
thangType.fetch() # thangType.fetch()
thangType = @supermodel.loadModel(thangType, 'thang').model # thangType = @supermodel.loadModel(thangType, 'thang').model
res = @supermodel.addSomethingResource 'sprite_sheet', 5 # res = @supermodel.addSomethingResource 'sprite_sheet', 5
res.thangType = thangType # res.thangType = thangType
res.markLoading() # res.markLoading()
@spriteSheetsToBuild.push res # @spriteSheetsToBuild.push res
@buildLoopInterval = setInterval @buildLoop, 5 if @spriteSheetsToBuild.length @buildLoopInterval = setInterval @buildLoop, 5 if @spriteSheetsToBuild.length

View file

@ -93,6 +93,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@scaleFactorX = @thang.scaleFactor if @thang?.scaleFactor? @scaleFactorX = @thang.scaleFactor if @thang?.scaleFactor?
@scaleFactorY = @thang.scaleFactorY if @thang?.scaleFactorY? @scaleFactorY = @thang.scaleFactorY if @thang?.scaleFactorY?
@scaleFactorY = @thang.scaleFactor if @thang?.scaleFactor? @scaleFactorY = @thang.scaleFactor if @thang?.scaleFactor?
@updateAction() unless @currentAction
setImageObject: (newImageObject) -> setImageObject: (newImageObject) ->
if @imageObject if @imageObject
@ -108,6 +109,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@imageObject = newImageObject @imageObject = newImageObject
@configureMouse() @configureMouse()
@imageObject.on 'animationend', @playNextAction @imageObject.on 'animationend', @playNextAction
@playAction(@currentAction) if @currentAction and not @stillLoading
@trigger 'new-image-object', @imageObject @trigger 'new-image-object', @imageObject
################################################## ##################################################
@ -115,7 +117,6 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
queueAction: (action) -> queueAction: (action) ->
# The normal way to have an action play # The normal way to have an action play
return unless @thangType.isFullyLoaded()
action = @actions[action] if _.isString(action) action = @actions[action] if _.isString(action)
action ?= @actions.idle action ?= @actions.idle
@actionQueue = [] @actionQueue = []
@ -362,7 +363,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
################################################## ##################################################
updateAction: -> updateAction: ->
return if @isRaster return if @isRaster or @actionLocked
action = @determineAction() action = @determineAction()
isDifferent = action isnt @currentRootAction or action is null isDifferent = action isnt @currentRootAction or action is null
if not action and @thang?.actionActivated and not @stopLogging if not action and @thang?.actionActivated and not @stopLogging
@ -391,6 +392,8 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
return unless action = @getActionDirection() return unless action = @getActionDirection()
@playAction(action) if action isnt @currentAction @playAction(action) if action isnt @currentAction
lockAction: -> (@actionLocked=true)
getActionDirection: (rootAction=null) -> getActionDirection: (rootAction=null) ->
rootAction ?= @currentRootAction rootAction ?= @currentRootAction
return null unless relatedActions = rootAction?.relatedActions ? {} return null unless relatedActions = rootAction?.relatedActions ? {}

View file

@ -43,7 +43,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
buildAutomatically: true buildAutomatically: true
buildAsync: true buildAsync: true
resolutionFactor: SPRITE_RESOLUTION_FACTOR resolutionFactor: SPRITE_RESOLUTION_FACTOR
defaultActions: ['idle', 'die', 'move', 'move_back', 'move_side', 'move_fore', 'attack'] defaultActions: ['idle', 'die', 'move', 'move', 'attack']
numThingsLoading: 0 numThingsLoading: 0
cocoSprites: null cocoSprites: null
spriteSheet: null spriteSheet: null
@ -165,7 +165,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
removeCocoSprite: (cocoSprite) -> removeCocoSprite: (cocoSprite) ->
@stopListening(cocoSprite) @stopListening(cocoSprite)
cocoSprite.imageObject.parent.removeChild cocoSprite.imageObject @container.removeChild cocoSprite.imageObject
@cocoSprites = _.without @cocoSprites, cocoSprite @cocoSprites = _.without @cocoSprites, cocoSprite
#- Loading network resources dynamically #- Loading network resources dynamically
@ -200,7 +200,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
@upsertActionToRender(cocoSprite.thangType) @upsertActionToRender(cocoSprite.thangType)
else else
for action in _.values(cocoSprite.thangType.getActions()) for action in _.values(cocoSprite.thangType.getActions())
continue unless action.name in @defaultActions continue unless _.any @defaultActions, (prefix) -> action.name.startsWith(prefix)
@upsertActionToRender(cocoSprite.thangType, action.name, cocoSprite.options.colorConfig) @upsertActionToRender(cocoSprite.thangType, action.name, cocoSprite.options.colorConfig)
upsertActionToRender: (thangType, actionName, colorConfig) -> upsertActionToRender: (thangType, actionName, colorConfig) ->
@ -284,6 +284,8 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
oldLayer = @container oldLayer = @container
@container = new createjs.SpriteContainer(@spriteSheet) @container = new createjs.SpriteContainer(@spriteSheet)
for cocoSprite in @cocoSprites for cocoSprite in @cocoSprites
console.log 'zombie sprite found on layer', @name if cocoSprite.destroyed
continue if cocoSprite.destroyed
@setImageObjectToCocoSprite(cocoSprite) @setImageObjectToCocoSprite(cocoSprite)
for prop in ['scaleX', 'scaleY', 'regX', 'regY'] for prop in ['scaleX', 'scaleY', 'regX', 'regY']
@container[prop] = oldLayer[prop] @container[prop] = oldLayer[prop]
@ -436,6 +438,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
if not cocoSprite.thangType.isFullyLoaded() if not cocoSprite.thangType.isFullyLoaded()
# just give a placeholder # just give a placeholder
sprite = new createjs.Sprite(@spriteSheet) sprite = new createjs.Sprite(@spriteSheet)
sprite.placeholder = true
else if cocoSprite.thangType.get('raster') else if cocoSprite.thangType.get('raster')
sprite = new createjs.Sprite(@spriteSheet) sprite = new createjs.Sprite(@spriteSheet)
@ -445,7 +448,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
sprite.gotoAndStop(@renderGroupingKey(cocoSprite.thangType)) sprite.gotoAndStop(@renderGroupingKey(cocoSprite.thangType))
else else
SpriteClass = if cocoSprite.thangType.get('spriteType') is 'segmented' then SegmentedSprite else SingularSprite SpriteClass = if (cocoSprite.thangType.get('spriteType') or @defaultSpriteType) is 'segmented' then SegmentedSprite else SingularSprite
prefix = @renderGroupingKey(cocoSprite.thangType, null, cocoSprite.colorConfig) + '.' prefix = @renderGroupingKey(cocoSprite.thangType, null, cocoSprite.colorConfig) + '.'
sprite = new SpriteClass(@spriteSheet, cocoSprite.thangType, prefix, @resolutionFactor) sprite = new SpriteClass(@spriteSheet, cocoSprite.thangType, prefix, @resolutionFactor)

View file

@ -24,7 +24,9 @@ module.exports = class Mark extends CocoClass
destroy: -> destroy: ->
createjs.Tween.removeTweens @mark if @mark createjs.Tween.removeTweens @mark if @mark
@mark?.parent?.removeChild @mark @mark?.parent?.removeChild @mark
@markSprite?.destroy() if @markSprite
@layer.removeCocoSprite(@markSprite)
@markSprite.destroy()
@sprite = null @sprite = null
super() super()

View file

@ -13,7 +13,7 @@ module.exports = class SegmentedSprite extends createjs.SpriteContainer
# CreateJS.Sprite-like interface # CreateJS.Sprite-like interface
play: -> @paused = false play: -> @paused = false unless @baseMovieClip and @animLength > 1
stop: -> @paused = true stop: -> @paused = true
gotoAndPlay: (actionName) -> @goto(actionName, false) gotoAndPlay: (actionName) -> @goto(actionName, false)
gotoAndStop: (actionName) -> @goto(actionName, true) gotoAndStop: (actionName) -> @goto(actionName, true)
@ -21,7 +21,7 @@ module.exports = class SegmentedSprite extends createjs.SpriteContainer
goto: (actionName, @paused=true) -> goto: (actionName, @paused=true) ->
@removeAllChildren() @removeAllChildren()
@currentAnimation = actionName @currentAnimation = actionName
@baseMovieClip = @framerate = null @baseMovieClip = @framerate = @animLength = null
@actionNotSupported = false @actionNotSupported = false
action = @thangType.getActions()[actionName] action = @thangType.getActions()[actionName]
@ -39,7 +39,8 @@ module.exports = class SegmentedSprite extends createjs.SpriteContainer
@baseMovieClip = @buildMovieClip(action.animation) @baseMovieClip = @buildMovieClip(action.animation)
@frames = action.frames @frames = action.frames
@frames = (parseInt(f) for f in @frames.split(',')) if @frames @frames = (parseInt(f) for f in @frames.split(',')) if @frames
@animLength = if @frames then @frames.length else @baseMovieClip.frameBounds.length @animLength = if @frames then @frames.length else @baseMovieClip.timeline.duration
@paused = true if @animLength is 1
@currentFrame = if randomStart then Math.floor(Math.random() * @animLength) else 0 @currentFrame = if randomStart then Math.floor(Math.random() * @animLength) else 0
@baseMovieClip.gotoAndStop(@currentFrame) @baseMovieClip.gotoAndStop(@currentFrame)
movieClip.gotoAndStop(@currentFrame) for movieClip in @childMovieClips movieClip.gotoAndStop(@currentFrame) for movieClip in @childMovieClips
@ -88,6 +89,7 @@ module.exports = class SegmentedSprite extends createjs.SpriteContainer
buildMovieClip: (animationName, mode, startPosition, loops) -> buildMovieClip: (animationName, mode, startPosition, loops) ->
raw = @thangType.get('raw') raw = @thangType.get('raw')
animData = raw.animations[animationName] animData = raw.animations[animationName]
@lastAnimData = animData
movieClip = new createjs.MovieClip() movieClip = new createjs.MovieClip()
locals = {} locals = {}
@ -107,7 +109,7 @@ module.exports = class SegmentedSprite extends createjs.SpriteContainer
for func in tweenData for func in tweenData
args = $.extend(true, [], (func.a)) args = $.extend(true, [], (func.a))
if @dereferenceArgs(args, locals, toSkip) is false if @dereferenceArgs(args, locals, toSkip) is false
console.debug 'Did not dereference args:', args # console.debug 'Did not dereference args:', args
stopped = true stopped = true
break break
tween = tween[func.n](args...) tween = tween[func.n](args...)
@ -236,5 +238,5 @@ module.exports = class SegmentedSprite extends createjs.SpriteContainer
@addChild(child) @addChild(child)
getBounds: -> # _getBounds: createjs.SpriteContainer.prototype.getBounds
@baseMovieClip.getBounds() # getBounds: -> @baseMovieClip?.getBounds() or @children[0]?.getBounds() or @_getBounds()

View file

@ -66,7 +66,7 @@ module.exports = class SingularSprite extends createjs.Sprite
@scaleX = @scaleY = 1 / @resolutionFactor @scaleX = @scaleY = 1 / @resolutionFactor
if @camera and @thangType.get('name') in floors if @camera and @thangType.get('name') in floors
@baseScaleY *= @options.camera.y2x @baseScaleY *= @camera.y2x
@scaleX *= -1 if action.flipX @scaleX *= -1 if action.flipX
@scaleY *= -1 if action.flipY @scaleY *= -1 if action.flipY
@baseScaleX = @scaleX @baseScaleX = @scaleX

View file

@ -33,7 +33,7 @@ module.exports = class SpriteBoss extends CocoClass
@dragged = 0 @dragged = 0
@options ?= {} @options ?= {}
@camera = @options.camera @camera = @options.camera
@surfaceLayer = @options.surfaceLayer @webGLStage = @options.webGLStage
@surfaceTextLayer = @options.surfaceTextLayer @surfaceTextLayer = @options.surfaceTextLayer
@world = options.world @world = options.world
@options.thangTypes ?= [] @options.thangTypes ?= []
@ -65,7 +65,7 @@ module.exports = class SpriteBoss extends CocoClass
['Floating', 10] ['Floating', 10]
] ]
@spriteLayers[name] = new LayerAdapter name: name, webGL: true, layerPriority: priority, transform: LayerAdapter.TRANSFORM_CHILD, camera: @camera @spriteLayers[name] = new LayerAdapter name: name, webGL: true, layerPriority: priority, transform: LayerAdapter.TRANSFORM_CHILD, camera: @camera
@surfaceLayer.addChild (spriteLayer.container for spriteLayer in _.values(@spriteLayers))... @webGLStage.addChild (spriteLayer.container for spriteLayer in _.values(@spriteLayers))...
layerForChild: (child, sprite) -> layerForChild: (child, sprite) ->
unless child.layerPriority? unless child.layerPriority?
@ -185,6 +185,7 @@ module.exports = class SpriteBoss extends CocoClass
sprite.update frameChanged for sprite in @spriteArray sprite.update frameChanged for sprite in @spriteArray
@updateSelection() @updateSelection()
@spriteLayers['Default'].updateLayerOrder() @spriteLayers['Default'].updateLayerOrder()
@cacheObstacles()
adjustSpriteExistence: -> adjustSpriteExistence: ->
# Add anything new, remove anything old, update everything current # Add anything new, remove anything old, update everything current
@ -206,6 +207,7 @@ module.exports = class SpriteBoss extends CocoClass
updatedObstacles.push sprite if isObstacle and (missing or sprite.hasMoved) updatedObstacles.push sprite if isObstacle and (missing or sprite.hasMoved)
sprite.hasMoved = false sprite.hasMoved = false
@removeSprite sprite if missing @removeSprite sprite if missing
@cacheObstacles updatedObstacles if updatedObstacles.length and @cachedObstacles
# mainly for handling selecting thangs from session when the thang is not always in existence # mainly for handling selecting thangs from session when the thang is not always in existence
if @willSelectThang and @sprites[@willSelectThang[0]] if @willSelectThang and @sprites[@willSelectThang[0]]
@ -226,6 +228,26 @@ module.exports = class SpriteBoss extends CocoClass
itemsJustEquipped.push item itemsJustEquipped.push item
return itemsJustEquipped return itemsJustEquipped
cacheObstacles: (updatedObstacles=null) ->
return if @cachedObstacles and not updatedObstacles
wallSprites = (sprite for sprite in @spriteArray when sprite.thangType?.get('name').search(/(dungeon|indoor).wall/i) isnt -1)
return if _.any (s.stillLoading for s in wallSprites)
walls = (sprite.thang for sprite in wallSprites)
@world.calculateBounds()
wallGrid = new Grid walls, @world.size()...
if updatedObstacles
possiblyUpdatedWallSprites = (sprite for sprite in wallSprites when _.find updatedObstacles, (w2) -> sprite is w2 or (Math.abs(sprite.thang.pos.x - w2.thang.pos.x) + Math.abs(sprite.thang.pos.y - w2.thang.pos.y)) <= 16)
else
possiblyUpdatedWallSprites = wallSprites
#console.log 'updating up to', possiblyUpdatedWallSprites.length, 'of', wallSprites.length, 'wall sprites from updatedObstacles', updatedObstacles
for wallSprite in possiblyUpdatedWallSprites
wallSprite.updateActionDirection wallGrid
wallSprite.lockAction()
wallSprite.updateScale()
wallSprite.updatePosition()
#console.log @wallGrid.toString()
@cachedObstacles = true
spriteFor: (thangID) -> @sprites[thangID] spriteFor: (thangID) -> @sprites[thangID]
onNewWorld: (e) -> onNewWorld: (e) ->

View file

@ -22,7 +22,7 @@ MusicPlayer = require './MusicPlayer'
module.exports = Surface = class Surface extends CocoClass module.exports = Surface = class Surface extends CocoClass
stage: null stage: null
layers: null normalLayers: null
surfaceLayer: null surfaceLayer: null
surfaceTextLayer: null surfaceTextLayer: null
screenLayer: null screenLayer: null
@ -81,9 +81,9 @@ module.exports = Surface = class Surface extends CocoClass
#- Initialization #- Initialization
constructor: (@world, @canvas, givenOptions) -> constructor: (@world, @normalCanvas, @webGLCanvas, givenOptions) ->
super() super()
@layers = [] @normalLayers = []
@options = _.clone(@defaults) @options = _.clone(@defaults)
@options = _.extend(@options, givenOptions) if givenOptions @options = _.extend(@options, givenOptions) if givenOptions
@initEasel() @initEasel()
@ -94,28 +94,32 @@ module.exports = Surface = class Surface extends CocoClass
_.defer => @setWorld @world _.defer => @setWorld @world
initEasel: -> initEasel: ->
@stage = new createjs.Stage(@canvas[0]) # Takes DOM objects, not jQuery objects. @normalStage = new createjs.Stage(@normalCanvas[0])
canvasWidth = parseInt @canvas.attr('width'), 10 @webGLStage = new createjs.SpriteStage(@webGLCanvas[0])
canvasHeight = parseInt @canvas.attr('height'), 10 @camera = AudioPlayer.camera = new Camera @webGLCanvas
@camera = AudioPlayer.camera = new Camera @canvas
@layers.push @surfaceLayer = new Layer name: 'Surface', layerPriority: 0, transform: Layer.TRANSFORM_SURFACE, camera: @camera @normalLayers.push @surfaceTextLayer = new Layer name: 'Surface Text', layerPriority: 1, transform: Layer.TRANSFORM_SURFACE_TEXT, camera: @camera
@layers.push @surfaceTextLayer = new Layer name: 'Surface Text', layerPriority: 1, transform: Layer.TRANSFORM_SURFACE_TEXT, camera: @camera @normalLayers.push @gridLayer = new Layer name: 'Grid', layerPriority: 2, transform: Layer.TRANSFORM_SURFACE, camera: @camera
@layers.push @gridLayer = new Layer name: 'Grid', layerPriority: 2, transform: Layer.TRANSFORM_SURFACE, camera: @camera @normalLayers.push @screenLayer = new Layer name: 'Screen', layerPriority: 3, transform: Layer.TRANSFORM_SCREEN, camera: @camera
@layers.push @screenLayer = new Layer name: 'Screen', layerPriority: 3, transform: Layer.TRANSFORM_SCREEN, camera: @camera @normalLayers.push @cameraBorderLayer = new Layer name: 'Camera Border', layerPriority: 4, transform: Layer.TRANSFORM_SURFACE, camera: @camera
@stage.addChild @layers... @cameraBorderLayer.addChild @cameraBorder = new CameraBorder(bounds: @camera.bounds)
@surfaceLayer.addChild @cameraBorder = new CameraBorder bounds: @camera.bounds @normalStage.addChild @normalLayers...
canvasWidth = parseInt @normalCanvas.attr('width'), 10
canvasHeight = parseInt @normalCanvas.attr('height'), 10
@screenLayer.addChild new Letterbox canvasWidth: canvasWidth, canvasHeight: canvasHeight @screenLayer.addChild new Letterbox canvasWidth: canvasWidth, canvasHeight: canvasHeight
@spriteBoss = new SpriteBoss camera: @camera, surfaceLayer: @surfaceLayer, surfaceTextLayer: @surfaceTextLayer, world: @world, thangTypes: @options.thangTypes, choosing: @options.choosing, navigateToSelection: @options.navigateToSelection, showInvisible: @options.showInvisible
@spriteBoss = new SpriteBoss camera: @camera, webGLStage: @webGLStage, surfaceTextLayer: @surfaceTextLayer, world: @world, thangTypes: @options.thangTypes, choosing: @options.choosing, navigateToSelection: @options.navigateToSelection, showInvisible: @options.showInvisible
@countdownScreen = new CountdownScreen camera: @camera, layer: @screenLayer @countdownScreen = new CountdownScreen camera: @camera, layer: @screenLayer
@playbackOverScreen = new PlaybackOverScreen camera: @camera, layer: @screenLayer @playbackOverScreen = new PlaybackOverScreen camera: @camera, layer: @screenLayer
@waitingScreen = new WaitingScreen camera: @camera, layer: @screenLayer @waitingScreen = new WaitingScreen camera: @camera, layer: @screenLayer
@initCoordinates() @initCoordinates()
@stage.enableMouseOver(10) @webGLStage.enableMouseOver(10)
@stage.addEventListener 'stagemousemove', @onMouseMove @webGLStage.addEventListener 'stagemousemove', @onMouseMove
@stage.addEventListener 'stagemousedown', @onMouseDown @webGLStage.addEventListener 'stagemousedown', @onMouseDown
@canvas[0].addEventListener 'mouseup', @onMouseUp @webGLCanvas[0].addEventListener 'mouseup', @onMouseUp
@canvas.on 'mousewheel', @onMouseWheel @webGLStage.on 'mousewheel', @onMouseWheel
@hookUpChooseControls() if @options.choosing @hookUpChooseControls() if @options.choosing # TODO: figure this stuff out
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED
createjs.Ticker.setFPS @options.frameRate createjs.Ticker.setFPS @options.frameRate
@onResize() @onResize()
@ -126,7 +130,7 @@ module.exports = Surface = class Surface extends CocoClass
@coordinateDisplay ?= new CoordinateDisplay camera: @camera, layer: @surfaceTextLayer if @world.showCoordinates or @options.coords @coordinateDisplay ?= new CoordinateDisplay camera: @camera, layer: @surfaceTextLayer if @world.showCoordinates or @options.coords
hookUpChooseControls: -> hookUpChooseControls: ->
chooserOptions = stage: @stage, surfaceLayer: @surfaceLayer, camera: @camera, restrictRatio: @options.choosing is 'ratio-region' chooserOptions = stage: @normalStage, surfaceLayer: @surfaceLayer, camera: @camera, restrictRatio: @options.choosing is 'ratio-region'
klass = if @options.choosing is 'point' then PointChooser else RegionChooser klass = if @options.choosing is 'point' then PointChooser else RegionChooser
@chooser = new klass chooserOptions @chooser = new klass chooserOptions
@ -201,7 +205,7 @@ module.exports = Surface = class Surface extends CocoClass
@onFrameChanged() @onFrameChanged()
@updatePaths() if (@totalFramesDrawn % 4) is 0 or createjs.Ticker.getMeasuredFPS() > createjs.Ticker.getFPS() - 5 @updatePaths() if (@totalFramesDrawn % 4) is 0 or createjs.Ticker.getMeasuredFPS() > createjs.Ticker.getFPS() - 5
Backbone.Mediator.publish('surface:ticked', {dt: 1 / @options.frameRate}) Backbone.Mediator.publish('surface:ticked', {dt: 1 / @options.frameRate})
mib = @stage.mouseInBounds mib = @webGLStage.mouseInBounds
if @mouseInBounds isnt mib if @mouseInBounds isnt mib
Backbone.Mediator.publish('surface:mouse-' + (if mib then 'over' else 'out'), {}) Backbone.Mediator.publish('surface:mouse-' + (if mib then 'over' else 'out'), {})
@mouseInBounds = mib @mouseInBounds = mib
@ -225,8 +229,8 @@ module.exports = Surface = class Surface extends CocoClass
drawCurrentFrame: (e) -> drawCurrentFrame: (e) ->
++@totalFramesDrawn ++@totalFramesDrawn
@stage.update e # @normalStage.update e
@webGLStage.update e
#- Setting play/pause and progress #- Setting play/pause and progress
@ -459,7 +463,7 @@ module.exports = Surface = class Surface extends CocoClass
return if @disabled return if @disabled
cap = @camera.screenToCanvas({x: e.stageX, y: e.stageY}) cap = @camera.screenToCanvas({x: e.stageX, y: e.stageY})
# getObject(s)UnderPoint is broken, so we have to use the private method to get what we want # getObject(s)UnderPoint is broken, so we have to use the private method to get what we want
onBackground = not @stage._getObjectsUnderPoint(e.stageX, e.stageY, null, true) onBackground = not @webGLStage._getObjectsUnderPoint(e.stageX, e.stageY, null, true)
wop = @camera.screenToWorld x: e.stageX, y: e.stageY wop = @camera.screenToWorld x: e.stageX, y: e.stageY
event = onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e, worldPos: wop event = onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e, worldPos: wop
@ -468,7 +472,7 @@ module.exports = Surface = class Surface extends CocoClass
onMouseUp: (e) => onMouseUp: (e) =>
return if @disabled return if @disabled
onBackground = not @stage.hitTest e.stageX, e.stageY onBackground = not @webGLStage.hitTest e.stageX, e.stageY
Backbone.Mediator.publish 'surface:stage-mouse-up', onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e Backbone.Mediator.publish 'surface:stage-mouse-up', onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e
Backbone.Mediator.publish 'tome:focus-editor', {} Backbone.Mediator.publish 'tome:focus-editor', {}
@ -479,7 +483,7 @@ module.exports = Surface = class Surface extends CocoClass
event = event =
deltaX: e.deltaX deltaX: e.deltaX
deltaY: e.deltaY deltaY: e.deltaY
canvas: @canvas canvas: @webGLCanvas
event.screenPos = @mouseScreenPos if @mouseScreenPos event.screenPos = @mouseScreenPos if @mouseScreenPos
Backbone.Mediator.publish 'surface:mouse-scrolled', event unless @disabled Backbone.Mediator.publish 'surface:mouse-scrolled', event unless @disabled
@ -489,8 +493,8 @@ module.exports = Surface = class Surface extends CocoClass
onResize: (e) => onResize: (e) =>
return if @destroyed or @options.choosing return if @destroyed or @options.choosing
oldWidth = parseInt @canvas.attr('width'), 10 oldWidth = parseInt @normalCanvas.attr('width'), 10
oldHeight = parseInt @canvas.attr('height'), 10 oldHeight = parseInt @normalCanvas.attr('height'), 10
aspectRatio = oldWidth / oldHeight aspectRatio = oldWidth / oldHeight
pageWidth = $('#page-container').width() - 17 # 17px nano scroll bar pageWidth = $('#page-container').width() - 17 # 17px nano scroll bar
if @realTime or @options.spectateGame if @realTime or @options.spectateGame
@ -507,12 +511,12 @@ module.exports = Surface = class Surface extends CocoClass
##if InstallTrigger? # Firefox rendering performance goes down as canvas size goes up ##if InstallTrigger? # Firefox rendering performance goes down as canvas size goes up
## newWidth = Math.min 924, newWidth ## newWidth = Math.min 924, newWidth
## newHeight = Math.min 589, newHeight ## newHeight = Math.min 589, newHeight
#@canvas.width newWidth #@normalCanvas.width newWidth
#@canvas.height newHeight #@normalCanvas.height newHeight
scaleFactor = if application.isIPadApp then 2 else 1 # Retina scaleFactor = if application.isIPadApp then 2 else 1 # Retina
@canvas.attr width: newWidth * scaleFactor, height: newHeight * scaleFactor @normalCanvas.add(@webGLCanvas).attr width: newWidth * scaleFactor, height: newHeight * scaleFactor
@stage.scaleX *= newWidth / oldWidth @webGLStage.scaleX = @normalStage.scaleX *= newWidth / oldWidth
@stage.scaleY *= newHeight / oldHeight @webGLStage.scaleY = @normalStage.scaleY *= newHeight / oldHeight
@camera.onResize newWidth, newHeight @camera.onResize newWidth, newHeight
@ -534,10 +538,10 @@ module.exports = Surface = class Surface extends CocoClass
@realTime = false @realTime = false
@onResize() @onResize()
@spriteBoss.selfWizardSprite?.toggle true @spriteBoss.selfWizardSprite?.toggle true
@canvas.removeClass 'flag-color-selected' @normalCanvas.add(@webGLCanvas).removeClass 'flag-color-selected'
onFlagColorSelected: (e) -> onFlagColorSelected: (e) ->
@canvas.toggleClass 'flag-color-selected', Boolean(e.color) @normalCanvas.add(@webGLCanvas).toggleClass 'flag-color-selected', Boolean(e.color)
e.pos = @camera.screenToWorld @mouseScreenPos if @mouseScreenPos e.pos = @camera.screenToWorld @mouseScreenPos if @mouseScreenPos
@ -545,6 +549,7 @@ module.exports = Surface = class Surface extends CocoClass
#- Paths - TODO: move to SpriteBoss? but only update on frame drawing instead of on every frame update? #- Paths - TODO: move to SpriteBoss? but only update on frame drawing instead of on every frame update?
updatePaths: -> updatePaths: ->
return # TODO: Get paths working again with WebGL
return unless @options.paths return unless @options.paths
return if @casting return if @casting
@hidePaths() @hidePaths()
@ -560,7 +565,8 @@ module.exports = Surface = class Surface extends CocoClass
hidePaths: -> hidePaths: ->
return if not @paths return if not @paths
@paths.parent.removeChild @paths if @paths.parent
@paths.parent.removeChild @paths
@paths = null @paths = null
@ -568,15 +574,16 @@ module.exports = Surface = class Surface extends CocoClass
#- Screenshot #- Screenshot
screenshot: (scale=0.25, format='image/jpeg', quality=0.8, zoom=2) -> screenshot: (scale=0.25, format='image/jpeg', quality=0.8, zoom=2) ->
# TODO: get screenshots working again
# Quality doesn't work with image/png, just image/jpeg and image/webp # Quality doesn't work with image/png, just image/jpeg and image/webp
[w, h] = [@camera.canvasWidth, @camera.canvasHeight] [w, h] = [@camera.canvasWidth, @camera.canvasHeight]
margin = (1 - 1 / zoom) / 2 margin = (1 - 1 / zoom) / 2
@stage.cache margin * w, margin * h, w / zoom, h / zoom, scale * zoom @webGLStage.cache margin * w, margin * h, w / zoom, h / zoom, scale * zoom
imageData = @stage.cacheCanvas.toDataURL(format, quality) imageData = @webGLStage.cacheCanvas.toDataURL(format, quality)
#console.log 'Screenshot with scale', scale, 'format', format, 'quality', quality, 'was', Math.floor(imageData.length / 1024), 'kB' #console.log 'Screenshot with scale', scale, 'format', format, 'quality', quality, 'was', Math.floor(imageData.length / 1024), 'kB'
screenshot = document.createElement('img') screenshot = document.createElement('img')
screenshot.src = imageData screenshot.src = imageData
@stage.uncache() @webGLStage.uncache()
imageData imageData
@ -650,7 +657,7 @@ module.exports = Surface = class Surface extends CocoClass
@camera?.destroy() @camera?.destroy()
createjs.Ticker.removeEventListener('tick', @tick) createjs.Ticker.removeEventListener('tick', @tick)
createjs.Sound.stop() createjs.Sound.stop()
layer.destroy() for layer in @layers layer.destroy() for layer in @normalLayers
@spriteBoss.destroy() @spriteBoss.destroy()
@chooser?.destroy() @chooser?.destroy()
@dimmer?.destroy() @dimmer?.destroy()
@ -659,16 +666,19 @@ module.exports = Surface = class Surface extends CocoClass
@waitingScreen?.destroy() @waitingScreen?.destroy()
@coordinateDisplay?.destroy() @coordinateDisplay?.destroy()
@coordinateGrid?.destroy() @coordinateGrid?.destroy()
@stage.clear() @normalStage.clear()
@webGLStage.clear()
@musicPlayer?.destroy() @musicPlayer?.destroy()
@stage.removeAllChildren() @normalStage.removeAllChildren()
@stage.removeEventListener 'stagemousemove', @onMouseMove @webGLStage.removeAllChildren()
@stage.removeEventListener 'stagemousedown', @onMouseDown @webGLStage.removeEventListener 'stagemousemove', @onMouseMove
@stage.removeEventListener 'stagemouseup', @onMouseUp @webGLStage.removeEventListener 'stagemousedown', @onMouseDown
@stage.removeAllEventListeners() @webGLStage.removeEventListener 'stagemouseup', @onMouseUp
@stage.enableDOMEvents false @webGLStage.removeAllEventListeners()
@stage.enableMouseOver 0 @normalStage.enableDOMEvents false
@canvas.off 'mousewheel', @onMouseWheel @webGLStage.enableDOMEvents false
@webGLStage.enableMouseOver 0
@webGLStage.off 'mousewheel', @onMouseWheel
$(window).off 'resize', @onResize $(window).off 'resize', @onResize
clearTimeout @surfacePauseTimeout if @surfacePauseTimeout clearTimeout @surfacePauseTimeout if @surfacePauseTimeout
clearTimeout @surfaceZoomPauseTimeout if @surfaceZoomPauseTimeout clearTimeout @surfaceZoomPauseTimeout if @surfaceZoomPauseTimeout

View file

@ -17,7 +17,7 @@ $level-resize-transition-time: 0.5s
#canvas-wrapper #canvas-wrapper
width: 100% width: 100%
canvas#surface canvas
margin: 0 auto margin: 0 auto
#control-bar-view #control-bar-view
width: 100% width: 100%
@ -53,10 +53,20 @@ $level-resize-transition-time: 0.5s
overflow: hidden overflow: hidden
@include transition($level-resize-transition-time ease-out) @include transition($level-resize-transition-time ease-out)
canvas#surface canvas#webgl-surface
background-color: #333 background-color: #333
display: block
z-index: 1 z-index: 1
canvas#normal-surface
z-index: 1
position: absolute
top: 0
left: 0
pointer-events: none
canvas#webgl-surface, canvas#normal-surface
display: block
z-index: 2
@include transition($level-resize-transition-time ease-out) @include transition($level-resize-transition-time ease-out)
&.flag-color-selected &.flag-color-selected
@ -260,6 +270,6 @@ body.ipad #level-view
#canvas-wrapper #canvas-wrapper
height: 653px height: 653px
canvas#surface canvas
margin: 0 auto margin: 0 auto
overflow: hidden overflow: hidden

View file

@ -10,7 +10,8 @@
#tome-view #tome-view
#canvas-wrapper #canvas-wrapper
canvas(width=924, height=589)#surface canvas(width=924, height=589)#webgl-surface
canvas(width=924, height=589)#normal-surface
#canvas-left-gradient.gradient #canvas-left-gradient.gradient
#canvas-top-gradient.gradient #canvas-top-gradient.gradient
#goals-view.secret #goals-view.secret

View file

@ -305,8 +305,9 @@ module.exports = class PlayLevelView extends RootView
storage.save 'recently-played-matches', allRecentlyPlayedMatches storage.save 'recently-played-matches', allRecentlyPlayedMatches
initSurface: -> initSurface: ->
surfaceCanvas = $('canvas#surface', @$el) webGLSurface = $('canvas#webgl-surface', @$el)
@surface = new Surface(@world, surfaceCanvas, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview) normalSurface = $('canvas#normal-surface', @$el)
@surface = new Surface(@world, normalSurface, webGLSurface, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview)
worldBounds = @world.getBounds() worldBounds = @world.getBounds()
bounds = [{x: worldBounds.left, y: worldBounds.top}, {x: worldBounds.right, y: worldBounds.bottom}] bounds = [{x: worldBounds.left, y: worldBounds.top}, {x: worldBounds.right, y: worldBounds.bottom}]
@surface.camera.setBounds(bounds) @surface.camera.setBounds(bounds)