From 6669a01c149dfe56664ee563535447931acb99fd Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Wed, 24 Sep 2014 12:08:55 -0700 Subject: [PATCH] Got rid of some cache functions. Set up area of effect animations in the new spriteSheet system. --- app/lib/surface/CocoSprite.coffee | 106 ++++++++------------ app/lib/surface/LayerAdapter.coffee | 26 +++-- app/lib/surface/SpriteBoss.coffee | 8 +- test/app/lib/surface/SpriteBoss.spec.coffee | 6 +- 4 files changed, 67 insertions(+), 79 deletions(-) diff --git a/app/lib/surface/CocoSprite.coffee b/app/lib/surface/CocoSprite.coffee index 680677019..ad5733cbe 100644 --- a/app/lib/surface/CocoSprite.coffee +++ b/app/lib/surface/CocoSprite.coffee @@ -30,7 +30,6 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass floatingLayer: null thang: null camera: null - spriteSheetCache: null showInvisible: false async: true @@ -114,28 +113,6 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass @configureMouse() @imageObject.on 'animationend', @playNextAction - - # TODO: figure out how to do placeholders again -# setUpPlaceholder: -> -# return if @placeholder or not @thang -# shape = new createjs.Shape() -# width = @thang.width * Camera.PPM -# height = @thang.height * Camera.PPM * @options.camera.y2x -# depth = @thang.depth * Camera.PPM * @options.camera.z2y * @options.camera.y2x -# brightnessFuzzFactor = 1 + 0.1 * (Math.random() - 0.5) -# makeColor = (brightnessFactor) => (Math.round(c * brightnessFuzzFactor * brightnessFactor) for c in (healthColors[@thang.team] ? [180, 180, 180])) -# topColor = "rgba(#{makeColor(0.85).join(', ')},1)" -# mainColor = "rgba(#{makeColor(0.75).join(', ')},1)" -# ellipse = @thang.shape in ['ellipsoid', 'disc'] -# fn = if ellipse then 'drawEllipse' else 'drawRect' -# shape.graphics.beginFill(mainColor)[fn](-width / 2, -height / 2, width, height).endFill() -# shape.graphics.moveTo(-width / 2, 0).beginFill(mainColor).lineTo(-width / 2, -depth).lineTo(width / 2, -depth).lineTo(width / 2, 0).lineTo(-width / 2, 0).endFill() -# shape.graphics.beginFill(topColor)[fn](-width / 2, -height / 2 - depth, width, height).endFill() -# shape.layerPriority = @thang?.layerPriority ? @thangType.get 'layerPriority' -# @setImageObject shape -# @updatePosition true -# @placeholder = shape - ################################################## # QUEUEING AND PLAYING ACTIONS @@ -207,43 +184,50 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass showAreaOfEffects: -> # TODO: add back area of effects -# return unless @thang?.currentEvents -# for event in @thang.currentEvents -# continue unless event.startsWith 'aoe-' -# continue if @handledDisplayEvents[event] -# -# @handledDisplayEvents[event] = true -# args = JSON.parse(event[4...]) -# pos = @options.camera.worldToSurface {x: args[0], y: args[1]} -# circle = new createjs.Shape() -# radius = args[2] * Camera.PPM -# if args.length is 4 -# circle.graphics.beginFill(args[3]).drawCircle(0, 0, radius) -# else -# startAngle = args[4] -# endAngle = args[5] -# circle.graphics.beginFill(args[3]) -# .lineTo(0, 0) -# .lineTo(radius * Math.cos(startAngle), radius * Math.sin(startAngle)) -# .arc(0, 0, radius, startAngle, endAngle) -# .lineTo(0, 0) -# circle.x = pos.x -# circle.y = pos.y -# circle.scaleY = @options.camera.y2x * 0.7 -# circle.scaleX = 0.7 -# circle.alpha = 0.2 -# circle -# @options.groundLayer.addChild circle -# createjs.Tween.get(circle) -# .to({alpha: 0.6, scaleY: @options.camera.y2x, scaleX: 1}, 100, createjs.Ease.circOut) -# .to({alpha: 0, scaleY: 0, scaleX: 0}, 700, createjs.Ease.circIn) -# .call => -# return if @destroyed -# @options.groundLayer.removeChild circle -# delete @handledDisplayEvents[event] + return unless @thang?.currentEvents + for event in @thang.currentEvents + continue unless event.startsWith 'aoe-' + continue if @handledDisplayEvents[event] + @handledDisplayEvents[event] = true + args = JSON.parse(event[4...]) + key = 'aoe-' + JSON.stringify(args[2..]) + + unless key in @options.groundLayer.spriteSheet.getAnimations() + args = JSON.parse(event[4...]) + circle = new createjs.Shape() + radius = args[2] * Camera.PPM + if args.length is 4 + circle.graphics.beginFill(args[3]).drawCircle(0, 0, radius) + else + startAngle = args[4] + endAngle = args[5] + circle.graphics.beginFill(args[3]) + .lineTo(0, 0) + .lineTo(radius * Math.cos(startAngle), radius * Math.sin(startAngle)) + .arc(0, 0, radius, startAngle, endAngle) + .lineTo(0, 0) + @options.groundLayer.addCustomGraphic(key, circle, [-radius, -radius, radius*2, radius*2]) + + circle = new createjs.Sprite(@options.groundLayer.spriteSheet) + circle.gotoAndStop(key) + pos = @options.camera.worldToSurface {x: args[0], y: args[1]} + circle.x = pos.x + circle.y = pos.y + resFactor = @options.groundLayer.resolutionFactor + circle.scaleY = @options.camera.y2x * 0.7 / resFactor + circle.scaleX = 0.7 / resFactor + circle.alpha = 0.2 + @options.groundLayer.addChild circle + createjs.Tween.get(circle) + .to({alpha: 0.6, scaleY: @options.camera.y2x / resFactor, scaleX: 1 / resFactor}, 100, createjs.Ease.circOut) + .to({alpha: 0, scaleY: 0, scaleX: 0}, 700, createjs.Ease.circIn) + .call => + return if @destroyed + @options.groundLayer.removeChild circle + delete @handledDisplayEvents[event] showTextEvents: -> - # TODO: Add back text events + # TODO: Add back text events, once this has been integrated with the Surface # return unless @thang?.currentEvents # for event in @thang.currentEvents # continue unless event.startsWith 'text-' @@ -267,12 +251,6 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass # return if @destroyed # @options.floatingLayer.removeChild label - cache: -> - return # TODO: get rid of caching - bounds = @imageObject.getBounds() - @imageObject.cache 0, 0, bounds.width, bounds.height - #console.log 'just cached', @thang.id, 'which was at', @imageObject.x, @imageObject.y, bounds.width, bounds.height, 'with scale', Math.max(@imageObject.scaleX, @imageObject.scaleY) - getBobOffset: -> return 0 unless @thang.bobHeight return @lastBobOffset if @stopped diff --git a/app/lib/surface/LayerAdapter.coffee b/app/lib/surface/LayerAdapter.coffee index 7e8b0febe..bfa7eb894 100644 --- a/app/lib/surface/LayerAdapter.coffee +++ b/app/lib/surface/LayerAdapter.coffee @@ -48,6 +48,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass cocoSprites: null spriteSheet: null container: null + customGraphics: null subscriptions: 'camera:zoom-updated': 'onZoomUpdated' @@ -56,6 +57,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass super() options ?= {} @name = options.name ? 'Unnamed' + @customGraphics = {} @layerPriority = options.layerPriority ? 0 @transformStyle = options.transform ? LayerAdapter.TRANSFORM_CHILD @camera = options.camera @@ -130,16 +132,16 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass #- Container-like child functions addChild: (children...) -> - container.addChild children... - if @transformStyle is ContainerLayer.TRANSFORM_SURFACE_TEXT + @container.addChild children... + if @transformStyle is LayerAdapter.TRANSFORM_SURFACE_TEXT for child in children child.scaleX /= @scaleX child.scaleY /= @scaleY removeChild: (children...) -> - container.removeChild children... + @container.removeChild children... # TODO: Do we actually need to scale children that were removed? - if @transformStyle is ContainerLayer.TRANSFORM_SURFACE_TEXT + if @transformStyle is LayerAdapter.TRANSFORM_SURFACE_TEXT for child in children child.scaleX *= @scaleX child.scaleY *= @scaleY @@ -209,6 +211,12 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass @willRender = _.defer => @renderNewSpriteSheet() return true + addCustomGraphic: (key, graphic, bounds) -> + return false if @customGraphics[key] + @customGraphics[key] = { graphic: graphic, bounds: new createjs.Rectangle(bounds...) } + return true if @willRender or not @buildAutomatically + @_renderNewSpriteSheet(false) + #- Rendering sprite sheets renderNewSpriteSheet: -> @@ -227,6 +235,12 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass placeholder.setBounds(0, 0, dimension, dimension) builder.addFrame(placeholder) + # Add custom graphics + for key, graphic of @customGraphics + frame = builder.addFrame(graphic.graphic, graphic.bounds, @resolutionFactor) + builder.addAnimation(key, [frame], false) + + # Render ThangTypes groups = {} if NEVER_RENDER_ANYTHING for bundleGrouping in _.values(groups) thangType = bundleGrouping[0].thangType @@ -246,7 +260,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass builder.on 'complete', @onBuildSpriteSheetComplete, @, true, builder else sheet = builder.build() - @onBuildSpriteSheetComplete(null, builder) + @onBuildSpriteSheetComplete({async:async}, builder) return sheet onBuildSpriteSheetComplete: (e, builder) -> @@ -255,7 +269,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass if builder.spriteSheet._images.length > 1 @resolutionFactor *= 0.9 console.debug('Sprite sheet is too large... re-rendering at', @resolutionFactor.toFixed(2)) - @_renderNewSpriteSheet() + @_renderNewSpriteSheet(e.async) return @spriteSheet = builder.spriteSheet diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee index 9d25fd61b..bb77408ac 100644 --- a/app/lib/surface/SpriteBoss.coffee +++ b/app/lib/surface/SpriteBoss.coffee @@ -41,7 +41,6 @@ module.exports = class SpriteBoss extends CocoClass @spriteArray = [] # Mirror @sprites, but faster for when we just need to iterate @selfWizardSprite = null @createLayers() - @spriteSheetCache = {} @pendingFlags = [] destroy: -> @@ -98,7 +97,7 @@ module.exports = class SpriteBoss extends CocoClass @selectionMark = new Mark name: 'selection', camera: @camera, layer: @spriteLayers['Ground'], thangType: 'selection' createSpriteOptions: (options) -> - _.extend options, camera: @camera, resolutionFactor: SPRITE_RESOLUTION_FACTOR, groundLayer: @spriteLayers['Ground'], textLayer: @surfaceTextLayer, floatingLayer: @spriteLayers['Floating'], spriteSheetCache: @spriteSheetCache, showInvisible: @options.showInvisible + _.extend options, camera: @camera, resolutionFactor: SPRITE_RESOLUTION_FACTOR, groundLayer: @spriteLayers['Ground'], textLayer: @surfaceTextLayer, floatingLayer: @spriteLayers['Floating'], showInvisible: @options.showInvisible createIndieSprites: (indieSprites, withWizards) -> unless @indieSprites @@ -186,7 +185,6 @@ module.exports = class SpriteBoss extends CocoClass sprite.update frameChanged for sprite in @spriteArray @updateSelection() @spriteLayers['Default'].updateLayerOrder() - @cache() adjustSpriteExistence: -> # Add anything new, remove anything old, update everything current @@ -208,7 +206,6 @@ module.exports = class SpriteBoss extends CocoClass updatedObstacles.push sprite if isObstacle and (missing or sprite.hasMoved) sprite.hasMoved = false @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 if @willSelectThang and @sprites[@willSelectThang[0]] @@ -229,9 +226,6 @@ module.exports = class SpriteBoss extends CocoClass itemsJustEquipped.push item return itemsJustEquipped - cache: (update=false) -> - # TODO: remove caching - spriteFor: (thangID) -> @sprites[thangID] onNewWorld: (e) -> diff --git a/test/app/lib/surface/SpriteBoss.spec.coffee b/test/app/lib/surface/SpriteBoss.spec.coffee index 83034188c..1e03b78ad 100644 --- a/test/app/lib/surface/SpriteBoss.spec.coffee +++ b/test/app/lib/surface/SpriteBoss.spec.coffee @@ -95,7 +95,7 @@ describe 'SpriteBoss', -> {id: 'Dying Ogre 4', spriteName: 'Segmented Munchkin', exists: true, pos: {x:-12.5, y:3}, action: 'die', health: 5, maxHealth: 10, rotation: 0, acts: true } # Throw in a ThangType that contains nested MovieClips - {id: 'Fangrider', spriteName: 'Fangrider', exists: true, pos: {x:8, y:8}, action: 'move', health: 20, maxHealth: 20, rotation: 0, acts: true } + {id: 'Fangrider', spriteName: 'Fangrider', exists: true, pos: {x:8, y:8}, action: 'move', health: 20, maxHealth: 20, rotation: 0, acts: true, currentEvents: ['aoe-' + JSON.stringify([0, 0, 8, '#00F'])] } ] _.find(world.thangs, {id: 'Disappearing Tree'}).exists = false @@ -110,7 +110,7 @@ describe 'SpriteBoss', -> midRenderExpectations.push([spriteBoss.sprites['Singular Ogre'].imageObject.paused,true,'animated singular action']) defaultLayer.once 'new-spritesheet', -> -# showMe() # Uncomment to display this world when you run any of these tests. + showMe() # Uncomment to display this world when you run any of these tests. done() beforeEach (done) -> init(done) @@ -125,6 +125,8 @@ describe 'SpriteBoss', -> return if ticks >= 100 ticks += 1 console.log 'update' + if ticks % 20 is 0 + spriteBoss.update(true) stage.update() } createjs.Ticker.addEventListener "tick", listener