mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 18:15:52 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
aa38ea4fe7
16 changed files with 1503 additions and 22 deletions
BIN
app/assets/images/common/particles/bullet.png
Normal file
BIN
app/assets/images/common/particles/bullet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 662 B |
BIN
app/assets/images/common/particles/bullet2.png
Normal file
BIN
app/assets/images/common/particles/bullet2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
app/assets/images/common/particles/cloud.png
Normal file
BIN
app/assets/images/common/particles/cloud.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 110 KiB |
BIN
app/assets/images/common/particles/cloud_small.png
Normal file
BIN
app/assets/images/common/particles/cloud_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
app/assets/images/common/particles/smoke.png
Normal file
BIN
app/assets/images/common/particles/smoke.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
app/assets/images/common/particles/star.png
Normal file
BIN
app/assets/images/common/particles/star.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
256
app/core/ParticleMan.coffee
Normal file
256
app/core/ParticleMan.coffee
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
CocoClass = require 'core/CocoClass'
|
||||||
|
utils = require 'core/utils'
|
||||||
|
|
||||||
|
module.exports = ParticleMan = class ParticleMan extends CocoClass
|
||||||
|
|
||||||
|
constructor: ->
|
||||||
|
return @unsupported = true unless Modernizr.webgl
|
||||||
|
@renderer = new THREE.WebGLRenderer alpha: true
|
||||||
|
$(@renderer.domElement).addClass 'particle-man'
|
||||||
|
@scene = new THREE.Scene()
|
||||||
|
@clock = new THREE.Clock()
|
||||||
|
@particleGroups = []
|
||||||
|
|
||||||
|
destroy: ->
|
||||||
|
@detach()
|
||||||
|
# TODO: figure out how to dispose everything
|
||||||
|
# scene.remove(mesh)
|
||||||
|
# mesh.dispose()
|
||||||
|
# geometry.dispose()
|
||||||
|
# material.dispose()
|
||||||
|
# texture.dispose()
|
||||||
|
super()
|
||||||
|
|
||||||
|
attach: (@$el) ->
|
||||||
|
return if @unsupported
|
||||||
|
width = @$el.innerWidth()
|
||||||
|
height = @$el.innerHeight()
|
||||||
|
@aspectRatio = width / height
|
||||||
|
@renderer.setSize(width, height)
|
||||||
|
@$el.append @renderer.domElement
|
||||||
|
@camera = camera = new THREE.OrthographicCamera(
|
||||||
|
100 * -0.5, # Left
|
||||||
|
100 * 0.5, # Right
|
||||||
|
100 * 0.5 * @aspectRatio, # Top
|
||||||
|
100 * -0.5 * @aspectRatio, # Bottom
|
||||||
|
0, # Near frustrum distance
|
||||||
|
1000 # Far frustrum distance
|
||||||
|
)
|
||||||
|
@camera.position.set(0, 0, 100)
|
||||||
|
@camera.up = new THREE.Vector3(0, 1, 0) # http://stackoverflow.com/questions/14271672/moving-the-camera-lookat-and-rotations-in-three-js
|
||||||
|
@camera.lookAt new THREE.Vector3(0, 0, 0)
|
||||||
|
unless @started
|
||||||
|
@started = true
|
||||||
|
@render()
|
||||||
|
|
||||||
|
detach: ->
|
||||||
|
return if @unsupported
|
||||||
|
@renderer.domElement.remove()
|
||||||
|
@started = false
|
||||||
|
|
||||||
|
render: =>
|
||||||
|
return if @unsupported
|
||||||
|
return if @destroyed
|
||||||
|
return unless @started
|
||||||
|
@renderer.render @scene, @camera
|
||||||
|
dt = @clock.getDelta()
|
||||||
|
for group in @particleGroups
|
||||||
|
group.tick dt
|
||||||
|
requestAnimationFrame @render
|
||||||
|
#@countFPS()
|
||||||
|
|
||||||
|
countFPS: ->
|
||||||
|
@framesRendered ?= 0
|
||||||
|
++@framesRendered
|
||||||
|
@lastFPS ?= new Date()
|
||||||
|
now = new Date()
|
||||||
|
if now - @lastFPS > 1000
|
||||||
|
console.log @framesRendered, 'fps with', @particleGroups.length, 'particle groups.'
|
||||||
|
@framesRendered = 0
|
||||||
|
@lastFPS = now
|
||||||
|
|
||||||
|
addEmitter: (x, y, kind="level-dungeon-premium") ->
|
||||||
|
return if @unsupported
|
||||||
|
console.log 'adding kind', kind
|
||||||
|
options = $.extend true, {}, particleKinds[kind]
|
||||||
|
options.group.texture = THREE.ImageUtils.loadTexture "/images/common/particles/#{options.group.texture}.png"
|
||||||
|
scale = 100
|
||||||
|
aspectRatio = @$el
|
||||||
|
group = new SPE.Group options.group
|
||||||
|
group.mesh.position.x = scale * (-0.5 + x)
|
||||||
|
group.mesh.position.y = scale * (-0.5 + y) * @aspectRatio
|
||||||
|
emitter = new SPE.Emitter options.emitter
|
||||||
|
group.addEmitter emitter
|
||||||
|
@particleGroups.push group
|
||||||
|
@scene.add group.mesh
|
||||||
|
group
|
||||||
|
|
||||||
|
removeEmitter: (group) ->
|
||||||
|
return if @unsupported
|
||||||
|
@scene.remove group.mesh
|
||||||
|
@particleGroups = _.without @particleGroups, group
|
||||||
|
|
||||||
|
removeEmitters: ->
|
||||||
|
return if @unsupported
|
||||||
|
@removeEmitter group for group in @particleGroups.slice()
|
||||||
|
|
||||||
|
#addTestCube: ->
|
||||||
|
#geometry = new THREE.BoxGeometry 5, 5, 5
|
||||||
|
#material = new THREE.MeshLambertMaterial color: 0xFF0000
|
||||||
|
#mesh = new THREE.Mesh geometry, material
|
||||||
|
#@scene.add mesh
|
||||||
|
#light = new THREE.PointLight 0xFFFF00
|
||||||
|
#light.position.set 10, 0, 20
|
||||||
|
#@scene.add light
|
||||||
|
|
||||||
|
|
||||||
|
hsl = (hue, saturation, lightness) ->
|
||||||
|
new THREE.Color utils.hslToHex([hue, saturation, lightness])
|
||||||
|
vec = (x, y, z) ->
|
||||||
|
new THREE.Vector3 x, y, z
|
||||||
|
|
||||||
|
defaults =
|
||||||
|
group:
|
||||||
|
texture: 'star'
|
||||||
|
maxAge: 4
|
||||||
|
hasPerspective: 1
|
||||||
|
colorize: 1
|
||||||
|
transparent: 1
|
||||||
|
alphaTest: 0.5
|
||||||
|
depthWrite: false
|
||||||
|
depthTest: true
|
||||||
|
blending: THREE.NormalBlending
|
||||||
|
emitter:
|
||||||
|
type: "cube"
|
||||||
|
particleCount: 60
|
||||||
|
position: vec 0, 0, 0
|
||||||
|
positionSpread: vec 1, 0, 1
|
||||||
|
acceleration: vec 0, -1, 0
|
||||||
|
accelerationSpread: vec 0, 0, 0
|
||||||
|
velocity: vec 0, 4, 0
|
||||||
|
velocitySpread: vec 2, 2, 2
|
||||||
|
sizeStart: 6
|
||||||
|
sizeStartSpread: 0
|
||||||
|
sizeMiddle: 4
|
||||||
|
sizeMiddleSpread: 0
|
||||||
|
sizeEnd: 2
|
||||||
|
sizeEndSpread: 0
|
||||||
|
angleStart: 0
|
||||||
|
angleStartSpread: 0
|
||||||
|
angleMiddle: 0
|
||||||
|
angleMiddleSpread: 0
|
||||||
|
angleEnd: 0
|
||||||
|
angleEndSpread: 0
|
||||||
|
angleAlignVelocity: false
|
||||||
|
colorStart: hsl 0.55, 0.75, 0.75
|
||||||
|
colorStartSpread: vec 0.3, 0.3, 0.3
|
||||||
|
colorMiddle: hsl 0.55, 0.6, 0.5
|
||||||
|
colorMiddleSpread: vec 0.2, 0.2, 0.2
|
||||||
|
colorEnd: hsl 0.55, 0.5, 0.25
|
||||||
|
colorEndSpread: vec 0.1, 0.1, 0.1
|
||||||
|
opacityStart: 1
|
||||||
|
opacityStartSpread: 0
|
||||||
|
opacityMiddle: 0.75
|
||||||
|
opacityMiddleSpread: 0
|
||||||
|
opacityEnd: 0.25
|
||||||
|
opacityEndSpread: 0
|
||||||
|
duration: null
|
||||||
|
alive: 1
|
||||||
|
isStatic: 0
|
||||||
|
|
||||||
|
ext = (d, options) ->
|
||||||
|
$.extend true, {}, d, options ? {}
|
||||||
|
|
||||||
|
particleKinds =
|
||||||
|
'level-dungeon-premium': ext defaults
|
||||||
|
'level-forest-premium': ext defaults,
|
||||||
|
emitter:
|
||||||
|
colorStart: hsl 0.56, 0.97, 0.5
|
||||||
|
colorMiddle: hsl 0.56, 0.57, 0.5
|
||||||
|
colorEnd: hsl 0.56, 0.17, 0.5
|
||||||
|
'level-desert-premium': ext defaults,
|
||||||
|
emitter:
|
||||||
|
colorStart: hsl 0.56, 0.97, 0.5
|
||||||
|
colorMiddle: hsl 0.56, 0.57, 0.5
|
||||||
|
colorEnd: hsl 0.56, 0.17, 0.5
|
||||||
|
'level-mountain-premium': ext defaults,
|
||||||
|
emitter:
|
||||||
|
colorStart: hsl 0.56, 0.97, 0.5
|
||||||
|
colorMiddle: hsl 0.56, 0.57, 0.5
|
||||||
|
colorEnd: hsl 0.56, 0.17, 0.5
|
||||||
|
|
||||||
|
particleKinds['level-dungeon-gate'] = ext particleKinds['level-dungeon-premium'],
|
||||||
|
emitter:
|
||||||
|
particleCount: 120
|
||||||
|
velocity: vec 0, 6, 0
|
||||||
|
colorStart: hsl 0.5, 0.75, 0.9
|
||||||
|
colorMiddle: hsl 0.5, 0.75, 0.7
|
||||||
|
colorEnd: hsl 0.5, 0.75, 0.3
|
||||||
|
colorStartSpread: vec 1, 1, 1
|
||||||
|
colorMiddleSpread: vec 1.5, 1.5, 1.5
|
||||||
|
colorEndSpread: vec 2.5, 2.5, 2.5
|
||||||
|
|
||||||
|
particleKinds['level-dungeon-hero-ladder'] = ext particleKinds['level-dungeon-premium'],
|
||||||
|
emitter:
|
||||||
|
particleCount: 90
|
||||||
|
velocity: vec 0, 4, 0
|
||||||
|
colorStart: hsl 0, 0.75, 0.7
|
||||||
|
colorMiddle: hsl 0, 0.75, 0.5
|
||||||
|
colorEnd: hsl 0, 0.75, 0.3
|
||||||
|
|
||||||
|
particleKinds['level-forest-gate'] = ext particleKinds['level-forest-premium'],
|
||||||
|
emitter:
|
||||||
|
particleCount: 120
|
||||||
|
velocity: vec 0, 8, 0
|
||||||
|
colorStart: hsl 0.56, 0.97, 0.3
|
||||||
|
colorMiddle: hsl 0.56, 0.57, 0.3
|
||||||
|
colorEnd: hsl 0.56, 0.17, 0.3
|
||||||
|
colorStartSpread: vec 1, 1, 1
|
||||||
|
colorMiddleSpread: vec 1.5, 1.5, 1.5
|
||||||
|
colorEndSpread: vec 2.5, 2.5, 2.5
|
||||||
|
|
||||||
|
particleKinds['level-forest-hero-ladder'] = ext particleKinds['level-forest-premium'],
|
||||||
|
emitter:
|
||||||
|
particleCount: 90
|
||||||
|
velocity: vec 0, 4, 0
|
||||||
|
colorStart: hsl 0, 0.95, 0.3
|
||||||
|
colorMiddle: hsl 0, 1, 0.5
|
||||||
|
colorEnd: hsl 0, 0.75, 0.1
|
||||||
|
|
||||||
|
particleKinds['level-desert-gate'] = ext particleKinds['level-desert-premium'],
|
||||||
|
emitter:
|
||||||
|
particleCount: 120
|
||||||
|
velocity: vec 0, 8, 0
|
||||||
|
colorStart: hsl 0.56, 0.97, 0.3
|
||||||
|
colorMiddle: hsl 0.56, 0.57, 0.3
|
||||||
|
colorEnd: hsl 0.56, 0.17, 0.3
|
||||||
|
colorStartSpread: vec 1, 1, 1
|
||||||
|
colorMiddleSpread: vec 1.5, 1.5, 1.5
|
||||||
|
colorEndSpread: vec 2.5, 2.5, 2.5
|
||||||
|
|
||||||
|
particleKinds['level-desert-hero-ladder'] = ext particleKinds['level-desert-premium'],
|
||||||
|
emitter:
|
||||||
|
particleCount: 90
|
||||||
|
velocity: vec 0, 4, 0
|
||||||
|
colorStart: hsl 0, 0.95, 0.3
|
||||||
|
colorMiddle: hsl 0, 1, 0.5
|
||||||
|
colorEnd: hsl 0, 0.75, 0.1
|
||||||
|
|
||||||
|
particleKinds['level-dungeon-gate'] = ext particleKinds['level-dungeon-premium'],
|
||||||
|
emitter:
|
||||||
|
particleCount: 120
|
||||||
|
velocity: vec 0, 8, 0
|
||||||
|
colorStart: hsl 0.56, 0.97, 0.3
|
||||||
|
colorMiddle: hsl 0.56, 0.57, 0.3
|
||||||
|
colorEnd: hsl 0.56, 0.17, 0.3
|
||||||
|
colorStartSpread: vec 1, 1, 1
|
||||||
|
colorMiddleSpread: vec 1.5, 1.5, 1.5
|
||||||
|
colorEndSpread: vec 2.5, 2.5, 2.5
|
||||||
|
|
||||||
|
particleKinds['level-dungeon-hero-ladder'] = ext particleKinds['level-dungeon-premium'],
|
||||||
|
emitter:
|
||||||
|
particleCount: 90
|
||||||
|
velocity: vec 0, 4, 0
|
||||||
|
colorStart: hsl 0, 0.95, 0.3
|
||||||
|
colorMiddle: hsl 0, 1, 0.5
|
||||||
|
colorEnd: hsl 0, 0.75, 0.1
|
|
@ -123,6 +123,16 @@ module.exports = class User extends CocoModel
|
||||||
application.tracker.identify gemPromptGroup: @gemPromptGroup unless me.isAdmin()
|
application.tracker.identify gemPromptGroup: @gemPromptGroup unless me.isAdmin()
|
||||||
@gemPromptGroup
|
@gemPromptGroup
|
||||||
|
|
||||||
|
getForeshadowsLevels: ->
|
||||||
|
return @foreshadowsLevels if @foreshadowsLevels?
|
||||||
|
group = me.get('testGroupNumber') % 16
|
||||||
|
@foreshadowsLevels = switch group
|
||||||
|
when 0, 1, 2, 3, 4, 5, 6, 7 then true
|
||||||
|
when 8, 9, 10, 11, 12, 13, 14, 15 then false
|
||||||
|
@foreshadowsLevels = true if me.isAdmin()
|
||||||
|
application.tracker.identify foreshadowsLevels: @foreshadowsLevels unless me.isAdmin()
|
||||||
|
@foreshadowsLevels
|
||||||
|
|
||||||
getVideoTutorialStylesIndex: (numVideos=0)->
|
getVideoTutorialStylesIndex: (numVideos=0)->
|
||||||
# A/B Testing video tutorial styles
|
# A/B Testing video tutorial styles
|
||||||
# Not a constant number of videos available (e.g. could be 0, 1, 3, or 4 currently)
|
# Not a constant number of videos available (e.g. could be 0, 1, 3, or 4 currently)
|
||||||
|
|
|
@ -383,3 +383,10 @@ body > iframe[src^="https://apis.google.com"]
|
||||||
@include scale(1.25)
|
@include scale(1.25)
|
||||||
width: auto
|
width: auto
|
||||||
margin: 8px 15px 8px 15px
|
margin: 8px 15px 8px 15px
|
||||||
|
|
||||||
|
.particle-man
|
||||||
|
position: absolute
|
||||||
|
z-index: 100
|
||||||
|
top: 0
|
||||||
|
left: 0
|
||||||
|
pointer-events: none
|
||||||
|
|
|
@ -66,7 +66,7 @@ $gameControlMargin: 30px
|
||||||
|
|
||||||
.level, .level-shadow
|
.level, .level-shadow
|
||||||
position: absolute
|
position: absolute
|
||||||
border-radius: 100%
|
border-radius: 50%
|
||||||
-webkit-transform: scaleY(0.75)
|
-webkit-transform: scaleY(0.75)
|
||||||
transform: scaleY(0.75)
|
transform: scaleY(0.75)
|
||||||
|
|
||||||
|
@ -130,16 +130,24 @@ $gameControlMargin: 30px
|
||||||
|
|
||||||
&.started .glyphicon-star
|
&.started .glyphicon-star
|
||||||
left: 0.5px
|
left: 0.5px
|
||||||
|
|
||||||
img.hero-portrait
|
img.hero-portrait
|
||||||
width: 120%
|
width: 120%
|
||||||
position: absolute
|
height: auto
|
||||||
bottom: 75%
|
bottom: 75%
|
||||||
left: 75%
|
left: 75%
|
||||||
border: 1px solid black
|
margin-left: 0
|
||||||
border-radius: 100%
|
margin-bottom: 0
|
||||||
background: white
|
|
||||||
|
|
||||||
|
img.hero-portrait
|
||||||
|
position: absolute
|
||||||
|
border: 1px solid black
|
||||||
|
border-radius: 50%
|
||||||
|
background: white
|
||||||
|
width: $levelDotWidth * 1.5
|
||||||
|
height: $levelDotHeight * 1.5
|
||||||
|
margin-left: -0.5 * $levelDotWidth * 1.5
|
||||||
|
margin-bottom: -$levelDotHeight / 3 * 1.5
|
||||||
|
|
||||||
.level-shadow
|
.level-shadow
|
||||||
z-index: 1
|
z-index: 1
|
||||||
|
@ -425,6 +433,9 @@ $gameControlMargin: 30px
|
||||||
vertical-align: bottom
|
vertical-align: bottom
|
||||||
margin: -20px 0 -6px 5px
|
margin: -20px 0 -6px 5px
|
||||||
|
|
||||||
|
.particle-man
|
||||||
|
z-index: 2
|
||||||
|
|
||||||
|
|
||||||
body:not(.ipad) #campaign-view
|
body:not(.ipad) #campaign-view
|
||||||
.level-info-container
|
.level-info-container
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
each level in levels
|
each level in levels
|
||||||
if !level.hidden
|
if !level.hidden
|
||||||
div(style="left: #{level.position.x}%; bottom: #{level.position.y}%; background-color: #{level.color}", class="level" + (level.next ? " next" : "") + (level.disabled ? " disabled" : "") + (level.locked ? " locked" : "") + " " + levelStatusMap[level.slug] || "", data-level-slug=level.slug, data-level-original=level.original, title=i18n(level, 'name') + (level.disabled ? ' (Coming Soon to Adventurers)' : ''))
|
div(style="left: #{level.position.x}%; bottom: #{level.position.y}%; background-color: #{level.color}", class="level" + (level.next ? " next" : "") + (level.disabled ? " disabled" : "") + (level.locked ? " locked" : "") + " " + levelStatusMap[level.slug] || "", data-level-slug=level.slug, data-level-original=level.original, title=i18n(level, 'name') + (level.disabled ? ' (Coming Soon to Adventurers)' : ''))
|
||||||
if level.unlocksHero && !level.unlockedHero
|
if level.unlocksHero && (!level.purchasedHero || editorMode)
|
||||||
img.hero-portrait(src=level.unlocksHero.img)
|
img.hero-portrait(src="/file/db/thang.type/#{level.unlocksHero}/portrait.png")
|
||||||
a(href=level.type == 'hero' ? '#' : level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.slug}", disabled=level.disabled, data-level-slug=level.slug, data-level-path=level.levelPath || 'level', data-level-name=level.name)
|
a(href=level.type == 'hero' ? '#' : level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.slug}", disabled=level.disabled, data-level-slug=level.slug, data-level-path=level.levelPath || 'level', data-level-name=level.name)
|
||||||
if level.requiresSubscription
|
if level.requiresSubscription
|
||||||
img.star(src="/images/pages/play/star.png")
|
img.star(src="/images/pages/play/star.png")
|
||||||
|
@ -40,6 +40,8 @@
|
||||||
|
|
||||||
if isIPadApp && !level.disabled && !level.locked
|
if isIPadApp && !level.disabled && !level.locked
|
||||||
button.btn.btn-success.btn-lg.start-level(data-i18n="common.play") Play
|
button.btn.btn-success.btn-lg.start-level(data-i18n="common.play") Play
|
||||||
|
else if level.unlocksHero && !level.purchasedHero
|
||||||
|
img.hero-portrait(src="/file/db/thang.type/#{level.unlocksHero}/portrait.png", style="left: #{level.position.x}%; bottom: #{level.position.y}%;")
|
||||||
|
|
||||||
for adjacentCampaign in adjacentCampaigns
|
for adjacentCampaign in adjacentCampaigns
|
||||||
a(href=(editorMode ? "/editor/campaign/" : "/play/") + adjacentCampaign.slug)
|
a(href=(editorMode ? "/editor/campaign/" : "/play/") + adjacentCampaign.slug)
|
||||||
|
|
|
@ -13,6 +13,8 @@ AuthModal = require 'views/core/AuthModal'
|
||||||
SubscribeModal = require 'views/core/SubscribeModal'
|
SubscribeModal = require 'views/core/SubscribeModal'
|
||||||
Level = require 'models/Level'
|
Level = require 'models/Level'
|
||||||
utils = require 'core/utils'
|
utils = require 'core/utils'
|
||||||
|
require 'vendor/three'
|
||||||
|
ParticleMan = require 'core/ParticleMan'
|
||||||
|
|
||||||
trackedHourOfCode = false
|
trackedHourOfCode = false
|
||||||
|
|
||||||
|
@ -144,8 +146,10 @@ module.exports = class CampaignView extends RootView
|
||||||
level.color = 'rgb(255, 80, 60)'
|
level.color = 'rgb(255, 80, 60)'
|
||||||
if level.requiresSubscription
|
if level.requiresSubscription
|
||||||
level.color = 'rgb(80, 130, 200)'
|
level.color = 'rgb(80, 130, 200)'
|
||||||
|
if unlocksHero = _.find(level.rewards, 'hero')?.hero
|
||||||
|
level.unlocksHero = unlocksHero
|
||||||
if level.unlocksHero
|
if level.unlocksHero
|
||||||
level.unlockedHero = level.unlocksHero.originalID in (me.get('earned')?.heroes or [])
|
level.purchasedHero = level.unlocksHero in (me.get('purchased')?.heroes or [])
|
||||||
level.hidden = level.locked
|
level.hidden = level.locked
|
||||||
unless level.disabled
|
unless level.disabled
|
||||||
++context.levelsTotal
|
++context.levelsTotal
|
||||||
|
@ -202,6 +206,7 @@ module.exports = class CampaignView extends RootView
|
||||||
if nextLevel = _.find(@campaign.renderedLevels, original: nextLevelOriginal)
|
if nextLevel = _.find(@campaign.renderedLevels, original: nextLevelOriginal)
|
||||||
@createLine level.position, nextLevel.position
|
@createLine level.position, nextLevel.position
|
||||||
@applyCampaignStyles()
|
@applyCampaignStyles()
|
||||||
|
@testParticles()
|
||||||
|
|
||||||
afterInsert: ->
|
afterInsert: ->
|
||||||
super()
|
super()
|
||||||
|
@ -253,6 +258,19 @@ module.exports = class CampaignView extends RootView
|
||||||
@$el.find(".#{pos}-gradient").css 'background-image', "linear-gradient(to #{pos}, #{backgroundColorTransparent} 0%, #{backgroundColor} 100%)"
|
@$el.find(".#{pos}-gradient").css 'background-image', "linear-gradient(to #{pos}, #{backgroundColorTransparent} 0%, #{backgroundColor} 100%)"
|
||||||
@playAmbientSound()
|
@playAmbientSound()
|
||||||
|
|
||||||
|
testParticles: ->
|
||||||
|
return unless @campaign.loaded and me.getForeshadowsLevels()
|
||||||
|
@particleMan ?= new ParticleMan()
|
||||||
|
@particleMan.removeEmitters()
|
||||||
|
@particleMan.attach @$el.find('.map')
|
||||||
|
for level in @campaign.renderedLevels ? {} when level.hidden
|
||||||
|
particleKey = ['level', @terrain]
|
||||||
|
particleKey.push level.type if level.type and level.type isnt 'hero'
|
||||||
|
particleKey.push 'premium' if level.requiresSubscription
|
||||||
|
particleKey.push 'gate' if level.slug in ['kithgard-gates', 'siege-of-stonehold', 'clash-of-clones']
|
||||||
|
continue if particleKey.length is 2 # Don't show basic levels
|
||||||
|
@particleMan.addEmitter level.position.x / 100, level.position.y / 100, particleKey.join('-')
|
||||||
|
|
||||||
onSessionsLoaded: (e) ->
|
onSessionsLoaded: (e) ->
|
||||||
return if @editorMode
|
return if @editorMode
|
||||||
for session in @sessions.models
|
for session in @sessions.models
|
||||||
|
@ -363,6 +381,7 @@ module.exports = class CampaignView extends RootView
|
||||||
resultingMarginX = (pageWidth - resultingWidth) / 2
|
resultingMarginX = (pageWidth - resultingWidth) / 2
|
||||||
resultingMarginY = (pageHeight - resultingHeight) / 2
|
resultingMarginY = (pageHeight - resultingHeight) / 2
|
||||||
@$el.find('.map').css(width: resultingWidth, height: resultingHeight, 'margin-left': resultingMarginX, 'margin-top': resultingMarginY)
|
@$el.find('.map').css(width: resultingWidth, height: resultingHeight, 'margin-left': resultingMarginX, 'margin-top': resultingMarginY)
|
||||||
|
@testParticles() if @particleMan
|
||||||
|
|
||||||
playAmbientSound: ->
|
playAmbientSound: ->
|
||||||
return if @ambientSound
|
return if @ambientSound
|
||||||
|
|
|
@ -94,18 +94,13 @@ module.exports = class LevelGuideView extends CocoView
|
||||||
window.tracker?.trackEvent 'Finish help video', level: @levelID, ls: @sessionID, style: @helpVideos[@helpVideosIndex].style
|
window.tracker?.trackEvent 'Finish help video', level: @levelID, ls: @sessionID, style: @helpVideos[@helpVideosIndex].style
|
||||||
@trackedHelpVideoFinish = true
|
@trackedHelpVideoFinish = true
|
||||||
|
|
||||||
# we wan't to always use the same scheme (HTTP/HTTPS) as the page was loaded with, but don't want to require Artisans to have to remember
|
|
||||||
# not to include a scheme in help video url
|
|
||||||
fixupUri = (uri) ->
|
|
||||||
n = uri.indexOf('/')
|
|
||||||
if n < 1
|
|
||||||
return uri
|
|
||||||
return uri.slice(n)
|
|
||||||
|
|
||||||
setupVideoPlayer: () ->
|
setupVideoPlayer: () ->
|
||||||
return unless @helpVideos.length > 0
|
return unless @helpVideos?.length > 0
|
||||||
helpVideoURL = fixupUri(@helpVideos[@helpVideosIndex].url)
|
return unless url = @helpVideos[@helpVideosIndex]?.url
|
||||||
@setupVimeoVideoPlayer helpVideoURL
|
# Always use HTTPS
|
||||||
|
# TODO: Not specifying the protocol should work based on Vimeo docs, but breaks postMessage/eventing in practice.
|
||||||
|
url = "https:" + url.substr url.indexOf '/'
|
||||||
|
@setupVimeoVideoPlayer url
|
||||||
|
|
||||||
setupVimeoVideoPlayer: (helpVideoURL) ->
|
setupVimeoVideoPlayer: (helpVideoURL) ->
|
||||||
# Setup Vimeo player
|
# Setup Vimeo player
|
||||||
|
|
|
@ -46,7 +46,8 @@
|
||||||
"zatanna": "https://github.com/differentmatt/zatanna.git#master",
|
"zatanna": "https://github.com/differentmatt/zatanna.git#master",
|
||||||
"modernizr": "~2.8.3",
|
"modernizr": "~2.8.3",
|
||||||
"backfire": "~0.3.0",
|
"backfire": "~0.3.0",
|
||||||
"fastclick": "~1.0.3"
|
"fastclick": "~1.0.3",
|
||||||
|
"three.js": "*"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"backbone": {
|
"backbone": {
|
||||||
|
|
|
@ -81,7 +81,7 @@ exports.config =
|
||||||
#- vendor.js, all the vendor libraries
|
#- vendor.js, all the vendor libraries
|
||||||
'javascripts/vendor.js': [
|
'javascripts/vendor.js': [
|
||||||
regJoin('^vendor/scripts/(?!(Box2d|coffeescript|difflib|diffview|jasmine))')
|
regJoin('^vendor/scripts/(?!(Box2d|coffeescript|difflib|diffview|jasmine))')
|
||||||
regJoin('^bower_components/(?!(aether|d3|treema))')
|
regJoin('^bower_components/(?!(aether|d3|treema|three.js))')
|
||||||
'bower_components/treema/treema-utils.js'
|
'bower_components/treema/treema-utils.js'
|
||||||
]
|
]
|
||||||
'javascripts/whole-vendor.js': if TRAVIS then [
|
'javascripts/whole-vendor.js': if TRAVIS then [
|
||||||
|
@ -112,6 +112,7 @@ exports.config =
|
||||||
'javascripts/app/vendor/treema.js': 'bower_components/treema/treema.js'
|
'javascripts/app/vendor/treema.js': 'bower_components/treema/treema.js'
|
||||||
'javascripts/app/vendor/jasmine-bundle.js': regJoin('^vendor/scripts/jasmine')
|
'javascripts/app/vendor/jasmine-bundle.js': regJoin('^vendor/scripts/jasmine')
|
||||||
'javascripts/app/vendor/jasmine-mock-ajax.js': 'vendor/scripts/jasmine-mock-ajax.js'
|
'javascripts/app/vendor/jasmine-mock-ajax.js': 'vendor/scripts/jasmine-mock-ajax.js'
|
||||||
|
'javascripts/app/vendor/three.js': 'bower_components/three.js/three.min.js'
|
||||||
|
|
||||||
#- test, demo libraries
|
#- test, demo libraries
|
||||||
'javascripts/app/tests.js': regJoin('^test/app/')
|
'javascripts/app/tests.js': regJoin('^test/app/')
|
||||||
|
|
1179
vendor/scripts/ShaderParticles.js
vendored
Normal file
1179
vendor/scripts/ShaderParticles.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue