Refactored portraits to be built in sprite sheets separately.
This commit is contained in:
parent
674ba86479
commit
c4bfcd5c2d
2 changed files with 66 additions and 57 deletions
app
|
@ -21,6 +21,7 @@ module.exports = class ThangType extends CocoModel
|
||||||
requiredRawAnimations: ->
|
requiredRawAnimations: ->
|
||||||
required = []
|
required = []
|
||||||
for name, action of @get('actions')
|
for name, action of @get('actions')
|
||||||
|
continue if name is 'portrait'
|
||||||
allActions = [action].concat(_.values (action.relatedActions ? {}))
|
allActions = [action].concat(_.values (action.relatedActions ? {}))
|
||||||
for a in allActions when a.animation
|
for a in allActions when a.animation
|
||||||
scale = if name is 'portrait' then a.scale or 1 else a.scale or @get('scale') or 1
|
scale = if name is 'portrait' then a.scale or 1 else a.scale or @get('scale') or 1
|
||||||
|
@ -59,80 +60,87 @@ module.exports = class ThangType extends CocoModel
|
||||||
options
|
options
|
||||||
|
|
||||||
buildSpriteSheet: (options) ->
|
buildSpriteSheet: (options) ->
|
||||||
options = @fillOptions options
|
@initBuild(options)
|
||||||
|
# @options.portraitOnly = true
|
||||||
|
@addGeneralFrames() unless @options.portraitOnly
|
||||||
|
@addPortrait()
|
||||||
|
@finishBuild()
|
||||||
|
|
||||||
|
initBuild: (options) ->
|
||||||
@buildActions() if not @actions
|
@buildActions() if not @actions
|
||||||
unless @requiredRawAnimations().length or _.find @actions, 'container'
|
@options = @fillOptions options
|
||||||
return null if @.get('name') is 'Invisible'
|
@vectorParser = new SpriteBuilder(@)
|
||||||
console.warn "Can't build a CocoSprite with no animations or containers!", @
|
@builder = new createjs.SpriteSheetBuilder()
|
||||||
|
@builder.padding = 2
|
||||||
|
@frames = {}
|
||||||
|
|
||||||
|
addPortrait: ->
|
||||||
|
# The portrait is built very differently than the other animations, so it gets a separate function.
|
||||||
|
portrait = @actions.portrait
|
||||||
|
return unless portrait
|
||||||
|
scale = portrait.scale or 1
|
||||||
|
pt = portrait.positions?.registration
|
||||||
|
rect = new createjs.Rectangle(pt?.x/scale or 0, pt?.y/scale or 0, 100/scale, 100/scale)
|
||||||
|
if portrait.animation
|
||||||
|
mc = @vectorParser.buildMovieClip portrait.animation
|
||||||
|
mc.nominalBounds = mc.frameBounds = null # override what the movie clip says on bounding
|
||||||
|
@builder.addMovieClip(mc, rect, scale)
|
||||||
|
frames = @builder._animations[portrait.animation].frames
|
||||||
|
frames = @normalizeFrames(portrait.frames, frames[0]) if portrait.frames?
|
||||||
|
portrait.frames = frames
|
||||||
|
@builder.addAnimation 'portrait', frames, true
|
||||||
|
else if portrait.container
|
||||||
|
s = @vectorParser.buildContainerFromStore(portrait.container)
|
||||||
|
frame = @builder.addFrame(s, rect, scale)
|
||||||
|
@builder.addAnimation 'portrait', [frame], false
|
||||||
|
|
||||||
vectorParser = new SpriteBuilder(@)
|
addGeneralFrames: ->
|
||||||
builder = new createjs.SpriteSheetBuilder()
|
|
||||||
builder.padding = 2
|
|
||||||
|
|
||||||
# First we add the frames from the raw animations to the sprite sheet builder
|
|
||||||
framesMap = {}
|
framesMap = {}
|
||||||
for animation in @requiredRawAnimations()
|
for animation in @requiredRawAnimations()
|
||||||
name = animation.animation
|
name = animation.animation
|
||||||
movieClip = vectorParser.buildMovieClip name
|
mc = @vectorParser.buildMovieClip name
|
||||||
if animation.portrait
|
@builder.addMovieClip mc, null, animation.scale * @options.resolutionFactor
|
||||||
movieClip.nominalBounds = null
|
framesMap[animation.scale + "_" + name] = @builder._animations[name].frames
|
||||||
movieClip.frameBounds = null
|
|
||||||
pt = @actions.portrait.positions?.registration
|
|
||||||
rect = new createjs.Rectangle(pt?.x/animation.scale or 0, pt?.y/animation.scale or 0, 100/animation.scale, 100/animation.scale)
|
|
||||||
builder.addMovieClip(movieClip, rect, animation.scale)
|
|
||||||
else
|
|
||||||
builder.addMovieClip movieClip, null, animation.scale * options.resolutionFactor
|
|
||||||
framesMap[animation.scale + "_" + name] = builder._animations[name].frames
|
|
||||||
|
|
||||||
# Then we add real animations for our actions with our desired configuration
|
|
||||||
for name, action of @actions when action.animation
|
for name, action of @actions when action.animation
|
||||||
if name is 'portrait'
|
continue if name is 'portrait'
|
||||||
scale = action.scale ? 1
|
scale = action.scale ? @get('scale') ? 1
|
||||||
else
|
frames = framesMap[scale + "_" + action.animation]
|
||||||
scale = action.scale ? @get('scale') ? 1
|
frames = @mapFrames(action.frames, frames[0]) if action.frames?
|
||||||
keptFrames = framesMap[scale + "_" + action.animation]
|
action.frames = frames # Keep generated frame numbers around
|
||||||
if action.frames
|
|
||||||
frames = action.frames
|
|
||||||
frames = frames.split(',') if _.isString(frames)
|
|
||||||
newFrames = (parseInt(f, 10) for f in frames)
|
|
||||||
keptFrames = (f + keptFrames[0] for f in newFrames)
|
|
||||||
action.frames = keptFrames # Keep generated frame numbers around
|
|
||||||
next = true
|
next = true
|
||||||
if action.goesTo
|
next = action.goesTo if action.goesTo
|
||||||
console.warn "Haven't figured out what action.goesTo should do yet"
|
next = false if action.loops is false
|
||||||
next = action.goesTo # TODO: what should this be? action? animation?
|
@builder.addAnimation name, frames, next
|
||||||
else if action.loops is false
|
|
||||||
next = false
|
|
||||||
builder.addAnimation name, keptFrames, next
|
|
||||||
|
|
||||||
for name, action of @actions when action.container and not action.animation
|
for name, action of @actions when action.container and not action.animation
|
||||||
scale = options.resolutionFactor * (action.scale or @get('scale') or 1)
|
continue if name is 'portrait'
|
||||||
s = vectorParser.buildContainerFromStore(action.container)
|
scale = @options.resolutionFactor * (action.scale or @get('scale') or 1)
|
||||||
if action.name is 'portrait'
|
s = @vectorParser.buildContainerFromStore(action.container)
|
||||||
scale = action.scale or 1
|
frame = @builder.addFrame(s, s.bounds, scale)
|
||||||
pt = action?.positions?.registration
|
@builder.addAnimation name, [frame], false
|
||||||
rect = new createjs.Rectangle(pt?.x/scale or 0, pt?.y/scale or 0, 100/scale, 100/scale)
|
|
||||||
frame = builder.addFrame(s, rect, scale)
|
mapFrames: (frames, frameOffset) ->
|
||||||
else
|
return frames unless _.isString(frames) # don't accidentally do this again
|
||||||
frame = builder.addFrame(s, s.bounds, scale)
|
(parseInt(f, 10) + frameOffset for f in frames.split(','))
|
||||||
builder.addAnimation name, [frame], false
|
|
||||||
|
|
||||||
|
finishBuild: ->
|
||||||
|
return if _.isEmpty(@builder._animations)
|
||||||
|
key = @spriteSheetKey(@options)
|
||||||
spriteSheet = null
|
spriteSheet = null
|
||||||
if options.async
|
if @options.async
|
||||||
builder.buildAsync()
|
@builder.buildAsync()
|
||||||
builder.on 'complete', @onBuildSpriteSheetComplete, @, true, @spriteSheetKey(options)
|
@builder.on 'complete', @onBuildSpriteSheetComplete, @, true, key
|
||||||
return true
|
return true
|
||||||
else
|
|
||||||
console.warn 'Building', @get('name'), 'and blocking the main thread. LevelLoader should have it built asynchronously instead.'
|
console.warn 'Building', @get('name'), 'and blocking the main thread. LevelLoader should have it built asynchronously instead.'
|
||||||
spriteSheet = builder.build()
|
spriteSheet = @builder.build()
|
||||||
@spriteSheets[@spriteSheetKey(options)] = spriteSheet
|
@spriteSheets[key] = spriteSheet
|
||||||
# console.log "Generated fresh spritesheet", @spriteSheetKey(options)
|
|
||||||
spriteSheet
|
spriteSheet
|
||||||
|
|
||||||
onBuildSpriteSheetComplete: (e, key) ->
|
onBuildSpriteSheetComplete: (e, key) ->
|
||||||
@spriteSheets[key] = e.target.spriteSheet
|
@spriteSheets[key] = e.target.spriteSheet
|
||||||
@trigger 'build-complete'
|
@trigger 'build-complete'
|
||||||
# $('body').append(@getPortrait(key))
|
|
||||||
|
|
||||||
spriteSheetKey: (options) ->
|
spriteSheetKey: (options) ->
|
||||||
"#{@get('name')} - #{options.resolutionFactor}"
|
"#{@get('name')} - #{options.resolutionFactor}"
|
||||||
|
|
|
@ -180,6 +180,7 @@ module.exports = class ThangTypeEditView extends View
|
||||||
@thangType.resetSpriteSheetCache()
|
@thangType.resetSpriteSheetCache()
|
||||||
spriteSheet = @thangType.buildSpriteSheet(options)
|
spriteSheet = @thangType.buildSpriteSheet(options)
|
||||||
$('#canvases').empty()
|
$('#canvases').empty()
|
||||||
|
return unless spriteSheet
|
||||||
for image in spriteSheet._images
|
for image in spriteSheet._images
|
||||||
$('#canvases').append(image)
|
$('#canvases').append(image)
|
||||||
@showAnimation()
|
@showAnimation()
|
||||||
|
|
Reference in a new issue