mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 23:58:02 -05:00
527 lines
No EOL
17 KiB
CoffeeScript
527 lines
No EOL
17 KiB
CoffeeScript
RootView = require 'views/kinds/RootView'
|
|
waterfallLib = require 'test/demo/fixtures/waterfall'
|
|
librarianLib = require 'test/demo/fixtures/librarian'
|
|
|
|
class WebGLDemoView extends RootView
|
|
template: -> '<canvas id="visible-canvas" width="1200" height="700" style="background: #ddd"><canvas id="invisible-canvas" width="0" height="0" style="display: none">'
|
|
|
|
testMovieClipWithRasterizedSpriteChildren: ->
|
|
# put two rasterized sprites into a movie clip and show that
|
|
stage = new createjs.Stage(@$el.find('canvas')[0])
|
|
createjs.Ticker.addEventListener "tick", stage
|
|
|
|
child1Shape = new createjs.Shape(new createjs.Graphics().beginFill("#999999").drawCircle(30, 30, 30))
|
|
child2Shape = new createjs.Shape(new createjs.Graphics().beginFill("#5a9cfb").drawCircle(50, 50, 30))
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
builder.addFrame(child1Shape, {x:0, y:0, width: 200, height: 200})
|
|
builder.addFrame(child2Shape, {x:0, y:0, width: 200, height: 200})
|
|
sheet = builder.build()
|
|
child1Sprite = new createjs.Sprite(sheet, 0)
|
|
child2Sprite = new createjs.Sprite(sheet, 1)
|
|
child2Sprite.stop()
|
|
|
|
mc = new createjs.MovieClip(null, 0, true, {start: 20})
|
|
stage.addChild mc
|
|
mc.timeline.addTween createjs.Tween.get(child1Sprite).to(x: 0).to({x: 60}, 50).to({x: 0}, 50)
|
|
mc.timeline.addTween createjs.Tween.get(child2Sprite).to(x: 60).to({x: 0}, 50).to({x: 60}, 50)
|
|
mc.gotoAndPlay "start"
|
|
|
|
testMovieClipWithEmptyObjectChildren: ->
|
|
# See if I can have the movie clip animate empty objects so we have the properties in
|
|
# an object that we can update our real sprites with
|
|
stage = new createjs.Stage(@$el.find('#visible-canvas')[0])
|
|
createjs.Ticker.addEventListener "tick", stage
|
|
|
|
d1 = {}
|
|
d2 = {}
|
|
mc = new createjs.MovieClip(null, 0, true, {start: 20})
|
|
stage.addChild mc
|
|
mc.timeline.addTween createjs.Tween.get(d1).to(x: 0).to({x: 60}, 50).to({x: 0}, 50)
|
|
mc.timeline.addTween createjs.Tween.get(d2).to(x: 60).to({x: 0}, 50).to({x: 60}, 50)
|
|
mc.gotoAndPlay "start"
|
|
window.d1 = d1
|
|
window.d2 = d2
|
|
|
|
f = ->
|
|
console.log(JSON.stringify([d1, d2]))
|
|
setInterval(f, 1000)
|
|
# Seems to work. Can perhaps have the movieclip do the heavy lifting of moving containers around
|
|
# and then copy the info over to individual sprites in a separate stage
|
|
|
|
testWaterfallRasteredPerformance: ->
|
|
# rasterize waterfall movieclip (this is what we do now)
|
|
stage = new createjs.Stage(@$el.find('canvas')[0])
|
|
createjs.Ticker.addEventListener "tick", stage
|
|
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
waterfall = new waterfallLib.waterfallRed_JSCC()
|
|
builder.addMovieClip(waterfall)
|
|
t0 = new Date().getTime()
|
|
sheet = builder.build()
|
|
t1 = new Date().getTime()
|
|
console.log "Time to build waterfall sprite sheet: #{t1-t0}ms"
|
|
sprite = new createjs.Sprite(sheet, 'start')
|
|
stage.addChild(sprite)
|
|
|
|
test11: ->
|
|
# Replace the Container constructors in the waterfall lib with a stub class
|
|
# that will instead return our constructed sheet.
|
|
stage = new createjs.Stage(@$el.find('canvas')[0])
|
|
createjs.Ticker.addEventListener "tick", stage
|
|
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
frames = []
|
|
|
|
createClass = (frame) ->
|
|
class Stub
|
|
constructor: ->
|
|
sprite = new createjs.Sprite(sheet, frame)
|
|
sprite.stop()
|
|
return sprite
|
|
|
|
for name, klass of waterfallLib
|
|
window.klass = klass
|
|
continue if name is 'waterfallRed_JSCC'
|
|
instance = new klass()
|
|
builder.addFrame(instance, instance.nominalBounds)
|
|
waterfallLib[name] = createClass(frames.length)
|
|
frames.push frames.length
|
|
|
|
t0 = new Date().getTime()
|
|
sheet = builder.build()
|
|
t1 = new Date().getTime()
|
|
console.log "Time to build waterfall containers: #{t1-t0}ms"
|
|
|
|
waterfall = new waterfallLib.waterfallRed_JSCC()
|
|
stage.addChild(waterfall)
|
|
@$el.append(sheet._images[0])
|
|
@$el.find('canvas:last').css('background', '#aaf')
|
|
@$el.find('canvas:last').css('width', '100%')
|
|
window.stage = stage
|
|
|
|
|
|
testMovieClipStageUpdatePerformance: ->
|
|
# test how performant having a ton of movie clips is, removing the graphics part of it
|
|
stage = new createjs.Stage(@$el.find('#invisible-canvas')[0])
|
|
createjs.Ticker.addEventListener "tick", stage
|
|
console.log 'fps', createjs.Ticker.getFPS()
|
|
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
frames = []
|
|
|
|
createClass = (frame) ->
|
|
class Stub
|
|
constructor: ->
|
|
sprite = new createjs.Sprite(sheet, frame)
|
|
sprite.stop()
|
|
return sprite
|
|
|
|
for name, klass of waterfallLib
|
|
window.klass = klass
|
|
continue if name is 'waterfallRed_JSCC'
|
|
instance = new klass()
|
|
builder.addFrame(instance, instance.nominalBounds)
|
|
waterfallLib[name] = createClass(frames.length)
|
|
frames.push frames.length
|
|
|
|
sheet = builder.build()
|
|
|
|
i = 0
|
|
while i < 100
|
|
i += 1
|
|
waterfall = new waterfallLib.waterfallRed_JSCC()
|
|
window.waterfall = waterfall
|
|
waterfall.x = (i%10) * 10
|
|
waterfall.y = i * 2
|
|
stage.addChild(waterfall)
|
|
window.stage = stage
|
|
|
|
# (20FPS)
|
|
# nothing going on: 1%
|
|
# 20 waterfalls w/graphics: 25%
|
|
# 100 waterfalls w/graphics: 90%
|
|
# 100 waterfalls w/out graphics: 42%
|
|
|
|
# these waterfalls have 20 containers in them, so you'd be able to update 2000 containers
|
|
# at 20FPS using 42% CPU
|
|
|
|
testAnimateWaterfallContainersWithMovieClip: ->
|
|
invisibleStage = new createjs.Stage(@$el.find('#invisible-canvas')[0])
|
|
visibleStage = new createjs.Stage(@$el.find('#visible-canvas')[0])
|
|
createjs.Ticker.addEventListener "tick", invisibleStage
|
|
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
frames = []
|
|
|
|
createClass = (frame) ->
|
|
class Stub
|
|
constructor: ->
|
|
sprite = new createjs.Sprite(sheet, frame)
|
|
sprite.stop()
|
|
return sprite
|
|
|
|
for name, klass of waterfallLib
|
|
window.klass = klass
|
|
continue if name is 'waterfallRed_JSCC'
|
|
instance = new klass()
|
|
builder.addFrame(instance, instance.nominalBounds)
|
|
waterfallLib[name] = createClass(frames.length)
|
|
frames.push frames.length
|
|
|
|
sheet = builder.build()
|
|
|
|
waterfall = new waterfallLib.waterfallRed_JSCC()
|
|
invisibleStage.addChild(waterfall)
|
|
|
|
#visibleStage.children = waterfall.children # hoped this would work, but you need the ticker
|
|
listener = {
|
|
handleEvent: ->
|
|
visibleStage.children = waterfall.children
|
|
visibleStage.update()
|
|
}
|
|
createjs.Ticker.addEventListener "tick", listener
|
|
|
|
testAnimateManyWaterfallContainersWithMovieClip: ->
|
|
# Performance testing
|
|
invisibleStage = new createjs.Stage(@$el.find('#invisible-canvas')[0])
|
|
visibleStage = new createjs.SpriteStage(@$el.find('#visible-canvas')[0])
|
|
createjs.Ticker.addEventListener "tick", invisibleStage
|
|
listener = {
|
|
handleEvent: ->
|
|
for child, index in visibleStage.children
|
|
child.children = invisibleStage.children[index].children
|
|
visibleStage.update()
|
|
}
|
|
createjs.Ticker.addEventListener "tick", listener
|
|
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
frames = []
|
|
|
|
createClass = (frame) ->
|
|
class SuperContainer extends createjs.Container
|
|
constructor: ->
|
|
sprite = new createjs.Sprite(sheet, frame)
|
|
sprite.stop()
|
|
return sprite
|
|
|
|
for name, klass of waterfallLib
|
|
window.klass = klass
|
|
continue if name is 'waterfallRed_JSCC'
|
|
instance = new klass()
|
|
builder.addFrame(instance, instance.nominalBounds)
|
|
waterfallLib[name] = createClass(frames.length)
|
|
frames.push frames.length
|
|
|
|
sheet = builder.build()
|
|
|
|
i = 0
|
|
while i < 100
|
|
waterfall = new waterfallLib.waterfallRed_JSCC()
|
|
window.waterfall = waterfall
|
|
invisibleStage.addChild(waterfall)
|
|
c = new createjs.SpriteContainer(sheet)
|
|
c.x = (i%10) * 15
|
|
c.y = i * 3
|
|
visibleStage.addChild(c)
|
|
i += 1
|
|
|
|
window.visibleStage = visibleStage
|
|
# About 45% with SpriteStage, over 100% with regular stage
|
|
|
|
|
|
testAnimateSomeWaterfalls: ->
|
|
# Performance testing
|
|
invisibleStage = new createjs.Stage(@$el.find('#invisible-canvas')[0])
|
|
visibleStage = new createjs.SpriteStage(@$el.find('#visible-canvas')[0])
|
|
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
frames = []
|
|
|
|
createClass = (frame) ->
|
|
class SuperContainer extends createjs.Container
|
|
constructor: ->
|
|
sprite = new createjs.Sprite(sheet, frame)
|
|
sprite.stop()
|
|
return sprite
|
|
|
|
for name, klass of waterfallLib
|
|
continue if name is 'waterfallRed_JSCC'
|
|
instance = new klass()
|
|
builder.addFrame(instance, instance.nominalBounds)
|
|
waterfallLib[name] = createClass(frames.length)
|
|
frames.push frames.length
|
|
|
|
sheet = builder.build()
|
|
|
|
movieClips = []
|
|
spriteContainers = []
|
|
i = 0
|
|
|
|
while i < 100
|
|
# beStatic = false
|
|
beStatic = i % 2
|
|
# beStatic = true
|
|
|
|
waterfall = new waterfallLib.waterfallRed_JSCC()
|
|
if beStatic
|
|
waterfall.gotoAndStop(0)
|
|
else
|
|
invisibleStage.addChild(waterfall)
|
|
invisibleStage.addChild(waterfall)
|
|
c = new createjs.SpriteContainer(sheet)
|
|
c.x = (i%10) * 95
|
|
c.y = i * 6
|
|
c.scaleX = 0.3
|
|
c.scaleY = 0.3
|
|
visibleStage.addChild(c)
|
|
|
|
movieClips.push(waterfall)
|
|
spriteContainers.push(c)
|
|
i += 1
|
|
|
|
createjs.Ticker.addEventListener "tick", invisibleStage
|
|
listener = {
|
|
handleEvent: ->
|
|
for child, index in spriteContainers
|
|
child.children = movieClips[index].children
|
|
visibleStage.update()
|
|
}
|
|
createjs.Ticker.addEventListener "tick", listener
|
|
|
|
# All waterfalls animating: 50%
|
|
# Stopping all waterfalls movieclips: 18%
|
|
# Removing movieclips from the animation stage and just showing a static frame: 9%
|
|
# Setting movie clip mode to SINGLE_FRAME and leaving them on the stage provides no performance improvement
|
|
# Time to build 100 waterfalls: 223ms. Could experiment with pools, caching.
|
|
# We would need a bunch of movieclips, one for each animation and sprite.
|
|
|
|
|
|
testAnimateManyRasteredWaterfalls: ->
|
|
# rasterize waterfall movieclip. It's so performant, the movie clips they take so much!
|
|
stage = new createjs.SpriteStage(@$el.find('canvas')[0])
|
|
createjs.Ticker.addEventListener "tick", stage
|
|
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
waterfall = new waterfallLib.waterfallRed_JSCC()
|
|
builder.addMovieClip(waterfall)
|
|
sheet = builder.build()
|
|
i = 0
|
|
while i < 2000
|
|
sprite = new createjs.Sprite(sheet, 'start')
|
|
sprite.x = (i%20) * 45
|
|
sprite.y = i * 0.23
|
|
sprite.scaleX = 0.3
|
|
sprite.scaleY = 0.3
|
|
stage.addChild(sprite)
|
|
i += 1
|
|
|
|
|
|
testManualMovieClipUpdating: ->
|
|
# Take control of the MovieClip directly, rather than using a separate stage
|
|
visibleStage = new createjs.Stage(@$el.find('#visible-canvas')[0])
|
|
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
frames = []
|
|
|
|
createClass = (frame) ->
|
|
class SuperContainer extends createjs.Container
|
|
constructor: ->
|
|
sprite = new createjs.Sprite(sheet, frame)
|
|
sprite.stop()
|
|
return sprite
|
|
|
|
for name, klass of waterfallLib
|
|
window.klass = klass
|
|
continue if name is 'waterfallRed_JSCC'
|
|
instance = new klass()
|
|
builder.addFrame(instance, instance.nominalBounds)
|
|
waterfallLib[name] = createClass(frames.length)
|
|
frames.push frames.length
|
|
|
|
sheet = builder.build()
|
|
|
|
waterfall = new waterfallLib.waterfallRed_JSCC()
|
|
visibleStage.children = waterfall.children
|
|
|
|
i = 0
|
|
listener = {
|
|
handleEvent: ->
|
|
i += 0.4
|
|
waterfall.gotoAndPlay(i)
|
|
visibleStage.update()
|
|
}
|
|
createjs.Ticker.addEventListener "tick", listener
|
|
|
|
# It works, and we can set the movie clip to go to an arbitrary frame.
|
|
# So we can set up the frame rates ourselves. Will have to, because movie clips
|
|
# don't have frame rate systems like sprites do.
|
|
# Also looks like with this system we don't have to move the children over each time
|
|
|
|
|
|
testManyWaterfallsWithManualAnimation: ->
|
|
visibleStage = new createjs.SpriteStage(@$el.find('#visible-canvas')[0])
|
|
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
frames = []
|
|
|
|
createClass = (frame) ->
|
|
class Stub
|
|
constructor: ->
|
|
sprite = new createjs.Sprite(sheet, frame)
|
|
sprite.stop()
|
|
return sprite
|
|
|
|
for name, klass of waterfallLib
|
|
continue if name is 'waterfallRed_JSCC'
|
|
instance = new klass()
|
|
builder.addFrame(instance, instance.nominalBounds)
|
|
waterfallLib[name] = createClass(frames.length)
|
|
frames.push frames.length
|
|
|
|
sheet = builder.build()
|
|
movieClips = []
|
|
spriteContainers = []
|
|
i = 0
|
|
|
|
while i < 100
|
|
beStatic = false
|
|
# beStatic = i % 2
|
|
# beStatic = true
|
|
|
|
waterfall = new waterfallLib.waterfallRed_JSCC()
|
|
c = new createjs.SpriteContainer(sheet)
|
|
c.x = (i%10) * 95
|
|
c.y = i * 6
|
|
c.scaleX = 0.3
|
|
c.scaleY = 0.3
|
|
visibleStage.addChild(c)
|
|
|
|
movieClips.push(waterfall)
|
|
spriteContainers.push(c)
|
|
c.children = waterfall.children
|
|
i += 1
|
|
|
|
i = 0
|
|
listener = {
|
|
handleEvent: ->
|
|
# for child, index in spriteContainers
|
|
# child.children = movieClips[index].children
|
|
i += 0.4
|
|
for waterfall, index in movieClips
|
|
# continue if i > 1 and index % 2
|
|
waterfall.gotoAndPlay(i*index/12)
|
|
visibleStage.update()
|
|
}
|
|
createjs.Ticker.addEventListener "tick", listener
|
|
|
|
# well this is a bit better. 33% CPU for 100 waterfalls going at various speeds
|
|
# and 23% if half the waterfalls are being updated.
|
|
# still, you take a pretty big hit for manipulating the positions of containers with the movieclip
|
|
|
|
|
|
testLibrarianHorde: ->
|
|
visibleStage = new createjs.SpriteStage(@$el.find('#visible-canvas')[0])
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
frames = []
|
|
|
|
createClass = (frame) ->
|
|
class Stub
|
|
constructor: ->
|
|
sprite = new createjs.Sprite(sheet, frame)
|
|
sprite.stop()
|
|
return sprite
|
|
|
|
for name, klass of librarianLib
|
|
continue if name is 'Librarian_SideWalk_JSCC'
|
|
instance = new klass()
|
|
builder.addFrame(instance, instance.nominalBounds)
|
|
librarianLib[name] = createClass(frames.length)
|
|
frames.push frames.length
|
|
|
|
sheet = builder.build()
|
|
movieClips = []
|
|
spriteContainers = []
|
|
i = 0
|
|
|
|
class SpriteContainerChildClass extends createjs.SpriteContainer
|
|
constructor: (spriteSheet) ->
|
|
@initialize(spriteSheet)
|
|
|
|
while i < 100
|
|
beStatic = false
|
|
# beStatic = i % 2
|
|
# beStatic = true
|
|
|
|
librarian = new librarianLib.Librarian_SideWalk_JSCC()
|
|
c = new SpriteContainerChildClass(sheet)
|
|
c.x = (i%10) * 95
|
|
c.y = i * 6
|
|
c.scaleX = 1
|
|
c.scaleY = 1
|
|
visibleStage.addChild(c)
|
|
|
|
movieClips.push(librarian)
|
|
spriteContainers.push(c)
|
|
c.children = librarian.children
|
|
i += 1
|
|
|
|
i = 0
|
|
listener = {
|
|
handleEvent: ->
|
|
i += 0.4
|
|
for librarian, index in movieClips
|
|
librarian.gotoAndPlay(i*index/12)
|
|
visibleStage.update()
|
|
}
|
|
createjs.Ticker.addEventListener "tick", listener
|
|
|
|
# 20% CPU
|
|
|
|
testGiantCanvas: ->
|
|
builder = new createjs.SpriteSheetBuilder()
|
|
|
|
# mess with these
|
|
builder.maxWidth = 4096
|
|
builder.maxHeight = 4096
|
|
scale = 3.9
|
|
duplicates = 100
|
|
|
|
frames = []
|
|
|
|
createClass = (frame) ->
|
|
class Stub
|
|
constructor: ->
|
|
sprite = new createjs.Sprite(sheet, frame)
|
|
sprite.stop()
|
|
return sprite
|
|
|
|
for name, klass of librarianLib
|
|
continue if name is 'Librarian_SideWalk_JSCC'
|
|
instance = new klass()
|
|
builder.addFrame(instance, instance.nominalBounds, scale) for i in _.range(duplicates)
|
|
librarianLib[name] = createClass(frames.length)
|
|
frames.push frames.length
|
|
|
|
sheet = builder.build()
|
|
$('body').attr('class', '').empty().css('background', 'white').append($(sheet._images))
|
|
for image, index in sheet._images
|
|
console.log "Sheet ##{index}: #{$(image).attr('width')}x#{$(image).attr('height')}"
|
|
|
|
afterRender: ->
|
|
# @testMovieClipWithRasterizedSpriteChildren()
|
|
# @testMovieClipWithEmptyObjectChildren()
|
|
# @testWaterfallRasteredPerformance()
|
|
# @testMovieClipStageUpdatePerformance()
|
|
# @testAnimateWaterfallContainersWithMovieClip()
|
|
# @testAnimateManyWaterfallContainersWithMovieClip()
|
|
# @testAnimateSomeWaterfalls()
|
|
# @testAnimateManyRasteredWaterfalls()
|
|
# @testManualMovieClipUpdating()
|
|
# @testManyWaterfallsWithManualAnimation()
|
|
@testLibrarianHorde()
|
|
|
|
module.exports = ->
|
|
v = new WebGLDemoView()
|
|
v.render()
|
|
window.v = v
|
|
v |