mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-11 16:21:08 -05:00
Refactored WebGLLayer and SpriteContainerLayer/ContainerLayer into a single LayerAdapter class that has a Container or SpriteContainer.
This commit is contained in:
parent
2183b7dac1
commit
3b7ce76d7d
9 changed files with 197 additions and 194 deletions
|
@ -105,7 +105,6 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
if parent = @imageObject.parent
|
if parent = @imageObject.parent
|
||||||
parent.removeChild @imageObject
|
parent.removeChild @imageObject
|
||||||
parent.addChild newImageObject
|
parent.addChild newImageObject
|
||||||
parent.updateLayerOrder()
|
|
||||||
|
|
||||||
# get the cocosprite to update things
|
# get the cocosprite to update things
|
||||||
for prop in ['lastPos', 'currentRootAction']
|
for prop in ['lastPos', 'currentRootAction']
|
||||||
|
|
|
@ -1,127 +0,0 @@
|
||||||
###
|
|
||||||
* Stage
|
|
||||||
** surfaceLayer
|
|
||||||
*** Land texture
|
|
||||||
*** Ground-based selection/target marks, range radii
|
|
||||||
*** Walls/obstacles
|
|
||||||
*** Paths and target pieces (and ghosts?)
|
|
||||||
*** Normal Thangs, bots, wizards (z-indexing based on World-determined sprite.thang.pos.z/y, mainly, instead of sprite-map-determined sprite.z, which we rename to... something)
|
|
||||||
*** Above-thang marks (blood, highlight) and health bars
|
|
||||||
*** Camera border
|
|
||||||
** surfaceTextLayer (speech, names)
|
|
||||||
** screenLayer
|
|
||||||
*** Letterbox
|
|
||||||
**** Letterbox top and bottom
|
|
||||||
*** FPS display, maybe grid axis labels, coordinate hover
|
|
||||||
|
|
||||||
** Grid lines--somewhere--we will figure it out, do not really need it at first
|
|
||||||
###
|
|
||||||
|
|
||||||
layerClassProperties = {
|
|
||||||
TRANSFORM_CHILD: 'child' # Layer transform is managed by its parents
|
|
||||||
TRANSFORM_SURFACE: 'surface' # Layer moves/scales/zooms with the Surface of the World
|
|
||||||
TRANSFORM_SURFACE_TEXT: 'surface_text' # Layer moves with the Surface but is size-independent
|
|
||||||
TRANSFORM_SCREEN: 'screen' # Layer stays fixed to the screen (different from child?)
|
|
||||||
}
|
|
||||||
|
|
||||||
layerProperties = {
|
|
||||||
subscriptions:
|
|
||||||
'camera:zoom-updated': 'onZoomUpdated'
|
|
||||||
|
|
||||||
initializeLayer: (options) ->
|
|
||||||
options ?= {}
|
|
||||||
@name = options.name ? 'Unnamed'
|
|
||||||
@layerPriority = options.layerPriority ? 0
|
|
||||||
@transformStyle = options.transform ? layerClassProperties.TRANSFORM_CHILD
|
|
||||||
@camera = options.camera
|
|
||||||
@updateLayerOrder = _.bind(@updateLayerOrder, @)
|
|
||||||
@updateLayerOrder = _.throttle @updateLayerOrder, 1000 / 30 # Don't call multiple times in one frame; 30 FPS is probably good enough
|
|
||||||
Backbone.Mediator.subscribe(channel, @[func], @) for channel, func of @subscriptions
|
|
||||||
|
|
||||||
destroy: ->
|
|
||||||
child.destroy?() for child in @children
|
|
||||||
Backbone.Mediator.unsubscribe(channel, @[func], @) for channel, func of @subscriptions
|
|
||||||
delete @updateLayerOrder
|
|
||||||
|
|
||||||
toString: -> "<Layer #{@layerPriority}: #{@name}>"
|
|
||||||
|
|
||||||
updateLayerOrder: ->
|
|
||||||
@sortChildren @layerOrderComparator
|
|
||||||
|
|
||||||
layerOrderComparator: (a, b) ->
|
|
||||||
# Optimize
|
|
||||||
alp = a.layerPriority or 0
|
|
||||||
blp = b.layerPriority or 0
|
|
||||||
return alp - blp if alp isnt blp
|
|
||||||
# TODO: remove this z stuff
|
|
||||||
az = a.z or 1000
|
|
||||||
bz = b.z or 1000
|
|
||||||
if aSprite = a.sprite
|
|
||||||
if aThang = aSprite.thang
|
|
||||||
aPos = aThang.pos
|
|
||||||
if aThang.health < 0
|
|
||||||
--az
|
|
||||||
if bSprite = b.sprite
|
|
||||||
if bThang = bSprite.thang
|
|
||||||
bPos = bThang.pos
|
|
||||||
if bThang.health < 0
|
|
||||||
--bz
|
|
||||||
if az is bz
|
|
||||||
return 0 unless aPos and bPos
|
|
||||||
return (bPos.y - aPos.y) or (bPos.x - aPos.x)
|
|
||||||
return az - bz
|
|
||||||
|
|
||||||
onZoomUpdated: (e) ->
|
|
||||||
return unless e.camera is @camera
|
|
||||||
if @transformStyle in [layerClassProperties.TRANSFORM_SURFACE, layerClassProperties.TRANSFORM_SURFACE_TEXT, layerClassProperties.TRANSFORM_CHILD]
|
|
||||||
change = @scaleX / e.zoom
|
|
||||||
@scaleX = @scaleY = e.zoom
|
|
||||||
@regX = e.surfaceViewport.x
|
|
||||||
@regY = e.surfaceViewport.y
|
|
||||||
if @transformStyle is layerClassProperties.TRANSFORM_SURFACE_TEXT
|
|
||||||
for child in @children
|
|
||||||
child.scaleX *= change
|
|
||||||
child.scaleY *= change
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ContainerLayer extends createjs.Container
|
|
||||||
constructor: (options) ->
|
|
||||||
super()
|
|
||||||
@initialize()
|
|
||||||
@initializeLayer(options)
|
|
||||||
|
|
||||||
addChild: (children...) ->
|
|
||||||
super children...
|
|
||||||
if @transformStyle is ContainerLayer.TRANSFORM_SURFACE_TEXT
|
|
||||||
for child in children
|
|
||||||
child.scaleX /= @scaleX
|
|
||||||
child.scaleY /= @scaleY
|
|
||||||
|
|
||||||
removeChild: (children...) ->
|
|
||||||
super children...
|
|
||||||
if @transformStyle is ContainerLayer.TRANSFORM_SURFACE_TEXT
|
|
||||||
for child in children
|
|
||||||
child.scaleX *= @scaleX
|
|
||||||
child.scaleY *= @scaleY
|
|
||||||
|
|
||||||
cache: ->
|
|
||||||
return unless @children.length
|
|
||||||
bounds = @getBounds()
|
|
||||||
return unless bounds
|
|
||||||
super bounds.x, bounds.y, bounds.width, bounds.height, 2
|
|
||||||
|
|
||||||
class SpriteContainerLayer extends createjs.SpriteContainer
|
|
||||||
constructor: (spriteSheet, options) ->
|
|
||||||
super(spriteSheet)
|
|
||||||
@initialize(spriteSheet)
|
|
||||||
@initializeLayer(options)
|
|
||||||
|
|
||||||
_.extend(ContainerLayer.prototype, layerProperties)
|
|
||||||
_.extend(SpriteContainerLayer.prototype, layerProperties)
|
|
||||||
_.extend(ContainerLayer, layerClassProperties)
|
|
||||||
_.extend(SpriteContainerLayer, layerClassProperties)
|
|
||||||
|
|
||||||
module.exports.ContainerLayer = ContainerLayer
|
|
||||||
module.exports.SpriteContainerLayer = SpriteContainerLayer
|
|
|
@ -1,15 +1,41 @@
|
||||||
|
###
|
||||||
|
* SpriteStage (WebGL Canvas)
|
||||||
|
** Land texture
|
||||||
|
** Ground-based selection/target marks, range radii
|
||||||
|
** Walls/obstacles
|
||||||
|
** Paths and target pieces (and ghosts?)
|
||||||
|
** Normal Thangs, bots, wizards (z-indexing based on World-determined sprite.thang.pos.z/y, mainly, instead of sprite-map-determined sprite.z, which we rename to... something)
|
||||||
|
** Above-thang marks (blood, highlight) and health bars
|
||||||
|
|
||||||
|
* Stage (Regular Canvas)
|
||||||
|
** Camera border
|
||||||
|
** surfaceTextLayer (speech, names)
|
||||||
|
** screenLayer
|
||||||
|
*** Letterbox
|
||||||
|
**** Letterbox top and bottom
|
||||||
|
*** FPS display, maybe grid axis labels, coordinate hover
|
||||||
|
|
||||||
|
** Grid lines--somewhere--we will figure it out, do not really need it at first
|
||||||
|
###
|
||||||
|
|
||||||
SpriteBuilder = require 'lib/sprites/SpriteBuilder'
|
SpriteBuilder = require 'lib/sprites/SpriteBuilder'
|
||||||
CocoClass = require 'lib/CocoClass'
|
CocoClass = require 'lib/CocoClass'
|
||||||
SegmentedSprite = require './SegmentedSprite'
|
SegmentedSprite = require './SegmentedSprite'
|
||||||
SingularSprite = require './SingularSprite'
|
SingularSprite = require './SingularSprite'
|
||||||
{SpriteContainerLayer} = require 'lib/surface/Layer'
|
|
||||||
|
|
||||||
NEVER_RENDER_ANYTHING = false # set to true to test placeholders
|
NEVER_RENDER_ANYTHING = false # set to true to test placeholders
|
||||||
|
|
||||||
module.exports = class LayerAdapter extends CocoClass
|
module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
||||||
|
|
||||||
_.extend(LayerAdapter.prototype, Backbone.Events)
|
# Intermediary between a Surface Stage and a top-level static normal Container or hot-swapped WebGL SpriteContainer.
|
||||||
|
# It handles zooming in different ways and, if webGL, creating and assigning spriteSheets.
|
||||||
|
|
||||||
|
@TRANSFORM_CHILD: 'child' # Layer transform is managed by its parents
|
||||||
|
@TRANSFORM_SURFACE: 'surface' # Layer moves/scales/zooms with the Surface of the World
|
||||||
|
@TRANSFORM_SURFACE_TEXT: 'surface_text' # Layer moves with the Surface but is size-independent
|
||||||
|
@TRANSFORM_SCREEN: 'screen' # Layer stays fixed to the screen (different from child?)
|
||||||
|
|
||||||
|
# WebGL properties
|
||||||
actionRenderState: null
|
actionRenderState: null
|
||||||
needToRerender: false
|
needToRerender: false
|
||||||
toRenderBundles: null
|
toRenderBundles: null
|
||||||
|
@ -21,27 +47,104 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
numThingsLoading: 0
|
numThingsLoading: 0
|
||||||
cocoSprites: null
|
cocoSprites: null
|
||||||
spriteSheet: null
|
spriteSheet: null
|
||||||
spriteContainer: null
|
container: null
|
||||||
|
|
||||||
constructor: (@layerOptions) ->
|
subscriptions:
|
||||||
@layerOptions ?= {}
|
'camera:zoom-updated': 'onZoomUpdated'
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
super()
|
super()
|
||||||
|
options ?= {}
|
||||||
|
@name = options.name ? 'Unnamed'
|
||||||
|
@layerPriority = options.layerPriority ? 0
|
||||||
|
@transformStyle = options.transform ? LayerAdapter.TRANSFORM_CHILD
|
||||||
|
@camera = options.camera
|
||||||
|
@updateLayerOrder = _.throttle @updateLayerOrder, 1000 / 30 # Don't call multiple times in one frame; 30 FPS is probably good enough
|
||||||
|
|
||||||
|
@webGL = !!options.webGL
|
||||||
|
if @webGL
|
||||||
@initializing = true
|
@initializing = true
|
||||||
@spriteSheet = @_renderNewSpriteSheet(false) # builds an empty spritesheet
|
@spriteSheet = @_renderNewSpriteSheet(false) # builds an empty spritesheet
|
||||||
@spriteContainer = new SpriteContainerLayer(@spriteSheet, @layerOptions)
|
@container = new createjs.SpriteContainer(@spriteSheet)
|
||||||
@actionRenderState = {}
|
@actionRenderState = {}
|
||||||
@toRenderBundles = []
|
@toRenderBundles = []
|
||||||
@cocoSprites = []
|
@cocoSprites = []
|
||||||
@initializing = false
|
@initializing = false
|
||||||
|
|
||||||
setDefaultActions: (@defaultActions) ->
|
else
|
||||||
|
@container = new createjs.Container()
|
||||||
|
|
||||||
renderGroupingKey: (thangType, grouping, colorConfig) ->
|
toString: -> "<Layer #{@layerPriority}: #{@name}>"
|
||||||
key = thangType.get('slug')
|
|
||||||
if colorConfig?.team
|
#- Layer ordering
|
||||||
key += "(#{colorConfig.team.hue},#{colorConfig.team.saturation},#{colorConfig.team.lightness})"
|
|
||||||
key += '.'+grouping if grouping
|
updateLayerOrder: ->
|
||||||
key
|
@container.sortChildren @layerOrderComparator
|
||||||
|
|
||||||
|
layerOrderComparator: (a, b) ->
|
||||||
|
# Optimize
|
||||||
|
alp = a.layerPriority or 0
|
||||||
|
blp = b.layerPriority or 0
|
||||||
|
return alp - blp if alp isnt blp
|
||||||
|
# TODO: remove this z stuff
|
||||||
|
az = a.z or 1000
|
||||||
|
bz = b.z or 1000
|
||||||
|
if aSprite = a.sprite
|
||||||
|
if aThang = aSprite.thang
|
||||||
|
aPos = aThang.pos
|
||||||
|
if aThang.health < 0
|
||||||
|
--az
|
||||||
|
if bSprite = b.sprite
|
||||||
|
if bThang = bSprite.thang
|
||||||
|
bPos = bThang.pos
|
||||||
|
if bThang.health < 0
|
||||||
|
--bz
|
||||||
|
if az is bz
|
||||||
|
return 0 unless aPos and bPos
|
||||||
|
return (bPos.y - aPos.y) or (bPos.x - aPos.x)
|
||||||
|
return az - bz
|
||||||
|
|
||||||
|
#- Zoom updating
|
||||||
|
|
||||||
|
onZoomUpdated: (e) ->
|
||||||
|
return unless e.camera is @camera
|
||||||
|
if @transformStyle in [LayerAdapter.TRANSFORM_SURFACE, LayerAdapter.TRANSFORM_SURFACE_TEXT, LayerAdapter.TRANSFORM_CHILD]
|
||||||
|
change = @container.scaleX / e.zoom
|
||||||
|
@container.scaleX = @container.scaleY = e.zoom
|
||||||
|
@container.regX = e.surfaceViewport.x
|
||||||
|
@container.regY = e.surfaceViewport.y
|
||||||
|
if @transformStyle is LayerAdapter.TRANSFORM_SURFACE_TEXT
|
||||||
|
for child in @container.children
|
||||||
|
child.scaleX *= change
|
||||||
|
child.scaleY *= change
|
||||||
|
|
||||||
|
#- Caching
|
||||||
|
|
||||||
|
cache: ->
|
||||||
|
return if @webGL
|
||||||
|
return unless @children.length
|
||||||
|
bounds = @container.getBounds()
|
||||||
|
return unless bounds
|
||||||
|
@container.cache bounds.x, bounds.y, bounds.width, bounds.height, 2
|
||||||
|
|
||||||
|
#- Container-like child functions
|
||||||
|
|
||||||
|
addChild: (children...) ->
|
||||||
|
container.addChild children...
|
||||||
|
if @transformStyle is ContainerLayer.TRANSFORM_SURFACE_TEXT
|
||||||
|
for child in children
|
||||||
|
child.scaleX /= @scaleX
|
||||||
|
child.scaleY /= @scaleY
|
||||||
|
|
||||||
|
removeChild: (children...) ->
|
||||||
|
container.removeChild children...
|
||||||
|
# TODO: Do we actually need to scale children that were removed?
|
||||||
|
if @transformStyle is ContainerLayer.TRANSFORM_SURFACE_TEXT
|
||||||
|
for child in children
|
||||||
|
child.scaleX *= @scaleX
|
||||||
|
child.scaleY *= @scaleY
|
||||||
|
|
||||||
|
#- Adding, removing children for WebGL layers.
|
||||||
|
|
||||||
addCocoSprite: (cocoSprite) ->
|
addCocoSprite: (cocoSprite) ->
|
||||||
cocoSprite.options.resolutionFactor = @resolutionFactor
|
cocoSprite.options.resolutionFactor = @resolutionFactor
|
||||||
|
@ -55,15 +158,14 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
@loadThangType(cocoSprite.thangType)
|
@loadThangType(cocoSprite.thangType)
|
||||||
@addDefaultActionsToRender(cocoSprite)
|
@addDefaultActionsToRender(cocoSprite)
|
||||||
@setImageObjectToCocoSprite(cocoSprite)
|
@setImageObjectToCocoSprite(cocoSprite)
|
||||||
# TODO: actually add it as a child
|
@updateLayerOrder()
|
||||||
|
|
||||||
removeCocoSprite: (cocoSprite) ->
|
removeCocoSprite: (cocoSprite) ->
|
||||||
@stopListening(cocoSprite)
|
@stopListening(cocoSprite)
|
||||||
cocoSprite.imageObject.parent.removeChild cocoSprite.imageObject
|
cocoSprite.imageObject.parent.removeChild cocoSprite.imageObject
|
||||||
@cocoSprites = _.without @cocoSprites, cocoSprite
|
@cocoSprites = _.without @cocoSprites, cocoSprite
|
||||||
|
|
||||||
onActionNeedsRender: (cocoSprite, action) ->
|
#- Loading network resources dynamically
|
||||||
@upsertActionToRender(cocoSprite.thangType, action.name, cocoSprite.options.colorConfig)
|
|
||||||
|
|
||||||
loadThangType: (thangType) ->
|
loadThangType: (thangType) ->
|
||||||
if not thangType.isFullyLoaded()
|
if not thangType.isFullyLoaded()
|
||||||
|
@ -84,6 +186,11 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
@addDefaultActionsToRender(cocoSprite)
|
@addDefaultActionsToRender(cocoSprite)
|
||||||
@renderNewSpriteSheet()
|
@renderNewSpriteSheet()
|
||||||
|
|
||||||
|
#- Adding to the list of things we need to render
|
||||||
|
|
||||||
|
onActionNeedsRender: (cocoSprite, action) ->
|
||||||
|
@upsertActionToRender(cocoSprite.thangType, action.name, cocoSprite.options.colorConfig)
|
||||||
|
|
||||||
addDefaultActionsToRender: (cocoSprite) ->
|
addDefaultActionsToRender: (cocoSprite) ->
|
||||||
needToRender = false
|
needToRender = false
|
||||||
if cocoSprite.thangType.get('raster')
|
if cocoSprite.thangType.get('raster')
|
||||||
|
@ -102,6 +209,8 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
@willRender = _.defer => @renderNewSpriteSheet()
|
@willRender = _.defer => @renderNewSpriteSheet()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
#- Rendering sprite sheets
|
||||||
|
|
||||||
renderNewSpriteSheet: ->
|
renderNewSpriteSheet: ->
|
||||||
@willRender = false
|
@willRender = false
|
||||||
return if @numThingsLoading
|
return if @numThingsLoading
|
||||||
|
@ -126,11 +235,11 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
args = [thangType, colorConfig, actionNames, builder]
|
args = [thangType, colorConfig, actionNames, builder]
|
||||||
if thangType.get('raw')
|
if thangType.get('raw')
|
||||||
if thangType.get('spriteType') is 'segmented'
|
if thangType.get('spriteType') is 'segmented'
|
||||||
@renderContainers(args...)
|
@renderSegmentedThangType(args...)
|
||||||
else
|
else
|
||||||
@renderSpriteSheet(args...)
|
@renderSingularThangType(args...)
|
||||||
else
|
else
|
||||||
@renderRasterImage(thangType, builder)
|
@renderRasterThangType(thangType, builder)
|
||||||
|
|
||||||
if async
|
if async
|
||||||
builder.buildAsync()
|
builder.buildAsync()
|
||||||
|
@ -140,17 +249,6 @@ module.exports = class LayerAdapter 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
|
||||||
|
|
||||||
|
@ -162,18 +260,18 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
|
|
||||||
@spriteSheet = builder.spriteSheet
|
@spriteSheet = builder.spriteSheet
|
||||||
@spriteSheet.resolutionFactor = @resolutionFactor
|
@spriteSheet.resolutionFactor = @resolutionFactor
|
||||||
oldLayer = @spriteContainer
|
oldLayer = @container
|
||||||
@spriteContainer = new SpriteContainerLayer(@spriteSheet, @layerOptions)
|
@container = new createjs.SpriteContainer(@spriteSheet)
|
||||||
for cocoSprite in @cocoSprites
|
for cocoSprite in @cocoSprites
|
||||||
@setImageObjectToCocoSprite(cocoSprite)
|
@setImageObjectToCocoSprite(cocoSprite)
|
||||||
for prop in ['scaleX', 'scaleY', 'regX', 'regY']
|
for prop in ['scaleX', 'scaleY', 'regX', 'regY']
|
||||||
@spriteContainer[prop] = oldLayer[prop]
|
@container[prop] = oldLayer[prop]
|
||||||
if parent = oldLayer.parent
|
if parent = oldLayer.parent
|
||||||
index = parent.getChildIndex(oldLayer)
|
index = parent.getChildIndex(oldLayer)
|
||||||
parent.removeChildAt(index)
|
parent.removeChildAt(index)
|
||||||
parent.addChildAt(@spriteContainer, index)
|
parent.addChildAt(@container, index)
|
||||||
@layerOptions.camera?.updateZoom(true)
|
@camera?.updateZoom(true)
|
||||||
@spriteContainer.updateLayerOrder()
|
@updateLayerOrder()
|
||||||
for cocoSprite in @cocoSprites
|
for cocoSprite in @cocoSprites
|
||||||
cocoSprite.options.resolutionFactor = @resolutionFactor
|
cocoSprite.options.resolutionFactor = @resolutionFactor
|
||||||
cocoSprite.updateBaseScale()
|
cocoSprite.updateBaseScale()
|
||||||
|
@ -181,7 +279,22 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
cocoSprite.updateRotation()
|
cocoSprite.updateRotation()
|
||||||
@trigger 'new-spritesheet'
|
@trigger 'new-spritesheet'
|
||||||
|
|
||||||
renderContainers: (thangType, colorConfig, actionNames, spriteSheetBuilder) ->
|
#- Placeholder
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
#- Rendering containers for segmented thang types
|
||||||
|
|
||||||
|
renderSegmentedThangType: (thangType, colorConfig, actionNames, spriteSheetBuilder) ->
|
||||||
containersToRender = {}
|
containersToRender = {}
|
||||||
for actionName in actionNames
|
for actionName in actionNames
|
||||||
action = _.find(thangType.getActions(), {name: actionName})
|
action = _.find(thangType.getActions(), {name: actionName})
|
||||||
|
@ -209,7 +322,9 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
containers = containers.concat(@getContainersForAnimation(thangType, animation.gn))
|
containers = containers.concat(@getContainersForAnimation(thangType, animation.gn))
|
||||||
return containers
|
return containers
|
||||||
|
|
||||||
renderSpriteSheet: (thangType, colorConfig, actionNames, spriteSheetBuilder) ->
|
#- Rendering sprite sheets for singular thang types
|
||||||
|
|
||||||
|
renderSingularThangType: (thangType, colorConfig, actionNames, spriteSheetBuilder) ->
|
||||||
actionObjects = _.values(thangType.getActions())
|
actionObjects = _.values(thangType.getActions())
|
||||||
animationActions = []
|
animationActions = []
|
||||||
for a in actionObjects
|
for a in actionObjects
|
||||||
|
@ -284,7 +399,9 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
next = false if action.loops is false
|
next = false if action.loops is false
|
||||||
return next
|
return next
|
||||||
|
|
||||||
renderRasterImage: (thangType, spriteSheetBuilder) ->
|
#- Rendering frames for raster thang types
|
||||||
|
|
||||||
|
renderRasterThangType: (thangType, spriteSheetBuilder) ->
|
||||||
unless thangType.rasterImage
|
unless thangType.rasterImage
|
||||||
console.error("Cannot render the LayerAdapter SpriteSheet until the raster image for <#{thangType.get('name')}> is loaded.")
|
console.error("Cannot render the LayerAdapter SpriteSheet until the raster image for <#{thangType.get('name')}> is loaded.")
|
||||||
|
|
||||||
|
@ -293,6 +410,8 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
frame = spriteSheetBuilder.addFrame(bm, null, scale)
|
frame = spriteSheetBuilder.addFrame(bm, null, scale)
|
||||||
spriteSheetBuilder.addAnimation(@renderGroupingKey(thangType), [frame], false)
|
spriteSheetBuilder.addAnimation(@renderGroupingKey(thangType), [frame], false)
|
||||||
|
|
||||||
|
#- Distributing new Segmented/Singular/RasterSprites to CocoSprites
|
||||||
|
|
||||||
setImageObjectToCocoSprite: (cocoSprite) ->
|
setImageObjectToCocoSprite: (cocoSprite) ->
|
||||||
if not cocoSprite.thangType.isFullyLoaded()
|
if not cocoSprite.thangType.isFullyLoaded()
|
||||||
# just give a placeholder
|
# just give a placeholder
|
||||||
|
@ -316,4 +435,15 @@ module.exports = class LayerAdapter extends CocoClass
|
||||||
cocoSprite.addHealthBar()
|
cocoSprite.addHealthBar()
|
||||||
cocoSprite.setImageObject(sprite)
|
cocoSprite.setImageObject(sprite)
|
||||||
cocoSprite.update(true)
|
cocoSprite.update(true)
|
||||||
@spriteContainer.addChild(sprite)
|
@container.addChild(sprite)
|
||||||
|
|
||||||
|
renderGroupingKey: (thangType, grouping, colorConfig) ->
|
||||||
|
key = thangType.get('slug')
|
||||||
|
if colorConfig?.team
|
||||||
|
key += "(#{colorConfig.team.hue},#{colorConfig.team.saturation},#{colorConfig.team.lightness})"
|
||||||
|
key += '.'+grouping if grouping
|
||||||
|
key
|
||||||
|
|
||||||
|
destroy: ->
|
||||||
|
child.destroy?() for child in @container.children
|
||||||
|
super()
|
|
@ -1,6 +1,6 @@
|
||||||
CocoClass = require 'lib/CocoClass'
|
CocoClass = require 'lib/CocoClass'
|
||||||
{me} = require 'lib/auth'
|
{me} = require 'lib/auth'
|
||||||
Layer = require './LayerAdapter'
|
LayerAdapter = require './LayerAdapter'
|
||||||
IndieSprite = require 'lib/surface/IndieSprite'
|
IndieSprite = require 'lib/surface/IndieSprite'
|
||||||
WizardSprite = require 'lib/surface/WizardSprite'
|
WizardSprite = require 'lib/surface/WizardSprite'
|
||||||
FlagSprite = require 'lib/surface/FlagSprite'
|
FlagSprite = require 'lib/surface/FlagSprite'
|
||||||
|
@ -65,8 +65,8 @@ module.exports = class SpriteBoss extends CocoClass
|
||||||
['Default', 0]
|
['Default', 0]
|
||||||
['Floating', 10]
|
['Floating', 10]
|
||||||
]
|
]
|
||||||
@spriteLayers[name] = new Layer name: name, layerPriority: priority, transform: Layer.TRANSFORM_CHILD, camera: @camera
|
@spriteLayers[name] = new LayerAdapter name: name, webGL: true, layerPriority: priority, transform: LayerAdapter.TRANSFORM_CHILD, camera: @camera
|
||||||
@surfaceLayer.addChild (spriteLayer.spriteContainer for spriteLayer in _.values(@spriteLayers))...
|
@surfaceLayer.addChild (spriteLayer.container for spriteLayer in _.values(@spriteLayers))...
|
||||||
|
|
||||||
layerForChild: (child, sprite) ->
|
layerForChild: (child, sprite) ->
|
||||||
unless child.layerPriority?
|
unless child.layerPriority?
|
||||||
|
@ -77,7 +77,7 @@ module.exports = class SpriteBoss extends CocoClass
|
||||||
child.layerPriority ?= 0
|
child.layerPriority ?= 0
|
||||||
return @spriteLayers['Default'] unless child.layerPriority
|
return @spriteLayers['Default'] unless child.layerPriority
|
||||||
layer = _.findLast @spriteLayers, (layer, name) ->
|
layer = _.findLast @spriteLayers, (layer, name) ->
|
||||||
layer.spriteContainer.layerPriority <= child.layerPriority
|
layer.layerPriority <= child.layerPriority
|
||||||
layer ?= @spriteLayers['Land'] if child.layerPriority < -40
|
layer ?= @spriteLayers['Land'] if child.layerPriority < -40
|
||||||
layer ? @spriteLayers['Default']
|
layer ? @spriteLayers['Default']
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ module.exports = class SpriteBoss extends CocoClass
|
||||||
layer ?= @spriteLayers['Obstacle'] if sprite.thang?.spriteName.search(/(dungeon|indoor).wall/i) isnt -1
|
layer ?= @spriteLayers['Obstacle'] if sprite.thang?.spriteName.search(/(dungeon|indoor).wall/i) isnt -1
|
||||||
layer ?= @layerForChild sprite.imageObject, sprite
|
layer ?= @layerForChild sprite.imageObject, sprite
|
||||||
layer.addCocoSprite sprite
|
layer.addCocoSprite sprite
|
||||||
layer.spriteContainer.updateLayerOrder()
|
layer.updateLayerOrder()
|
||||||
sprite
|
sprite
|
||||||
|
|
||||||
createMarks: ->
|
createMarks: ->
|
||||||
|
@ -185,7 +185,7 @@ module.exports = class SpriteBoss extends CocoClass
|
||||||
@adjustSpriteExistence() if frameChanged
|
@adjustSpriteExistence() if frameChanged
|
||||||
sprite.update frameChanged for sprite in @spriteArray
|
sprite.update frameChanged for sprite in @spriteArray
|
||||||
@updateSelection()
|
@updateSelection()
|
||||||
@spriteLayers['Default'].spriteContainer.updateLayerOrder()
|
@spriteLayers['Default'].updateLayerOrder()
|
||||||
@cache()
|
@cache()
|
||||||
|
|
||||||
adjustSpriteExistence: ->
|
adjustSpriteExistence: ->
|
||||||
|
|
|
@ -8,7 +8,7 @@ SpriteBuilder = require 'lib/sprites/SpriteBuilder'
|
||||||
describe 'LayerAdapter', ->
|
describe 'LayerAdapter', ->
|
||||||
layer = null
|
layer = null
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
layer = new LayerAdapter()
|
layer = new LayerAdapter({webGL:true})
|
||||||
layer.buildAutomatically = false
|
layer.buildAutomatically = false
|
||||||
layer.buildAsync = false
|
layer.buildAsync = false
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ describe 'LayerAdapter', ->
|
||||||
expect(key in sheet.getAnimations()).toBe(true)
|
expect(key in sheet.getAnimations()).toBe(true)
|
||||||
|
|
||||||
it 'only renders frames used by actions when spriteType=singular', ->
|
it 'only renders frames used by actions when spriteType=singular', ->
|
||||||
layer.setDefaultActions(['idle']) # uses the move side animation
|
layer.defaultActions = ['idle'] # uses the move side animation
|
||||||
ogreMunchkinThangType.set('spriteType', 'singular')
|
ogreMunchkinThangType.set('spriteType', 'singular')
|
||||||
colorConfig = {team: {hue: 0, saturation: 1, lightness: 0.5}}
|
colorConfig = {team: {hue: 0, saturation: 1, lightness: 0.5}}
|
||||||
sprite = new CocoSprite(ogreMunchkinThangType, {colorConfig: colorConfig})
|
sprite = new CocoSprite(ogreMunchkinThangType, {colorConfig: colorConfig})
|
||||||
|
|
|
@ -26,7 +26,7 @@ describe 'SegmentedSprite', ->
|
||||||
|
|
||||||
describe 'with Ogre Munchkin ThangType', ->
|
describe 'with Ogre Munchkin ThangType', ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
layer = new LayerAdapter()
|
layer = new LayerAdapter({webGL:true})
|
||||||
layer.buildAutomatically = false
|
layer.buildAutomatically = false
|
||||||
layer.buildAsync = false
|
layer.buildAsync = false
|
||||||
ogreMunchkinThangType.markToRevert()
|
ogreMunchkinThangType.markToRevert()
|
||||||
|
@ -82,7 +82,7 @@ describe 'SegmentedSprite', ->
|
||||||
|
|
||||||
describe 'with Ogre Fangrider ThangType', ->
|
describe 'with Ogre Fangrider ThangType', ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
layer = new LayerAdapter()
|
layer = new LayerAdapter({webGL:true})
|
||||||
layer.buildAutomatically = false
|
layer.buildAutomatically = false
|
||||||
layer.buildAsync = false
|
layer.buildAsync = false
|
||||||
ogreFangriderThangType.markToRevert()
|
ogreFangriderThangType.markToRevert()
|
||||||
|
|
|
@ -24,7 +24,7 @@ describe 'SingularSprite', ->
|
||||||
|
|
||||||
describe 'with Ogre Munchkin ThangType', ->
|
describe 'with Ogre Munchkin ThangType', ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
layer = new LayerAdapter()
|
layer = new LayerAdapter({webGL:true})
|
||||||
layer.buildAutomatically = false
|
layer.buildAutomatically = false
|
||||||
layer.buildAsync = false
|
layer.buildAsync = false
|
||||||
ogreMunchkinThangType.markToRevert()
|
ogreMunchkinThangType.markToRevert()
|
||||||
|
|
|
@ -62,7 +62,7 @@ describe 'SpriteBoss', ->
|
||||||
# Sort of an implicit test. By default, all the default actions are always rendered,
|
# Sort of an implicit test. By default, all the default actions are always rendered,
|
||||||
# but I want to make sure the system can dynamically hear about actions it needs to render for
|
# but I want to make sure the system can dynamically hear about actions it needs to render for
|
||||||
# as they are used.
|
# as they are used.
|
||||||
defaultLayer.setDefaultActions(['idle'])
|
defaultLayer.defaultActions = ['idle']
|
||||||
|
|
||||||
# Render the simple world with just trees
|
# Render the simple world with just trees
|
||||||
spriteBoss.update(true)
|
spriteBoss.update(true)
|
||||||
|
@ -163,8 +163,8 @@ describe 'SpriteBoss', ->
|
||||||
expect(spriteBoss.sprites['Ogre E'].imageObject.alpha).toBe(0.5)
|
expect(spriteBoss.sprites['Ogre E'].imageObject.alpha).toBe(0.5)
|
||||||
|
|
||||||
it 'orders sprites in the layer based on thang pos.y\'s', ->
|
it 'orders sprites in the layer based on thang pos.y\'s', ->
|
||||||
container = spriteBoss.spriteLayers.Default.spriteContainer
|
container = spriteBoss.spriteLayers.Default.container
|
||||||
l = spriteBoss.spriteLayers.Default.spriteContainer.children
|
l = container.children
|
||||||
i1 = container.getChildIndex(_.find(container.children, (c) -> c.sprite.thang.id is 'Dying Ogre 1'))
|
i1 = container.getChildIndex(_.find(container.children, (c) -> c.sprite.thang.id is 'Dying Ogre 1'))
|
||||||
i2 = container.getChildIndex(_.find(container.children, (c) -> c.sprite.thang.id is 'Dying Ogre 2'))
|
i2 = container.getChildIndex(_.find(container.children, (c) -> c.sprite.thang.id is 'Dying Ogre 2'))
|
||||||
i3 = container.getChildIndex(_.find(container.children, (c) -> c.sprite.thang.id is 'Dying Ogre 3'))
|
i3 = container.getChildIndex(_.find(container.children, (c) -> c.sprite.thang.id is 'Dying Ogre 3'))
|
||||||
|
@ -174,6 +174,6 @@ describe 'SpriteBoss', ->
|
||||||
expect(i3).toBeGreaterThan(i4)
|
expect(i3).toBeGreaterThan(i4)
|
||||||
|
|
||||||
it 'only contains children Sprites and SpriteContainers whose spritesheet matches the Layer', ->
|
it 'only contains children Sprites and SpriteContainers whose spritesheet matches the Layer', ->
|
||||||
defaultLayerContainer = spriteBoss.spriteLayers.Default.spriteContainer
|
defaultLayerContainer = spriteBoss.spriteLayers.Default.container
|
||||||
for c in defaultLayerContainer.children
|
for c in defaultLayerContainer.children
|
||||||
expect(c.spriteSheet).toBe(defaultLayerContainer.spriteSheet)
|
expect(c.spriteSheet).toBe(defaultLayerContainer.spriteSheet)
|
||||||
|
|
1
vendor/scripts/SpriteStage.js
vendored
1
vendor/scripts/SpriteStage.js
vendored
|
@ -432,6 +432,7 @@ var p = SpriteStage.prototype = new createjs.Stage();
|
||||||
if (child._spritestage_compatibility >= 1) {
|
if (child._spritestage_compatibility >= 1) {
|
||||||
// The child is compatible with SpriteStage.
|
// The child is compatible with SpriteStage.
|
||||||
} else {
|
} else {
|
||||||
|
console.trace();
|
||||||
console && console.log("Error: You can only add children of type SpriteContainer, Sprite, Bitmap, BitmapText, or DOMElement. [" + child.toString() + "]");
|
console && console.log("Error: You can only add children of type SpriteContainer, Sprite, Bitmap, BitmapText, or DOMElement. [" + child.toString() + "]");
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue