Got the WebGLSprite to work with nested MovieClips.

This commit is contained in:
Scott Erickson 2014-09-15 15:08:02 -07:00
parent 8e401d6853
commit 9ba11e2354
4 changed files with 102 additions and 76 deletions

View file

@ -66,7 +66,7 @@ module.exports = class WebGLLayer extends createjs.SpriteContainer
if action.container if action.container
containersToRender[action.container] = true containersToRender[action.container] = true
else if action.animation else if action.animation
animationContainers = thangType.get('raw').animations[action.animation].containers animationContainers = @getContainersForAnimation(thangType, action.animation)
containersToRender[container.gn] = true for container in animationContainers containersToRender[container.gn] = true for container in animationContainers
spriteBuilder = new SpriteBuilder(thangType, {colorConfig: colorConfig}) spriteBuilder = new SpriteBuilder(thangType, {colorConfig: colorConfig})
@ -76,6 +76,11 @@ module.exports = class WebGLLayer extends createjs.SpriteContainer
frame = spriteSheetBuilder.addFrame(container) frame = spriteSheetBuilder.addFrame(container)
spriteSheetBuilder.addAnimation(containerKey, [frame], false) spriteSheetBuilder.addAnimation(containerKey, [frame], false)
getContainersForAnimation: (thangType, animation) ->
containers = thangType.get('raw').animations[animation].containers
for animation in thangType.get('raw').animations[animation].animations
containers = containers.concat(@getContainersForAnimation(thangType, animation.gn))
return containers
renderSpriteSheet: (thangType, colorConfig, actionNames, spriteSheetBuilder) -> renderSpriteSheet: (thangType, colorConfig, actionNames, spriteSheetBuilder) ->
actionObjects = _.values(thangType.getActions()) actionObjects = _.values(thangType.getActions())
@ -141,14 +146,4 @@ module.exports = class WebGLLayer extends createjs.SpriteContainer
bm = new createjs.Bitmap(thangType.rasterImage[0]) bm = new createjs.Bitmap(thangType.rasterImage[0])
scale = thangType.get('scale') or 1 scale = thangType.get('scale') or 1
frame = spriteSheetBuilder.addFrame(bm, null, scale) frame = spriteSheetBuilder.addFrame(bm, null, scale)
spriteSheetBuilder.addAnimation(@renderGroupingKey(thangType), [frame], false) spriteSheetBuilder.addAnimation(@renderGroupingKey(thangType), [frame], false)
# renderForSprite: (cocoSprite) ->
# rawData = cocoSprite.thangType.get('raw')
# groupKey = @renderGroupingKey(cocoSprite.thangType, cocoSprite.options.colorConfig)
# spriteBuilder = new SpriteBuilder(cocoSprite.thangType, cocoSprite.options)
# for animation in raw.animations ? []
# for shape in shapes
# shape = @spriteBuilder.buildShapeFromStore(shape.gn)
# key = groupKey = ':' + shape.gn
# frame = @spriteBuilder.addFrame(groupKey)

View file

@ -1,6 +1,8 @@
SpriteBuilder = require 'lib/sprites/SpriteBuilder' SpriteBuilder = require 'lib/sprites/SpriteBuilder'
module.exports = class WebGLSprite extends createjs.SpriteContainer module.exports = class WebGLSprite extends createjs.SpriteContainer
childSpriteContainers: null
constructor: (@spriteSheet, @thangType, @spriteSheetPrefix) -> constructor: (@spriteSheet, @thangType, @spriteSheetPrefix) ->
@initialize(@spriteSheet) @initialize(@spriteSheet)
@ -11,6 +13,7 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
@currentAnimation = actionName @currentAnimation = actionName
action = @thangType.getActions()[actionName] action = @thangType.getActions()[actionName]
if action.animation if action.animation
@childSpriteContainers = []
@baseMovieClip = @buildMovieClip(action.animation) @baseMovieClip = @buildMovieClip(action.animation)
@mirrorMovieClip(@baseMovieClip, @) @mirrorMovieClip(@baseMovieClip, @)
@framerate = (action.framerate ? 20) * (action.speed ? 1) @framerate = (action.framerate ? 20) * (action.speed ? 1)
@ -29,16 +32,7 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
return return
mirrorMovieClip: (movieClip, spriteContainer) -> mirrorMovieClip: (movieClip, spriteContainer) ->
movieClips = []
spriteContainer.children = movieClip.children spriteContainer.children = movieClip.children
for child, index in spriteContainer.children
if child instanceof createjs.MovieClip
movieClips.push(child)
childMovieClip = child
childSpriteContainer = new createjs.SpriteContainer(@spriteSheet)
spriteContainer.children[index] = childSpriteContainer
movieClips = movieClips.concat(@mirrorMovieClip(childMovieClip, childSpriteContainer))
return movieClips
buildMovieClip: (animationName, mode, startPosition, loops) -> buildMovieClip: (animationName, mode, startPosition, loops) ->
raw = @thangType.get('raw') raw = @thangType.get('raw')
@ -57,8 +51,7 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
tween = createjs.Tween tween = createjs.Tween
for func in tweenData for func in tweenData
args = $.extend(true, [], (func.a)) args = $.extend(true, [], (func.a))
args = @dereferenceArgs(args, locals) if @dereferenceArgs(args, locals) is false
if args is false
console.log 'could not dereference args', args console.log 'could not dereference args', args
stopped = true stopped = true
break break
@ -88,6 +81,10 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
animation = @buildMovieClip(localAnimation.gn, localAnimation.a...) animation = @buildMovieClip(localAnimation.gn, localAnimation.a...)
animation.setTransform(localAnimation.t...) animation.setTransform(localAnimation.t...)
map[localAnimation.bn] = animation map[localAnimation.bn] = animation
childSpriteContainer = new createjs.SpriteContainer(@spriteSheet)
childSpriteContainer.movieClip = animation
childSpriteContainer.children = animation.children
@childSpriteContainers.push(childSpriteContainer)
return map return map
dereferenceArgs: (args, locals) -> dereferenceArgs: (args, locals) ->
@ -137,5 +134,12 @@ module.exports = class WebGLSprite extends createjs.SpriteContainer
@currentFrame = newFrame @currentFrame = newFrame
if @childSpriteContainers
for childSpriteContainer in @childSpriteContainers
movieClip = childSpriteContainer.movieClip
index = movieClip.parent.getChildIndex(movieClip)
movieClip.gotoAndStop(newFrame)
movieClip.parent[index] = childSpriteContainer
getBounds: -> getBounds: ->
@baseMovieClip.getBounds() @baseMovieClip.getBounds()

