mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 15:48:11 -05:00
Set up placeholders for when WebGLSprites don't have their raw data built yet. Not finished yet because of scaling, but will come back to it... Got some refactoring to do first.
This commit is contained in:
parent
a99cdfb957
commit
3c9b40e8f4
5 changed files with 74 additions and 36 deletions
|
@ -11,6 +11,7 @@ marked.setOptions {gfm: true, sanitize: true, smartLists: true, breaks: false}
|
|||
|
||||
# TODO, add C-style macro constants like this?
|
||||
window.SPRITE_RESOLUTION_FACTOR = 3
|
||||
window.SPRITE_PLACEHOLDER_RADIUS = 30
|
||||
|
||||
# Prevent Ctrl/Cmd + [ / ], P, S
|
||||
ctrlDefaultPrevented = [219, 221, 80, 83]
|
||||
|
|
|
@ -3,6 +3,8 @@ CocoClass = require 'lib/CocoClass'
|
|||
WebGLSprite = require './WebGLSprite'
|
||||
{SpriteContainerLayer} = require 'lib/surface/Layer'
|
||||
|
||||
NEVER_RENDER_ANYTHING = true # set to true to test placeholders
|
||||
|
||||
module.exports = class WebGLLayer extends CocoClass
|
||||
|
||||
_.extend(WebGLLayer.prototype, Backbone.Events)
|
||||
|
@ -109,12 +111,13 @@ module.exports = class WebGLLayer extends CocoClass
|
|||
builder = new createjs.SpriteSheetBuilder()
|
||||
groups = _.groupBy(@toRenderBundles, ((bundle) -> @renderGroupingKey(bundle.thangType, '', bundle.colorConfig)), @)
|
||||
|
||||
# Always have an empty frame be the first frame.
|
||||
# Then if you go to a frame that DNE, it doesn't show up.
|
||||
emptiness = new createjs.Container()
|
||||
emptiness.setBounds(0, 0, 1, 1)
|
||||
builder.addFrame(emptiness)
|
||||
# The first frame is always the 'loading', ie placeholder, image.
|
||||
placeholder = @createPlaceholder()
|
||||
dimension = @resolutionFactor*SPRITE_PLACEHOLDER_RADIUS*2
|
||||
placeholder.setBounds(0, 0, dimension, dimension)
|
||||
builder.addFrame(placeholder)
|
||||
|
||||
groups = {} if NEVER_RENDER_ANYTHING
|
||||
for bundleGrouping in _.values(groups)
|
||||
thangType = bundleGrouping[0].thangType
|
||||
colorConfig = bundleGrouping[0].colorConfig
|
||||
|
@ -135,6 +138,17 @@ module.exports = class WebGLLayer extends CocoClass
|
|||
sheet = builder.build()
|
||||
@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
|
||||
|
|
|
@ -33,6 +33,7 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
|
|||
goto: (actionName, @paused=true) ->
|
||||
@currentAnimation = actionName
|
||||
@baseMovieClip = @framerate = null
|
||||
@actionNotSupported = false
|
||||
|
||||
action = @thangType.getActions()[actionName]
|
||||
randomStart = actionName.startsWith('move')
|
||||
|
@ -47,13 +48,21 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
|
|||
@regY = -reg.y * scale
|
||||
func = if @paused then 'gotoAndStop' else 'gotoAndPlay'
|
||||
animationName = @spriteSheetPrefix + actionName
|
||||
if not (animationName in @spriteSheet.getAnimations())
|
||||
@singleChildSprite.gotoAndStop(0)
|
||||
@notifyActionNeedsRender(action)
|
||||
return
|
||||
@singleChildSprite[func](animationName)
|
||||
if @singleChildSprite.currentFrame is 0
|
||||
@regX = -reg.x
|
||||
@regY = -reg.y
|
||||
@singleChildSprite.stop()
|
||||
@notifyActionNeedsRender(action)
|
||||
bounds = @thangType.get('raw').animations[action.animation].bounds
|
||||
@singleChildSprite.x = bounds[0]
|
||||
@singleChildSprite.y = bounds[1]
|
||||
console.log 'bounds?', bounds
|
||||
@singleChildSprite.scaleX = bounds[2] / (SPRITE_PLACEHOLDER_RADIUS * @resolutionFactor * 2)
|
||||
@singleChildSprite.scaleY = bounds[3] / (SPRITE_PLACEHOLDER_RADIUS * @resolutionFactor * 2)
|
||||
return
|
||||
|
||||
@singleChildSprite.framerate = action.framerate or 20
|
||||
|
||||
if randomStart and frames = @spriteSheet.getAnimation(animationName)?.frames
|
||||
@singleChildSprite.currentAnimationFrame = Math.floor(Math.random() * frames.length)
|
||||
|
||||
|
@ -62,10 +71,6 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
|
|||
@regY = -reg.y
|
||||
@childMovieClips = []
|
||||
@baseMovieClip = @buildMovieClip(action.animation)
|
||||
if not @baseMovieClip
|
||||
@children = []
|
||||
@notifyActionNeedsRender(action)
|
||||
return
|
||||
@children = @baseMovieClip.children
|
||||
@frames = action.frames
|
||||
@frames = (parseInt(f) for f in @frames.split(',')) if @frames
|
||||
|
@ -74,31 +79,41 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
|
|||
@baseMovieClip.gotoAndStop(@currentFrame)
|
||||
@loop = action.loops isnt false
|
||||
@goesTo = action.goesTo
|
||||
@notifyActionNeedsRender(action) if @actionNotSupported
|
||||
|
||||
if action.container
|
||||
scale = @resolutionFactor * (action.scale ? @thangType.get('scale') ? 1)
|
||||
|
||||
if @singleChildSprite
|
||||
scale = @resolutionFactor * (action.scale ? @thangType.get('scale') ? 1)
|
||||
@regX = -reg.x * scale
|
||||
@regY = -reg.y * scale
|
||||
animationName = @spriteSheetPrefix + actionName
|
||||
if not (animationName in @spriteSheet.getAnimations())
|
||||
@singleChildSprite.gotoAndStop(0)
|
||||
@notifyActionNeedsRender(action)
|
||||
return
|
||||
@singleChildSprite.gotoAndStop(animationName)
|
||||
if @singleChildSprite.currentFrame is 0
|
||||
@notifyActionNeedsRender(action)
|
||||
bounds = @thangType.get('raw').containers[action.container].b
|
||||
@singleChildSprite.x = bounds[0]
|
||||
@singleChildSprite.y = bounds[1]
|
||||
@singleChildSprite.scaleX = bounds[2] / (SPRITE_PLACEHOLDER_RADIUS * 2)
|
||||
@singleChildSprite.scaleY = bounds[3] / (SPRITE_PLACEHOLDER_RADIUS * 2)
|
||||
return
|
||||
|
||||
else
|
||||
@regX = -reg.x
|
||||
@regY = -reg.y
|
||||
@childMovieClips = []
|
||||
containerName = @spriteSheetPrefix + action.container
|
||||
if not (containerName in @spriteSheet.getAnimations())
|
||||
@children = []
|
||||
@notifyActionNeedsRender(action)
|
||||
return
|
||||
sprite = new createjs.Sprite(@spriteSheet)
|
||||
sprite.gotoAndStop(containerName)
|
||||
sprite.scaleX = sprite.scaleY = 1 / @resolutionFactor
|
||||
if sprite.currentFrame is 0
|
||||
@notifyActionNeedsRender(action)
|
||||
bounds = @thangType.get('raw').containers[action.container].b
|
||||
sprite.x = bounds[0]
|
||||
sprite.y = bounds[1]
|
||||
sprite.scaleX = bounds[2] / (SPRITE_PLACEHOLDER_RADIUS * 2 * scale)
|
||||
sprite.scaleY = bounds[3] / (SPRITE_PLACEHOLDER_RADIUS * 2 * scale)
|
||||
else
|
||||
sprite.scaleX = sprite.scaleY = 1 / scale
|
||||
@children = [sprite]
|
||||
|
||||
return
|
||||
|
@ -112,10 +127,8 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
|
|||
movieClip = new createjs.MovieClip()
|
||||
|
||||
locals = {}
|
||||
_.extend locals, containers = @buildMovieClipContainers(animData.containers)
|
||||
return false if not containers
|
||||
_.extend locals, animations = @buildMovieClipAnimations(animData.animations)
|
||||
return false if not animations
|
||||
_.extend locals, @buildMovieClipContainers(animData.containers)
|
||||
_.extend locals, @buildMovieClipAnimations(animData.animations)
|
||||
|
||||
toSkip = {}
|
||||
toSkip[shape.bn] = true for shape in animData.shapes
|
||||
|
@ -147,10 +160,16 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
|
|||
for localContainer in localContainers
|
||||
outerContainer = new createjs.SpriteContainer(@spriteSheet)
|
||||
innerContainer = new createjs.Sprite(@spriteSheet)
|
||||
innerContainer.scaleX = innerContainer.scaleY = 1 / (@resolutionFactor * (@thangType.get('scale') or 1))
|
||||
animationName = @spriteSheetPrefix + localContainer.gn
|
||||
return false if not (animationName in @spriteSheet.getAnimations())
|
||||
innerContainer.gotoAndStop(animationName)
|
||||
innerContainer.gotoAndStop(@spriteSheetPrefix + localContainer.gn)
|
||||
if innerContainer.currentFrame is 0
|
||||
@actionNotSupported = true
|
||||
bounds = @thangType.get('raw').containers[localContainer.gn].b
|
||||
innerContainer.x = bounds[0]
|
||||
innerContainer.y = bounds[1]
|
||||
innerContainer.scaleX = bounds[2] / (SPRITE_PLACEHOLDER_RADIUS * @resolutionFactor * 2)
|
||||
innerContainer.scaleY = bounds[3] / (SPRITE_PLACEHOLDER_RADIUS * @resolutionFactor * 2)
|
||||
else
|
||||
innerContainer.scaleX = innerContainer.scaleY = 1 / (@resolutionFactor * (@thangType.get('scale') or 1))
|
||||
outerContainer.addChild(innerContainer)
|
||||
outerContainer.setTransform(localContainer.t...)
|
||||
outerContainer._off = localContainer.o if localContainer.o?
|
||||
|
@ -162,7 +181,6 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
|
|||
map = {}
|
||||
for localAnimation in localAnimations
|
||||
animation = @buildMovieClip(localAnimation.gn, localAnimation.a...)
|
||||
return false if not animation
|
||||
animation.setTransform(localAnimation.t...)
|
||||
map[localAnimation.bn] = animation
|
||||
@childMovieClips.push(animation)
|
||||
|
|
|
@ -69,7 +69,9 @@ describe 'SpriteBoss', ->
|
|||
spriteBoss.update(true)
|
||||
|
||||
# Test that the unrendered, static sprites aren't showing anything
|
||||
midRenderExpectations.push([spriteBoss.sprites['Tree 1'].imageObject.children.length,0,'static container action'])
|
||||
midRenderExpectations.push([spriteBoss.sprites['Tree 1'].imageObject.children.length,1,'static container action'])
|
||||
midRenderExpectations.push([spriteBoss.sprites['Tree 1'].imageObject.children[0].currentFrame,0,'static container action'])
|
||||
midRenderExpectations.push([spriteBoss.sprites['Tree 1'].imageObject.children[0].paused,true,'static container action'])
|
||||
midRenderExpectations.push([spriteBoss.sprites['Tree 2'].imageObject.children[0].currentFrame,0,'static spriteSheet action'])
|
||||
midRenderExpectations.push([spriteBoss.sprites['Tree 2'].imageObject.children[0].paused,true,'static spriteSheet action'])
|
||||
|
||||
|
@ -102,13 +104,15 @@ describe 'SpriteBoss', ->
|
|||
spriteBoss.update(true)
|
||||
|
||||
# Test that the unrendered, animated sprites aren't showing anything
|
||||
midRenderExpectations.push([spriteBoss.sprites['NotFROgre'].imageObject.children.length,0,'animated container action'])
|
||||
midRenderExpectations.push([spriteBoss.sprites['NotFROgre'].imageObject.children.length,10,'animated container action'])
|
||||
for child in spriteBoss.sprites['NotFROgre'].imageObject.children
|
||||
midRenderExpectations.push([child.children[0].currentFrame, 0, 'animated container action'])
|
||||
midRenderExpectations.push([spriteBoss.sprites['FROgre'].imageObject.children[0].currentFrame,0,'animated spriteSheet action'])
|
||||
midRenderExpectations.push([spriteBoss.sprites['FROgre'].imageObject.children[0].paused,true,'animated spriteSheet action'])
|
||||
|
||||
defaultLayer.once 'new-spritesheet', ->
|
||||
showMe() # Uncomment to display this world when you run any of these tests.
|
||||
done()
|
||||
# showMe() # Uncomment to display this world when you run any of these tests.
|
||||
|
||||
beforeEach (done) -> init(done)
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ describe 'WebGLSprite', ->
|
|||
expect(webGLSprite.paused).toBe(false)
|
||||
webGLSprite.gotoAndStop('move_fore')
|
||||
expect(webGLSprite.paused).toBe(true)
|
||||
showMe()
|
||||
|
||||
it 'has a tick function which moves the animation forward', ->
|
||||
webGLSprite.gotoAndPlay('attack')
|
||||
|
|
Loading…
Reference in a new issue