Set up scaling and mouse events for segmented sprites with container actions.

This commit is contained in:
Scott Erickson 2014-09-23 12:08:50 -07:00
parent 5de5d5658e
commit 16cb596a12
3 changed files with 113 additions and 7 deletions

View file

@ -107,7 +107,7 @@ module.exports = class SpriteBuilder
shape shape
buildContainerFromStore: (containerKey) -> buildContainerFromStore: (containerKey) ->
console.error 'Yo we don\'t have no', containerKey unless containerKey console.error 'Yo we don\'t have no containerKey' unless containerKey
contData = @containerStore[containerKey] contData = @containerStore[containerKey]
cont = new createjs.Container() cont = new createjs.Container()
cont.initialize() cont.initialize()

View file

@ -19,6 +19,7 @@ module.exports = class SegmentedSprite extends createjs.SpriteContainer
gotoAndStop: (actionName) -> @goto(actionName, true) gotoAndStop: (actionName) -> @goto(actionName, true)
goto: (actionName, @paused=true) -> goto: (actionName, @paused=true) ->
@removeAllChildren()
@currentAnimation = actionName @currentAnimation = actionName
@baseMovieClip = @framerate = null @baseMovieClip = @framerate = null
@actionNotSupported = false @actionNotSupported = false
@ -31,10 +32,10 @@ module.exports = class SegmentedSprite extends createjs.SpriteContainer
reg = action.positions?.registration or @thangType.get('positions')?.registration or {x:0, y:0} reg = action.positions?.registration or @thangType.get('positions')?.registration or {x:0, y:0}
@regX = -reg.x @regX = -reg.x
@regY = -reg.y @regY = -reg.y
@baseScaleY = @baseScaleX = action.scale ? @thangType.get('scale') ? 1
if action.animation if action.animation
@framerate = (action.framerate ? 20) * (action.speed ? 1) @framerate = (action.framerate ? 20) * (action.speed ? 1)
@baseScaleY = @baseScaleX = action.scale ? @thangType.get('scale') ? 1
@childMovieClips = [] @childMovieClips = []
@baseMovieClip = @buildMovieClip(action.animation) @baseMovieClip = @buildMovieClip(action.animation)
@children = @baseMovieClip.children @children = @baseMovieClip.children
@ -54,16 +55,19 @@ module.exports = class SegmentedSprite extends createjs.SpriteContainer
containerName = @spriteSheetPrefix + action.container containerName = @spriteSheetPrefix + action.container
sprite = new createjs.Sprite(@spriteSheet) sprite = new createjs.Sprite(@spriteSheet)
sprite.gotoAndStop(containerName) sprite.gotoAndStop(containerName)
if sprite.currentFrame is 0 @listenToEventsFor(sprite)
if sprite.currentFrame is 0 or @usePlaceholders
sprite.gotoAndStop(0)
@notifyActionNeedsRender(action) @notifyActionNeedsRender(action)
bounds = @thangType.get('raw').containers[action.container].b bounds = @thangType.get('raw').containers[action.container].b
sprite.x = bounds[0] sprite.x = bounds[0]
sprite.y = bounds[1] sprite.y = bounds[1]
sprite.scaleX = bounds[2] / (SPRITE_PLACEHOLDER_RADIUS * 2 * scale) sprite.scaleX = bounds[2] / (SPRITE_PLACEHOLDER_RADIUS * @resolutionFactor * 2)
sprite.scaleY = bounds[3] / (SPRITE_PLACEHOLDER_RADIUS * 2 * scale) sprite.scaleY = bounds[3] / (SPRITE_PLACEHOLDER_RADIUS * @resolutionFactor * 2)
else else
sprite.scaleX = sprite.scaleY = 1 / scale sprite.scaleX = sprite.scaleY = 1 / scale
@children = [sprite] @children = []
@addChild(sprite)
return return
@ -168,7 +172,7 @@ module.exports = class SegmentedSprite extends createjs.SpriteContainer
@lastTimeStamp = e.timeStamp @lastTimeStamp = e.timeStamp
tick: (delta) -> tick: (delta) ->
return if @paused return if @paused or not @baseMovieClip
newFrame = @currentFrame + @framerate * delta / 1000 newFrame = @currentFrame + @framerate * delta / 1000
if newFrame > @animLength if newFrame > @animLength

View file

