diff --git a/app/lib/surface/CocoSprite.coffee b/app/lib/surface/CocoSprite.coffee index 20a5581a0..680677019 100644 --- a/app/lib/surface/CocoSprite.coffee +++ b/app/lib/surface/CocoSprite.coffee @@ -105,7 +105,6 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass if parent = @imageObject.parent parent.removeChild @imageObject parent.addChild newImageObject - parent.updateLayerOrder() # get the cocosprite to update things for prop in ['lastPos', 'currentRootAction'] diff --git a/app/lib/surface/Layer.coffee b/app/lib/surface/Layer.coffee index d640a813b..e69de29bb 100644 --- a/app/lib/surface/Layer.coffee +++ b/app/lib/surface/Layer.coffee @@ -1,127 +0,0 @@ -### -* Stage -** surfaceLayer -*** Land texture -*** Ground-based selection/target marks, range radii -*** Walls/obstacles -*** Paths and target pieces (and ghosts?) -*** Normal Thangs, bots, wizards (z-indexing based on World-determined sprite.thang.pos.z/y, mainly, instead of sprite-map-determined sprite.z, which we rename to... something) -*** Above-thang marks (blood, highlight) and health bars -*** Camera border -** surfaceTextLayer (speech, names) -** screenLayer -*** Letterbox -**** Letterbox top and bottom -*** FPS display, maybe grid axis labels, coordinate hover - -** Grid lines--somewhere--we will figure it out, do not really need it at first -### - -layerClassProperties = { - TRANSFORM_CHILD: 'child' # Layer transform is managed by its parents - TRANSFORM_SURFACE: 'surface' # Layer moves/scales/zooms with the Surface of the World - TRANSFORM_SURFACE_TEXT: 'surface_text' # Layer moves with the Surface but is size-independent - TRANSFORM_SCREEN: 'screen' # Layer stays fixed to the screen (different from child?) -} - -layerProperties = { - subscriptions: - 'camera:zoom-updated': 'onZoomUpdated' - - initializeLayer: (options) -> - options ?= {} - @name = options.name ? 'Unnamed' - @layerPriority = options.layerPriority ? 0 - @transformStyle = options.transform ? layerClassProperties.TRANSFORM_CHILD - @camera = options.camera - @updateLayerOrder = _.bind(@updateLayerOrder, @) - @updateLayerOrder = _.throttle @updateLayerOrder, 1000 / 30 # Don't call multiple times in one frame; 30 FPS is probably good enough - Backbone.Mediator.subscribe(channel, @[func], @) for channel, func of @subscriptions - - destroy: -> - child.destroy?() for child in @children - Backbone.Mediator.unsubscribe(channel, @[func], @) for channel, func of @subscriptions - delete @updateLayerOrder - - toString: -> "" - - updateLayerOrder: -> - @sortChildren @layerOrderComparator - - layerOrderComparator: (a, b) -> - # Optimize - alp = a.layerPriority or 0 - blp = b.layerPriority or 0 - return alp - blp if alp isnt blp - # TODO: remove this z stuff - az = a.z or 1000 - bz = b.z or 1000 - if aSprite = a.sprite - if aThang = aSprite.thang - aPos = aThang.pos - if aThang.health < 0 - --az - if bSprite = b.sprite - if bThang = bSprite.thang - bPos = bThang.pos - if bThang.health < 0 - --bz - if az is bz - return 0 unless aPos and bPos - return (bPos.y - aPos.y) or (bPos.x - aPos.x) - return az - bz - - onZoomUpdated: (e) -> - return unless e.camera is @camera - if @transformStyle in [layerClassProperties.TRANSFORM_SURFACE, layerClassProperties.TRANSFORM_SURFACE_TEXT, layerClassProperties.TRANSFORM_CHILD] - change = @scaleX / e.zoom - @scaleX = @scaleY = e.zoom - @regX = e.surfaceViewport.x - @regY = e.surfaceViewport.y - if @transformStyle is layerClassProperties.TRANSFORM_SURFACE_TEXT - for child in @children - child.scaleX *= change - child.scaleY *= change - -} - - -class ContainerLayer extends createjs.Container - constructor: (options) -> - super() - @initialize() - @initializeLayer(options) - - addChild: (children...) -> - super children... - if @transformStyle is ContainerLayer.TRANSFORM_SURFACE_TEXT - for child in children - child.scaleX /= @scaleX - child.scaleY /= @scaleY - - removeChild: (children...) -> - super children... - if @transformStyle is ContainerLayer.TRANSFORM_SURFACE_TEXT - for child in children - child.scaleX *= @scaleX - child.scaleY *= @scaleY - - cache: -> - return unless @children.length - bounds = @getBounds() - return unless bounds - super bounds.x, bounds.y, bounds.width, bounds.height, 2 - -class SpriteContainerLayer extends createjs.SpriteContainer - constructor: (spriteSheet, options) -> - super(spriteSheet) - @initialize(spriteSheet) - @initializeLayer(options) - -_.extend(ContainerLayer.prototype, layerProperties) -_.extend(SpriteContainerLayer.prototype, layerProperties) -_.extend(ContainerLayer, layerClassProperties) -_.extend(SpriteContainerLayer, layerClassProperties) - -module.exports.ContainerLayer = ContainerLayer -module.exports.SpriteContainerLayer = SpriteContainerLayer diff --git a/app/lib/surface/LayerAdapter.coffee b/app/lib/surface/LayerAdapter.coffee index 5ed02c15d..0766ac69f 100644 --- a/app/lib/surface/LayerAdapter.coffee +++ b/app/lib/surface/LayerAdapter.coffee @@ -1,15 +1,41 @@ +### + * SpriteStage (WebGL Canvas) + ** Land texture + ** Ground-based selection/target marks, range radii + ** Walls/obstacles + ** Paths and target pieces (and ghosts?) + ** Normal Thangs, bots, wizards (z-indexing based on World-determined sprite.thang.pos.z/y, mainly, instead of sprite-map-determined sprite.z, which we rename to... something) + ** Above-thang marks (blood, highlight) and health bars + + * Stage (Regular Canvas) + ** Camera border + ** surfaceTextLayer (speech, names) + ** screenLayer + *** Letterbox + **** Letterbox top and bottom + *** FPS display, maybe grid axis labels, coordinate hover + + ** Grid lines--somewhere--we will figure it out, do not really need it at first +### + SpriteBuilder = require 'lib/sprites/SpriteBuilder' CocoClass = require 'lib/CocoClass' SegmentedSprite = require './SegmentedSprite' SingularSprite = require './SingularSprite' -{SpriteContainerLayer} = require 'lib/surface/Layer' NEVER_RENDER_ANYTHING = false # set to true to test placeholders -module.exports = class LayerAdapter extends CocoClass +module.exports = LayerAdapter = class LayerAdapter extends CocoClass + + # Intermediary between a Surface Stage and a top-level static normal Container or hot-swapped WebGL SpriteContainer. + # It handles zooming in different ways and, if webGL, creating and assigning spriteSheets. - _.extend(LayerAdapter.prototype, Backbone.Events) + @TRANSFORM_CHILD: 'child' # Layer transform is managed by its parents + @TRANSFORM_SURFACE: 'surface' # Layer moves/scales/zooms with the Surface of the World + @TRANSFORM_SURFACE_TEXT: 'surface_text' # Layer moves with the Surface but is size-independent + @TRANSFORM_SCREEN: 'screen' # Layer stays fixed to the screen (different from child?) + # WebGL properties actionRenderState: null needToRerender: false toRenderBundles: null @@ -21,28 +47,105 @@ module.exports = class LayerAdapter extends CocoClass numThingsLoading: 0 cocoSprites: null spriteSheet: null - spriteContainer: null - - constructor: (@layerOptions) -> - @layerOptions ?= {} + container: null + + subscriptions: + 'camera:zoom-updated': 'onZoomUpdated' + + constructor: (options) -> super() - @initializing = true - @spriteSheet = @_renderNewSpriteSheet(false) # builds an empty spritesheet - @spriteContainer = new SpriteContainerLayer(@spriteSheet, @layerOptions) - @actionRenderState = {} - @toRenderBundles = [] - @cocoSprites = [] - @initializing = false + options ?= {} + @name = options.name ? 'Unnamed' + @layerPriority = options.layerPriority ? 0 + @transformStyle = options.transform ? LayerAdapter.TRANSFORM_CHILD + @camera = options.camera + @updateLayerOrder = _.throttle @updateLayerOrder, 1000 / 30 # Don't call multiple times in one frame; 30 FPS is probably good enough + + @webGL = !!options.webGL + if @webGL + @initializing = true + @spriteSheet = @_renderNewSpriteSheet(false) # builds an empty spritesheet + @container = new createjs.SpriteContainer(@spriteSheet) + @actionRenderState = {} + @toRenderBundles = [] + @cocoSprites = [] + @initializing = false + + else + @container = new createjs.Container() + + toString: -> "" + + #- Layer ordering - setDefaultActions: (@defaultActions) -> - - renderGroupingKey: (thangType, grouping, colorConfig) -> - key = thangType.get('slug') - if colorConfig?.team - key += "(#{colorConfig.team.hue},#{colorConfig.team.saturation},#{colorConfig.team.lightness})" - key += '.'+grouping if grouping - key + updateLayerOrder: -> + @container.sortChildren @layerOrderComparator + + layerOrderComparator: (a, b) -> + # Optimize + alp = a.layerPriority or 0 + blp = b.layerPriority or 0 + return alp - blp if alp isnt blp + # TODO: remove this z stuff + az = a.z or 1000 + bz = b.z or 1000 + if aSprite = a.sprite + if aThang = aSprite.thang + aPos = aThang.pos + if aThang.health < 0 + --az + if bSprite = b.sprite + if bThang = bSprite.thang + bPos = bThang.pos + if bThang.health < 0 + --bz + if az is bz + return 0 unless aPos and bPos + return (bPos.y - aPos.y) or (bPos.x - aPos.x) + return az - bz + #- Zoom updating + + onZoomUpdated: (e) -> + return unless e.camera is @camera + if @transformStyle in [LayerAdapter.TRANSFORM_SURFACE, LayerAdapter.TRANSFORM_SURFACE_TEXT, LayerAdapter.TRANSFORM_CHILD] + change = @container.scaleX / e.zoom + @container.scaleX = @container.scaleY = e.zoom + @container.regX = e.surfaceViewport.x + @container.regY = e.surfaceViewport.y + if @transformStyle is LayerAdapter.TRANSFORM_SURFACE_TEXT + for child in @container.children + child.scaleX *= change + child.scaleY *= change + + #- Caching + + cache: -> + return if @webGL + return unless @children.length + bounds = @container.getBounds() + return unless bounds + @container.cache bounds.x, bounds.y, bounds.width, bounds.height, 2 + + #- Container-like child functions + + addChild: (children...) -> + container.addChild children... + if @transformStyle is ContainerLayer.TRANSFORM_SURFACE_TEXT + for child in children + child.scaleX /= @scaleX + child.scaleY /= @scaleY + + removeChild: (children...) -> + container.removeChild children... + # TODO: Do we actually need to scale children that were removed? + if @transformStyle is ContainerLayer.TRANSFORM_SURFACE_TEXT + for child in children + child.scaleX *= @scaleX + child.scaleY *= @scaleY + + #- Adding, removing children for WebGL layers. + addCocoSprite: (cocoSprite) -> cocoSprite.options.resolutionFactor = @resolutionFactor if cocoSprite.layer @@ -55,16 +158,15 @@ module.exports = class LayerAdapter extends CocoClass @loadThangType(cocoSprite.thangType) @addDefaultActionsToRender(cocoSprite) @setImageObjectToCocoSprite(cocoSprite) - # TODO: actually add it as a child - + @updateLayerOrder() + removeCocoSprite: (cocoSprite) -> @stopListening(cocoSprite) cocoSprite.imageObject.parent.removeChild cocoSprite.imageObject @cocoSprites = _.without @cocoSprites, cocoSprite - onActionNeedsRender: (cocoSprite, action) -> - @upsertActionToRender(cocoSprite.thangType, action.name, cocoSprite.options.colorConfig) - + #- Loading network resources dynamically + loadThangType: (thangType) -> if not thangType.isFullyLoaded() thangType.setProjection null @@ -84,6 +186,11 @@ module.exports = class LayerAdapter extends CocoClass @addDefaultActionsToRender(cocoSprite) @renderNewSpriteSheet() + #- Adding to the list of things we need to render + + onActionNeedsRender: (cocoSprite, action) -> + @upsertActionToRender(cocoSprite.thangType, action.name, cocoSprite.options.colorConfig) + addDefaultActionsToRender: (cocoSprite) -> needToRender = false if cocoSprite.thangType.get('raster') @@ -102,6 +209,8 @@ module.exports = class LayerAdapter extends CocoClass @willRender = _.defer => @renderNewSpriteSheet() return true + #- Rendering sprite sheets + renderNewSpriteSheet: -> @willRender = false return if @numThingsLoading @@ -126,11 +235,11 @@ module.exports = class LayerAdapter extends CocoClass args = [thangType, colorConfig, actionNames, builder] if thangType.get('raw') if thangType.get('spriteType') is 'segmented' - @renderContainers(args...) + @renderSegmentedThangType(args...) else - @renderSpriteSheet(args...) + @renderSingularThangType(args...) else - @renderRasterImage(thangType, builder) + @renderRasterThangType(thangType, builder) if async builder.buildAsync() @@ -140,17 +249,6 @@ module.exports = class LayerAdapter extends CocoClass @onBuildSpriteSheetComplete(null, builder) return sheet - createPlaceholder: -> - # TODO: Experiment with this. Perhaps have rectangles if default layer is obstacle or floor, - # and different colors for different layers. - g = new createjs.Graphics() - g.setStrokeStyle(5) - g.beginStroke(createjs.Graphics.getRGB(64,64,64)) - g.beginFill(createjs.Graphics.getRGB(64,64,64,0.7)) - radius = @resolutionFactor*SPRITE_PLACEHOLDER_RADIUS - g.drawCircle(radius, radius, radius) - new createjs.Shape(g) - onBuildSpriteSheetComplete: (e, builder) -> return if @initializing @@ -162,18 +260,18 @@ module.exports = class LayerAdapter extends CocoClass @spriteSheet = builder.spriteSheet @spriteSheet.resolutionFactor = @resolutionFactor - oldLayer = @spriteContainer - @spriteContainer = new SpriteContainerLayer(@spriteSheet, @layerOptions) + oldLayer = @container + @container = new createjs.SpriteContainer(@spriteSheet) for cocoSprite in @cocoSprites @setImageObjectToCocoSprite(cocoSprite) for prop in ['scaleX', 'scaleY', 'regX', 'regY'] - @spriteContainer[prop] = oldLayer[prop] + @container[prop] = oldLayer[prop] if parent = oldLayer.parent index = parent.getChildIndex(oldLayer) parent.removeChildAt(index) - parent.addChildAt(@spriteContainer, index) - @layerOptions.camera?.updateZoom(true) - @spriteContainer.updateLayerOrder() + parent.addChildAt(@container, index) + @camera?.updateZoom(true) + @updateLayerOrder() for cocoSprite in @cocoSprites cocoSprite.options.resolutionFactor = @resolutionFactor cocoSprite.updateBaseScale() @@ -181,7 +279,22 @@ module.exports = class LayerAdapter extends CocoClass cocoSprite.updateRotation() @trigger 'new-spritesheet' - renderContainers: (thangType, colorConfig, actionNames, spriteSheetBuilder) -> + #- Placeholder + + createPlaceholder: -> + # TODO: Experiment with this. Perhaps have rectangles if default layer is obstacle or floor, + # and different colors for different layers. + g = new createjs.Graphics() + g.setStrokeStyle(5) + g.beginStroke(createjs.Graphics.getRGB(64,64,64)) + g.beginFill(createjs.Graphics.getRGB(64,64,64,0.7)) + radius = @resolutionFactor*SPRITE_PLACEHOLDER_RADIUS + g.drawCircle(radius, radius, radius) + new createjs.Shape(g) + + #- Rendering containers for segmented thang types + + renderSegmentedThangType: (thangType, colorConfig, actionNames, spriteSheetBuilder) -> containersToRender = {} for actionName in actionNames action = _.find(thangType.getActions(), {name: actionName}) @@ -208,8 +321,10 @@ module.exports = class LayerAdapter extends CocoClass for animation in thangType.get('raw').animations[animation].animations containers = containers.concat(@getContainersForAnimation(thangType, animation.gn)) return containers + + #- Rendering sprite sheets for singular thang types - renderSpriteSheet: (thangType, colorConfig, actionNames, spriteSheetBuilder) -> + renderSingularThangType: (thangType, colorConfig, actionNames, spriteSheetBuilder) -> actionObjects = _.values(thangType.getActions()) animationActions = [] for a in actionObjects @@ -283,8 +398,10 @@ module.exports = class LayerAdapter extends CocoClass next = action.goesTo if action.goesTo next = false if action.loops is false return next + + #- Rendering frames for raster thang types - renderRasterImage: (thangType, spriteSheetBuilder) -> + renderRasterThangType: (thangType, spriteSheetBuilder) -> unless thangType.rasterImage console.error("Cannot render the LayerAdapter SpriteSheet until the raster image for <#{thangType.get('name')}> is loaded.") @@ -292,6 +409,8 @@ module.exports = class LayerAdapter extends CocoClass scale = thangType.get('scale') or 1 frame = spriteSheetBuilder.addFrame(bm, null, scale) spriteSheetBuilder.addAnimation(@renderGroupingKey(thangType), [frame], false) + + #- Distributing new Segmented/Singular/RasterSprites to CocoSprites setImageObjectToCocoSprite: (cocoSprite) -> if not cocoSprite.thangType.isFullyLoaded() @@ -316,4 +435,15 @@ module.exports = class LayerAdapter extends CocoClass cocoSprite.addHealthBar() cocoSprite.setImageObject(sprite) cocoSprite.update(true) - @spriteContainer.addChild(sprite) \ No newline at end of file + @container.addChild(sprite) + + renderGroupingKey: (thangType, grouping, colorConfig) -> + key = thangType.get('slug') + if colorConfig?.team + key += "(#{colorConfig.team.hue},#{colorConfig.team.saturation},#{colorConfig.team.lightness})" + key += '.'+grouping if grouping + key + + destroy: -> + child.destroy?() for child in @container.children + super() \ No newline at end of file diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee index 88a06a6e6..9d25fd61b 100644 --- a/app/lib/surface/SpriteBoss.coffee +++ b/app/lib/surface/SpriteBoss.coffee @@ -1,6 +1,6 @@ CocoClass = require 'lib/CocoClass' {me} = require 'lib/auth' -Layer = require './LayerAdapter' +LayerAdapter = require './LayerAdapter' IndieSprite = require 'lib/surface/IndieSprite' WizardSprite = require 'lib/surface/WizardSprite' FlagSprite = require 'lib/surface/FlagSprite' @@ -65,8 +65,8 @@ module.exports = class SpriteBoss extends CocoClass ['Default', 0] ['Floating', 10] ] - @spriteLayers[name] = new Layer name: name, layerPriority: priority, transform: Layer.TRANSFORM_CHILD, camera: @camera - @surfaceLayer.addChild (spriteLayer.spriteContainer for spriteLayer in _.values(@spriteLayers))... + @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))... layerForChild: (child, sprite) -> unless child.layerPriority? @@ -77,7 +77,7 @@ module.exports = class SpriteBoss extends CocoClass child.layerPriority ?= 0 return @spriteLayers['Default'] unless child.layerPriority layer = _.findLast @spriteLayers, (layer, name) -> - layer.spriteContainer.layerPriority <= child.layerPriority + layer.layerPriority <= child.layerPriority layer ?= @spriteLayers['Land'] if child.layerPriority < -40 layer ? @spriteLayers['Default'] @@ -89,7 +89,7 @@ module.exports = class SpriteBoss extends CocoClass layer ?= @spriteLayers['Obstacle'] if sprite.thang?.spriteName.search(/(dungeon|indoor).wall/i) isnt -1 layer ?= @layerForChild sprite.imageObject, sprite layer.addCocoSprite sprite - layer.spriteContainer.updateLayerOrder() + layer.updateLayerOrder() sprite createMarks: -> @@ -185,7 +185,7 @@ module.exports = class SpriteBoss extends CocoClass @adjustSpriteExistence() if frameChanged sprite.update frameChanged for sprite in @spriteArray @updateSelection() - @spriteLayers['Default'].spriteContainer.updateLayerOrder() + @spriteLayers['Default'].updateLayerOrder() @cache() adjustSpriteExistence: -> diff --git a/test/app/lib/surface/LayerAdapter.spec.coffee b/test/app/lib/surface/LayerAdapter.spec.coffee index 2e589a827..b89d2877f 100644 --- a/test/app/lib/surface/LayerAdapter.spec.coffee +++ b/test/app/lib/surface/LayerAdapter.spec.coffee @@ -8,7 +8,7 @@ SpriteBuilder = require 'lib/sprites/SpriteBuilder' describe 'LayerAdapter', -> layer = null beforeEach -> - layer = new LayerAdapter() + layer = new LayerAdapter({webGL:true}) layer.buildAutomatically = false layer.buildAsync = false @@ -47,7 +47,7 @@ describe 'LayerAdapter', -> expect(key in sheet.getAnimations()).toBe(true) it 'only renders frames used by actions when spriteType=singular', -> - layer.setDefaultActions(['idle']) # uses the move side animation + layer.defaultActions = ['idle'] # uses the move side animation ogreMunchkinThangType.set('spriteType', 'singular') colorConfig = {team: {hue: 0, saturation: 1, lightness: 0.5}} sprite = new CocoSprite(ogreMunchkinThangType, {colorConfig: colorConfig}) diff --git a/test/app/lib/surface/SegmentedSprite.spec.coffee b/test/app/lib/surface/SegmentedSprite.spec.coffee index 31e8f6a9d..d811fc522 100644 --- a/test/app/lib/surface/SegmentedSprite.spec.coffee +++ b/test/app/lib/surface/SegmentedSprite.spec.coffee @@ -26,7 +26,7 @@ describe 'SegmentedSprite', -> describe 'with Ogre Munchkin ThangType', -> beforeEach -> - layer = new LayerAdapter() + layer = new LayerAdapter({webGL:true}) layer.buildAutomatically = false layer.buildAsync = false ogreMunchkinThangType.markToRevert() @@ -82,7 +82,7 @@ describe 'SegmentedSprite', -> describe 'with Ogre Fangrider ThangType', -> beforeEach -> - layer = new LayerAdapter() + layer = new LayerAdapter({webGL:true}) layer.buildAutomatically = false layer.buildAsync = false ogreFangriderThangType.markToRevert() diff --git a/test/app/lib/surface/SingularSprite.spec.coffee b/test/app/lib/surface/SingularSprite.spec.coffee index d1dd103a4..cba39bb99 100644 --- a/test/app/lib/surface/SingularSprite.spec.coffee +++ b/test/app/lib/surface/SingularSprite.spec.coffee @@ -24,7 +24,7 @@ describe 'SingularSprite', -> describe 'with Ogre Munchkin ThangType', -> beforeEach -> - layer = new LayerAdapter() + layer = new LayerAdapter({webGL:true}) layer.buildAutomatically = false layer.buildAsync = false ogreMunchkinThangType.markToRevert() diff --git a/test/app/lib/surface/SpriteBoss.spec.coffee b/test/app/lib/surface/SpriteBoss.spec.coffee index f105fc616..83034188c 100644 --- a/test/app/lib/surface/SpriteBoss.spec.coffee +++ b/test/app/lib/surface/SpriteBoss.spec.coffee @@ -62,7 +62,7 @@ describe 'SpriteBoss', -> # Sort of an implicit test. By default, all the default actions are always rendered, # but I want to make sure the system can dynamically hear about actions it needs to render for # as they are used. - defaultLayer.setDefaultActions(['idle']) + defaultLayer.defaultActions = ['idle'] # Render the simple world with just trees spriteBoss.update(true) @@ -163,8 +163,8 @@ describe 'SpriteBoss', -> expect(spriteBoss.sprites['Ogre E'].imageObject.alpha).toBe(0.5) it 'orders sprites in the layer based on thang pos.y\'s', -> - container = spriteBoss.spriteLayers.Default.spriteContainer - l = spriteBoss.spriteLayers.Default.spriteContainer.children + container = spriteBoss.spriteLayers.Default.container + l = container.children i1 = container.getChildIndex(_.find(container.children, (c) -> c.sprite.thang.id is 'Dying Ogre 1')) i2 = container.getChildIndex(_.find(container.children, (c) -> c.sprite.thang.id is 'Dying Ogre 2')) i3 = container.getChildIndex(_.find(container.children, (c) -> c.sprite.thang.id is 'Dying Ogre 3')) @@ -174,6 +174,6 @@ describe 'SpriteBoss', -> expect(i3).toBeGreaterThan(i4) it 'only contains children Sprites and SpriteContainers whose spritesheet matches the Layer', -> - defaultLayerContainer = spriteBoss.spriteLayers.Default.spriteContainer + defaultLayerContainer = spriteBoss.spriteLayers.Default.container for c in defaultLayerContainer.children expect(c.spriteSheet).toBe(defaultLayerContainer.spriteSheet) diff --git a/vendor/scripts/SpriteStage.js b/vendor/scripts/SpriteStage.js index 926de4a71..ce01ac996 100644 --- a/vendor/scripts/SpriteStage.js +++ b/vendor/scripts/SpriteStage.js @@ -432,6 +432,7 @@ var p = SpriteStage.prototype = new createjs.Stage(); if (child._spritestage_compatibility >= 1) { // The child is compatible with SpriteStage. } else { + console.trace(); console && console.log("Error: You can only add children of type SpriteContainer, Sprite, Bitmap, BitmapText, or DOMElement. [" + child.toString() + "]"); return child; }