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