@ -5,6 +5,7 @@ ThangType = require 'models/ThangType'
SpriteBuilder = require 'lib/sprites/SpriteBuilder' SpriteBuilder = require 'lib/sprites/SpriteBuilder'
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') ogreFangriderThangType = new ThangType(require 'test/app/fixtures/ogre-fangrider.thang.type')
treeThangType = new ThangType(require 'test/app/fixtures/tree1.thang.type')
describe 'SegmentedSprite', -> describe 'SegmentedSprite', ->
segmentedSprite = null segmentedSprite = null
@ -27,6 +28,107 @@ describe 'SegmentedSprite', ->
} }
createjs.Ticker.addEventListener "tick", listener createjs.Ticker.addEventListener "tick", listener
describe 'with Tree ThangType', ->
beforeEach ->
layer = new LayerAdapter({webGL:true})
layer.buildAutomatically = false
layer.buildAsync = false
treeThangType.markToRevert()
treeThangType.set('spriteType', 'segmented')
sprite = new CocoSprite(treeThangType)
layer.addCocoSprite(sprite)
sheet = layer.renderNewSpriteSheet()
prefix = layer.renderGroupingKey(treeThangType) + '.'
window.segmentedSprite = segmentedSprite = new SegmentedSprite(sheet, treeThangType, prefix)
segmentedSprite.x = 100
segmentedSprite.y = 200
it 'scales rendered containers to the size of the source container', ->
# build a movie clip, put it on top of the segmented sprite and make sure
# they both 'hit' at the same time.
segmentedSprite.gotoAndStop('idle')
builder = new SpriteBuilder(treeThangType)
container = builder.buildContainerFromStore('Tree_4')
container.x = 100
container.y = 200
container.regX = 59
container.regY = 100
showMe()
stage.addChild(container)
stage.update()
t = new Date()
tests = hits = 0
for x in _.range(30, 190, 20)
for y in _.range(90, 250, 20)
tests += 1
objects = stage.getObjectsUnderPoint(x, y)
if objects.length
hasSprite = _.any objects, (o) -> o instanceof createjs.Sprite
hasShape = _.any objects, (o) -> o instanceof createjs.Shape
hits+= 1 if hasSprite and hasShape
g = new createjs.Graphics()
g.beginFill(createjs.Graphics.getRGB(64,64,64,0.7))
g.drawCircle(0, 0, 2)
s = new createjs.Shape(g)
s.x = x
s.y = y
stage.addChild(s)
else
hits += 1
expect(hits / tests).toBeGreaterThan(0.98) # not perfect, but pretty close.
expect(segmentedSprite.baseScaleX).toBe(0.3)
expect(segmentedSprite.baseScaleY).toBe(0.3)
# $('canvas').remove()
it 'scales placeholder containers to the size of the source container', ->
# build a movie clip, put it on top of the segmented sprite and make sure
# they both 'hit' at the same time.
segmentedSprite.usePlaceholders = true
segmentedSprite.gotoAndStop('idle')
builder = new SpriteBuilder(treeThangType)
container = builder.buildContainerFromStore('Tree_4')
container.x = 100
container.y = 200
container.regX = 59
container.regY = 100
showMe()
stage.addChild(container)
stage.update()
t = new Date()
tests = hits = 0
for x in _.range(30, 190, 20)
for y in _.range(90, 250, 20)
tests += 1
objects = stage.getObjectsUnderPoint(x, y)
if objects.length
hasSprite = _.any objects, (o) -> o instanceof createjs.Sprite
hasShape = _.any objects, (o) -> o instanceof createjs.Shape
hits+= 1 if hasSprite and hasShape
g = new createjs.Graphics()
g.beginFill(createjs.Graphics.getRGB(64,64,64,0.7))
g.drawCircle(0, 0, 2)
s = new createjs.Shape(g)
s.x = x
s.y = y
stage.addChild(s)
else
hits += 1
expect(hits / tests).toBeGreaterThan(0.84) # the circle is rather out of the tree bounds, so accuracy is low
expect(segmentedSprite.baseScaleX).toBe(0.3)
expect(segmentedSprite.baseScaleY).toBe(0.3)
$('canvas').remove()
it 'propagates events from the single segment through the segmented sprite', ->
fired = {}
segmentedSprite.on('click', -> fired.didIt = true)
segmentedSprite.gotoAndStop('idle')
segmentedSprite.children[0].dispatchEvent('click')
expect(fired.didIt).toBe(true)
describe 'with Ogre Munchkin ThangType', -> describe 'with Ogre Munchkin ThangType', ->
beforeEach -> beforeEach ->
layer = new LayerAdapter({webGL:true}) layer = new LayerAdapter({webGL:true})