File diff suppressed because one or more lines are too long

View file

@ -4,12 +4,13 @@ CocoSprite = require 'lib/surface/CocoSprite'
ThangType = require 'models/ThangType' ThangType = require 'models/ThangType'
treeThangType = new ThangType(require 'test/app/fixtures/tree1.thang.type') treeThangType = new ThangType(require 'test/app/fixtures/tree1.thang.type')
ogreMunchkinThangType = new ThangType(require 'test/app/fixtures/ogre-munchkin-m.thang.type') ogreMunchkinThangType = new ThangType(require 'test/app/fixtures/ogre-munchkin-m.thang.type')
ogreFangriderThangType = new ThangType(require 'test/app/fixtures/ogre-fangrider.thang.type')
describe 'WebGLSprite', -> describe 'WebGLSprite', ->
webGLSprite = null webGLSprite = null
showMe = -> showMe = ->
canvas = $('<canvas width="600" height="400"></canvas>').css('position', 'absolute').css('index', 1000).css('background', 'white') canvas = $('<canvas width="600" height="400"></canvas>').css('position', 'absolute').css('index', 1000)#.css('background', 'white')
$('body').append(canvas) $('body').append(canvas)
stage = new createjs.SpriteStage(canvas[0]) stage = new createjs.SpriteStage(canvas[0])
stage.addChild(webGLSprite) stage.addChild(webGLSprite)
@ -23,57 +24,82 @@ describe 'WebGLSprite', ->
ticks += 1 ticks += 1
} }
createjs.Ticker.addEventListener "tick", listener createjs.Ticker.addEventListener "tick", listener
describe 'with Ogre Munchkin ThangType', ->
beforeEach ->
layer = new WebGLLayer()
ogreMunchkinThangType.markToRevert()
ogreMunchkinThangType.set('renderStrategy', 'container')
actions = ogreMunchkinThangType.getActions()
# couple extra actions for doing some tests
actions.littledance = {animation:'enemy_small_move_side',framerate:1, frames:'0,6,2,6,2,8,0'}
actions.onestep = {animation:'enemy_small_move_side', loops: false}
colorConfig = {team: {hue: 0, saturation: 1, lightness: 0.5}}
sprite = new CocoSprite(ogreMunchkinThangType, {colorConfig: colorConfig})
layer.addCocoSprite(sprite)
sheet = layer.renderNewSpriteSheet()
prefix = layer.renderGroupingKey(ogreMunchkinThangType, null, colorConfig) + '.'
window.webGLSprite = webGLSprite = new WebGLSprite(sheet, ogreMunchkinThangType, prefix)
afterEach ->
ogreMunchkinThangType.revert()
beforeEach -> it 'has gotoAndPlay, gotoAndStop, and paused like a MovieClip or Sprite', ->
layer = new WebGLLayer() webGLSprite.gotoAndPlay('move_fore')
ogreMunchkinThangType.markToRevert() expect(webGLSprite.baseMovieClip).toBeDefined()
ogreMunchkinThangType.set('renderStrategy', 'container') expect(webGLSprite.paused).toBe(false)
actions = ogreMunchkinThangType.getActions() webGLSprite.gotoAndStop('move_fore')
expect(webGLSprite.paused).toBe(true)
# couple extra actions for doing some tests
actions.littledance = {animation:'enemy_small_move_side',framerate:1, frames:'0,6,2,6,2,8,0'} it 'is paused when the action is a single frame', ->
actions.onestep = {animation:'enemy_small_move_side', loops: false} webGLSprite.gotoAndPlay('idle')
expect(webGLSprite.paused).toBe(true)
colorConfig = {team: {hue: 0, saturation: 1, lightness: 0.5}}
sprite = new CocoSprite(ogreMunchkinThangType, {colorConfig: colorConfig}) it 'has a tick function which moves the animation forward', ->
layer.addCocoSprite(sprite) webGLSprite.gotoAndPlay('move_fore')
sheet = layer.renderNewSpriteSheet() webGLSprite.tick(100) # one hundred milliseconds
prefix = layer.renderGroupingKey(ogreMunchkinThangType, null, colorConfig) + '.' expect(webGLSprite.baseMovieClip.currentFrame).toBe(webGLSprite.framerate*100/1000)
window.webGLSprite = webGLSprite = new WebGLSprite(sheet, ogreMunchkinThangType, prefix)
it 'will interpolate between frames of a custom frame set', ->
afterEach -> webGLSprite.gotoAndPlay('littledance')
ogreMunchkinThangType.revert() webGLSprite.tick(1000)
expect(webGLSprite.baseMovieClip.currentFrame).toBe(6)
webGLSprite.tick(1000)
expect(webGLSprite.baseMovieClip.currentFrame).toBe(2)
webGLSprite.tick(500)
expect(webGLSprite.baseMovieClip.currentFrame).toBe(4)
webGLSprite.tick(500)
expect(webGLSprite.baseMovieClip.currentFrame).toBe(6)
it 'emits animationend for animations where loops is false and there is no goesTo', ->
fired = false
webGLSprite.gotoAndPlay('onestep')
webGLSprite.on('animationend', -> fired = true)
webGLSprite.tick(1000)
expect(fired).toBe(true)
it 'has gotoAndPlay, gotoAndStop, and paused like a MovieClip or Sprite', -> describe 'with Ogre Fangrider ThangType', ->
webGLSprite.gotoAndPlay('move_fore') beforeEach ->
expect(webGLSprite.baseMovieClip).toBeDefined() layer = new WebGLLayer()
expect(webGLSprite.paused).toBe(false) ogreFangriderThangType.markToRevert()
webGLSprite.gotoAndStop('move_fore') ogreFangriderThangType.set('renderStrategy', 'container')
expect(webGLSprite.paused).toBe(true) colorConfig = {team: {hue: 0, saturation: 1, lightness: 0.5}}
sprite = new CocoSprite(ogreFangriderThangType, {colorConfig: colorConfig})
it 'is paused when the action is a single frame', -> layer.addCocoSprite(sprite)
webGLSprite.gotoAndPlay('idle') sheet = layer.renderNewSpriteSheet()
expect(webGLSprite.paused).toBe(true) prefix = layer.renderGroupingKey(ogreFangriderThangType, null, colorConfig) + '.'
window.webGLSprite = webGLSprite = new WebGLSprite(sheet, ogreFangriderThangType, prefix)
it 'has a tick function which moves the animation forward', ->
webGLSprite.gotoAndPlay('move_fore') afterEach ->
webGLSprite.tick(100) # one hundred milliseconds ogreFangriderThangType.revert()
expect(webGLSprite.baseMovieClip.currentFrame).toBe(webGLSprite.framerate*100/1000)
it 'has gotoAndPlay, gotoAndStop, and paused like a MovieClip or Sprite', ->
it 'will interpolate between frames of a custom frame set', -> webGLSprite.gotoAndPlay('move_fore')
webGLSprite.gotoAndPlay('littledance') webGLSprite.tick(100) # one hundred milliseconds
webGLSprite.tick(1000) expectedFrame = webGLSprite.framerate*100/1000
expect(webGLSprite.baseMovieClip.currentFrame).toBe(6) expect(webGLSprite.baseMovieClip.currentFrame).toBe(expectedFrame)
webGLSprite.tick(1000) for child in webGLSprite.childSpriteContainers
expect(webGLSprite.baseMovieClip.currentFrame).toBe(2) expect(child.movieClip.currentFrame).toBe(expectedFrame)
webGLSprite.tick(500) showMe()
expect(webGLSprite.baseMovieClip.currentFrame).toBe(4)
webGLSprite.tick(500)
expect(webGLSprite.baseMovieClip.currentFrame).toBe(6)
it 'emits animationend for animations where loops is false and there is no goesTo', ->
fired = false
webGLSprite.gotoAndPlay('onestep')
webGLSprite.on('animationend', -> fired = true)
webGLSprite.tick(1000)
expect(fired).toBe(true)