mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 01:55:38 -05:00
commit
b7ddbe74a9
15 changed files with 60 additions and 154 deletions
|
@ -121,7 +121,7 @@ module.exports = class LevelLoader extends CocoClass
|
|||
url = "/db/level/#{obj.original}/version/#{obj.majorVersion}"
|
||||
@maybeLoadURL url, Level, 'level'
|
||||
|
||||
unless @headless
|
||||
unless @headless and not @editorMode
|
||||
wizard = ThangType.loadUniversalWizard()
|
||||
@supermodel.loadModel wizard, 'thang'
|
||||
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
CocoClass = require 'lib/CocoClass'
|
||||
|
||||
module.exports = class LoadingScreen extends CocoClass
|
||||
progress: 0
|
||||
|
||||
constructor: (canvas) ->
|
||||
super()
|
||||
@width = canvas.width
|
||||
@height = canvas.height
|
||||
@stage = new createjs.Stage(canvas)
|
||||
|
||||
subscriptions:
|
||||
'level-loader:progress-changed': 'onLevelLoaderProgressChanged'
|
||||
|
||||
show: ->
|
||||
@stage.removeChild(@screen) if @screen
|
||||
@screen = @makeScreen()
|
||||
@stage.addChild(@screen)
|
||||
@updateProgressBar()
|
||||
|
||||
hide: ->
|
||||
@stage.removeChild(@screen) if @screen
|
||||
@screen = null
|
||||
|
||||
makeScreen: ->
|
||||
c = new createjs.Container()
|
||||
c.addChild(@makeLoadBackground())
|
||||
c.addChild(@makeLoadText())
|
||||
c.addChild(@makeProgressBar())
|
||||
@makeLoadLogo(c)
|
||||
c
|
||||
|
||||
makeLoadBackground: ->
|
||||
g = new createjs.Graphics()
|
||||
g.beginFill(createjs.Graphics.getRGB(30,30,60))
|
||||
g.drawRoundRect(0, 0, @width, @height, 0.0)
|
||||
s = new createjs.Shape(g)
|
||||
s.y = 0
|
||||
s.x = 0
|
||||
s
|
||||
|
||||
makeLoadLogo: (container) ->
|
||||
logoImage = new Image()
|
||||
$(logoImage).load =>
|
||||
@logo = new createjs.Bitmap logoImage
|
||||
@logo.x = @width / 2 - logoImage.width / 2
|
||||
@logo.y = 40
|
||||
container.addChild @logo
|
||||
logoImage.src = "/images/loading_image.png"
|
||||
|
||||
makeLoadText: ->
|
||||
size = @height / 10
|
||||
text = new createjs.Text("LOADING", "#{size}px Monospace", "#ff7700")
|
||||
text.regX = text.getMeasuredWidth() / 2
|
||||
text.regY = text.getMeasuredHeight() / 2
|
||||
text.x = @width / 2
|
||||
text.y = @height / 2
|
||||
@text = text
|
||||
return text
|
||||
|
||||
makeProgressBar: ->
|
||||
BAR_PIXEL_HEIGHT = 20
|
||||
BAR_PCT_WIDTH = .75
|
||||
pixelWidth = parseInt(@width * BAR_PCT_WIDTH)
|
||||
pixelMargin = (@width - (@width * BAR_PCT_WIDTH)) / 2
|
||||
barY = 2 * (@height / 3)
|
||||
|
||||
c = new createjs.Container()
|
||||
c.x = pixelMargin
|
||||
c.y = barY
|
||||
|
||||
g = new createjs.Graphics()
|
||||
g.beginFill(createjs.Graphics.getRGB(255,0,0))
|
||||
g.drawRoundRect(0,0,pixelWidth, BAR_PIXEL_HEIGHT, 5)
|
||||
@progressBar = new createjs.Shape(g)
|
||||
c.addChild(@progressBar)
|
||||
|
||||
g = new createjs.Graphics()
|
||||
g.setStrokeStyle(2)
|
||||
g.beginStroke(createjs.Graphics.getRGB(230,230,230))
|
||||
g.drawRoundRect(0,0,pixelWidth, BAR_PIXEL_HEIGHT, 5)
|
||||
c.addChild(new createjs.Shape(g))
|
||||
c
|
||||
|
||||
onLevelLoaderProgressChanged: (e) ->
|
||||
@progress = e.progress
|
||||
@updateProgressBar()
|
||||
|
||||
updateProgressBar: ->
|
||||
newProg = parseInt((@progress or 0) * 100)
|
||||
newProg = ' '+newProg while newProg.length < 4
|
||||
@lastProg = newProg
|
||||
@text.text = "BUILDING" if @progress is 1
|
||||
@progressBar.scaleX = @progress
|
||||
@stage.update()
|
||||
|
||||
showReady: ->
|
||||
@text.text = 'READY'
|
||||
@text.regX = @text.getMeasuredWidth() / 2
|
||||
@stage.update()
|
||||
|
||||
destroy: ->
|
||||
@stage.canvas = null
|
||||
super()
|
|
@ -96,11 +96,8 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
unless @indieSprites
|
||||
@indieSprites = []
|
||||
@indieSprites = (@createIndieSprite indieSprite for indieSprite in indieSprites) if indieSprites
|
||||
unless @selfWizardSprite
|
||||
if withWizards and not @selfWizardSprite
|
||||
@selfWizardSprite = @createWizardSprite thangID: "My Wizard", isSelf: true, sprites: @sprites
|
||||
unless withWizards
|
||||
@selfWizardSprite.displayObject.visible = false
|
||||
@selfWizardSprite.labels.name.setText null
|
||||
|
||||
createIndieSprite: (indieSprite) ->
|
||||
unless thangType = @thangTypeFor indieSprite.thangType
|
||||
|
|
|
@ -29,8 +29,8 @@ module.exports = class ThangState
|
|||
value = thang[prop]
|
||||
if type is 'Vector'
|
||||
@props.push value?.copy() # could try storing [x, y, z] or {x, y, z} here instead if this is expensive
|
||||
else if type is 'object'
|
||||
@props.push = clone(value, true)
|
||||
else if type is 'object' or type is 'array'
|
||||
@props.push clone(value, true)
|
||||
else
|
||||
@props.push value
|
||||
|
||||
|
@ -98,7 +98,7 @@ module.exports = class ThangState
|
|||
storage = @trackedPropertyValues[propIndex]
|
||||
value = @getStoredProp propIndex, type, storage
|
||||
if prop is "pos"
|
||||
if @thang.pos.distanceSquared(value) > 900
|
||||
if @thang.teleport and @thang.pos.distanceSquared(value) > 900
|
||||
# Don't interpolate; it was probably a teleport. https://github.com/codecombat/codecombat/issues/738
|
||||
@thang.pos = value
|
||||
else
|
||||
|
@ -144,6 +144,8 @@ module.exports = class ThangState
|
|||
# We make sure the array keys won't collide with any string keys by using some unprintable characters.
|
||||
stringPieces = ['\x1D'] # Group Separator
|
||||
for element in value
|
||||
if element and element.isThang
|
||||
element = element.id
|
||||
stringPieces.push element, '\x1E' # Record Separator(s)
|
||||
value = stringPieces.join('')
|
||||
specialKey = specialValuesToKeys[value]
|
||||
|
|
|
@ -42,12 +42,15 @@ module.exports.clone = clone = (obj, skipThangs=false) ->
|
|||
if skipThangs and obj.isThang
|
||||
return obj
|
||||
|
||||
if _.isArray obj
|
||||
return obj.slice()
|
||||
|
||||
if ArrayBufferView and obj instanceof ArrayBufferView
|
||||
newInstance = new obj.constructor obj
|
||||
else
|
||||
newInstance = new obj.constructor()
|
||||
for key of obj
|
||||
newInstance[key] = clone obj[key]
|
||||
return new obj.constructor obj
|
||||
|
||||
newInstance = new obj.constructor()
|
||||
for key of obj
|
||||
newInstance[key] = clone obj[key], skipThangs
|
||||
|
||||
newInstance
|
||||
|
||||
|
|
|
@ -40,3 +40,6 @@
|
|||
font-size: 13px
|
||||
height: 24px
|
||||
|
||||
|
||||
#level-done-button
|
||||
display: none
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@import "../../../bootstrap/mixins"
|
||||
@import "app/styles/bootstrap/mixins"
|
||||
|
||||
@mixin editor-height($extraHeight)
|
||||
@include box-sizing(border-box)
|
||||
|
@ -123,3 +123,13 @@
|
|||
// https://github.com/codecombat/codecombat/issues/6
|
||||
color: rgb(145, 48, 50)
|
||||
|
||||
.ace_search
|
||||
background-color: rgba(216, 187, 165, 1)
|
||||
border: 0
|
||||
@include box-shadow(1px 2px 1px #444)
|
||||
|
||||
.ace_search_field
|
||||
width: 190px
|
||||
|
||||
.ace_searchbtn, .ace_replacebtn
|
||||
padding: 0px 4px
|
||||
|
|
|
@ -17,4 +17,4 @@ if spectateGame
|
|||
|
||||
button.btn.btn-xs.btn-inverse.banner#restart-button(title="Reload all custom code to reset level", data-i18n="play_level.restart") Restart
|
||||
|
||||
button.btn.btn-xs.btn-primary.banner.secret#level-done-button(data-i18n="play_level.done") Done
|
||||
button.btn.btn-xs.btn-primary.banner#level-done-button(data-i18n="play_level.done") Done
|
||||
|
|
|
@ -64,7 +64,7 @@ module.exports = class EditorLevelView extends View
|
|||
return unless @supermodel.finished()
|
||||
@$el.find('a[data-toggle="tab"]').on 'shown.bs.tab', (e) =>
|
||||
Backbone.Mediator.publish 'level:view-switched', e
|
||||
@thangsTab = @insertSubView new ThangsTabView world: @world, supermodel: @supermodel
|
||||
@thangsTab = @insertSubView new ThangsTabView world: @world, supermodel: @supermodel, level: @level
|
||||
@settingsTab = @insertSubView new SettingsTabView supermodel: @supermodel
|
||||
@scriptsTab = @insertSubView new ScriptsTabView world: @world, supermodel: @supermodel, files: @files
|
||||
@componentsTab = @insertSubView new ComponentsTabView supermodel: @supermodel
|
||||
|
|
|
@ -35,7 +35,6 @@ module.exports = class ThangsTabView extends View
|
|||
'surface:mouse-moved': 'onSurfaceMouseMoved'
|
||||
'surface:mouse-over': 'onSurfaceMouseOver'
|
||||
'surface:mouse-out': 'onSurfaceMouseOut'
|
||||
'level-loaded': 'onLevelLoaded'
|
||||
'edit-level-thang': 'editThang'
|
||||
'level-thang-edited': 'onLevelThangEdited'
|
||||
'level-thang-done-editing': 'onLevelThangDoneEditing'
|
||||
|
@ -68,6 +67,7 @@ module.exports = class ThangsTabView extends View
|
|||
@thangTypes = @supermodel.loadCollection(new ThangTypeSearchCollection(), 'thangs').model
|
||||
# just loading all Components for now: https://github.com/codecombat/codecombat/issues/405
|
||||
@componentCollection = @supermodel.loadCollection(new ComponentsCollection(), 'components').load()
|
||||
@level = options.level
|
||||
|
||||
$(document).bind 'contextmenu', @preventDefaultContextMenu
|
||||
|
||||
|
@ -113,7 +113,7 @@ module.exports = class ThangsTabView extends View
|
|||
@$el.find('#extant-thangs-filter button:first').button('toggle')
|
||||
$(window).resize @onWindowResize
|
||||
@addThangsView = @insertSubView new AddThangsView world: @world, supermodel: @supermodel
|
||||
@onLevelLoaded() # refactor to not have this trigger when this view re-renders?
|
||||
@buildInterface() # refactor to not have this trigger when this view re-renders?
|
||||
|
||||
onFilterExtantThangs: (e) ->
|
||||
@$el.find('#extant-thangs-filter button.active').button('toggle')
|
||||
|
@ -127,7 +127,7 @@ module.exports = class ThangsTabView extends View
|
|||
@scrollTop += (if e.deltaY < 0 then 1 else -1) * 30
|
||||
e.preventDefault()
|
||||
|
||||
onLevelLoaded: (e) ->
|
||||
buildInterface: (e) ->
|
||||
@level = e.level if e
|
||||
|
||||
data = $.extend(true, {}, @level.attributes)
|
||||
|
|
|
@ -115,7 +115,7 @@ module.exports = class CocoView extends Backbone.View
|
|||
|
||||
afterRender: ->
|
||||
|
||||
updateProgress: (progress)=>
|
||||
updateProgress: (progress) ->
|
||||
@loadProgress.progress = progress if progress > @loadProgress.progress
|
||||
@updateProgressBar(progress)
|
||||
|
||||
|
|
|
@ -6,9 +6,6 @@ module.exports = class LevelLoadingView extends View
|
|||
id: "level-loading-view"
|
||||
template: template
|
||||
|
||||
subscriptions:
|
||||
'level-loader:progress-changed': 'onLevelLoaderProgressChanged'
|
||||
|
||||
onLoaded: ->
|
||||
afterRender: ->
|
||||
@$el.find('.tip.rare').remove() if _.random(1, 10) < 9
|
||||
|
@ -17,15 +14,6 @@ module.exports = class LevelLoadingView extends View
|
|||
$(tip).removeClass('to-remove')
|
||||
@$el.find('.to-remove').remove()
|
||||
|
||||
onLevelLoaderProgressChanged: (e) ->
|
||||
return if @destroyed
|
||||
@progress = e.progress
|
||||
@progress = 0.01 if @progress < 0.01
|
||||
@updateProgressBar()
|
||||
|
||||
updateProgressBar: ->
|
||||
@$el.find('.progress-bar').css('width', (100 * @progress) + '%')
|
||||
|
||||
showReady: ->
|
||||
ready = $.i18n.t('play_level.loading_ready', defaultValue: 'Ready!')
|
||||
@$el.find('#tip-wrapper .tip').addClass('ready').text ready
|
||||
|
@ -35,7 +23,7 @@ module.exports = class LevelLoadingView extends View
|
|||
_.delay @reallyUnveil, 1000
|
||||
|
||||
reallyUnveil: =>
|
||||
return if @destroyed or @progress < 1
|
||||
return if @destroyed
|
||||
@$el.addClass 'unveiled'
|
||||
loadingDetails = @$el.find('.loading-details')
|
||||
duration = parseFloat loadingDetails.css 'transition-duration'
|
||||
|
|
|
@ -21,7 +21,7 @@ module.exports = class DebugView extends View
|
|||
@ace = options.ace
|
||||
@thang = options.thang
|
||||
@variableStates = {}
|
||||
@globals = {Math: Math, _: _} # ... add more as documented
|
||||
@globals = {Math: Math, _: _, String: String, Number: Number, Array: Array, Object: Object} # ... add more as documented
|
||||
for className, klass of serializedClasses
|
||||
@globals[className] = klass
|
||||
@onMouseMove = _.throttle @onMouseMove, 25
|
||||
|
@ -33,17 +33,18 @@ module.exports = class DebugView extends View
|
|||
setVariableStates: (@variableStates) ->
|
||||
@update()
|
||||
|
||||
isIdentifier: (t) ->
|
||||
t and (t.type is 'identifier' or t.value is 'this' or @globals[t.value])
|
||||
|
||||
onMouseMove: (e) =>
|
||||
return if @destroyed
|
||||
pos = e.getDocumentPosition()
|
||||
endOfDoc = pos.row is @ace.getSession().getDocument().getLength() - 1
|
||||
it = new TokenIterator e.editor.session, pos.row, pos.column
|
||||
isIdentifier = (t) => t and (t.type is 'identifier' or t.value is 'this' or @globals[t.value])
|
||||
while it.getCurrentTokenRow() is pos.row and not isIdentifier(token = it.getCurrentToken())
|
||||
endOfLine = it.getCurrentToken()?.index is it.$rowTokens.length - 1
|
||||
while it.getCurrentTokenRow() is pos.row and not @isIdentifier(token = it.getCurrentToken())
|
||||
break if endOfLine or not token # Don't iterate beyond end or beginning of line
|
||||
it.stepBackward()
|
||||
break unless token
|
||||
break if endOfDoc # Don't iterate backward on last line, since we might be way below.
|
||||
if isIdentifier token
|
||||
if @isIdentifier token
|
||||
# This could be a property access, like "enemy.target.pos" or "this.spawnedRectangles".
|
||||
# We have to realize this and dig into the nesting of the objects.
|
||||
start = it.getCurrentTokenColumn()
|
||||
|
@ -53,7 +54,7 @@ module.exports = class DebugView extends View
|
|||
break unless it.getCurrentToken()?.value is "."
|
||||
it.stepBackward()
|
||||
token = null # If we're doing a complex access like this.getEnemies().length, then length isn't a valid var.
|
||||
break unless isIdentifier(prev = it.getCurrentToken())
|
||||
break unless @isIdentifier(prev = it.getCurrentToken())
|
||||
token = prev
|
||||
start = it.getCurrentTokenColumn()
|
||||
chain.unshift token.value
|
||||
|
|
|
@ -87,10 +87,8 @@ module.exports = class PlayLevelView extends View
|
|||
@saveScreenshot = _.throttle @saveScreenshot, 30000
|
||||
|
||||
if @isEditorPreview
|
||||
f = =>
|
||||
@supermodel.shouldSaveBackups = (model) ->
|
||||
model.constructor.className in ['Level', 'LevelComponent', 'LevelSystem']
|
||||
@load() unless @levelLoader
|
||||
# wait to see if it's just given to us through setLevel
|
||||
f = => @load() unless @levelLoader
|
||||
setTimeout f, 100
|
||||
else
|
||||
@load()
|
||||
|
@ -100,7 +98,11 @@ module.exports = class PlayLevelView extends View
|
|||
# TODO NOW: remove this in favor of the supermodel handling it
|
||||
application.router.navigate "/play?not_found=#{@levelID}", {trigger: true}
|
||||
|
||||
setLevel: (@level, @supermodel) ->
|
||||
setLevel: (@level, givenSupermodel) ->
|
||||
@supermodel.models = givenSupermodel.models
|
||||
@supermodel.collections = givenSupermodel.collections
|
||||
@supermodel.shouldSaveBackups = givenSupermodel.shouldSaveBackups
|
||||
|
||||
@god?.level = @level.serialize @supermodel
|
||||
if @world
|
||||
serializedLevel = @level.serialize(@supermodel)
|
||||
|
@ -129,7 +131,8 @@ module.exports = class PlayLevelView extends View
|
|||
@$el.find('#level-done-button').hide()
|
||||
$('body').addClass('is-playing')
|
||||
|
||||
onLevelLoaderProgressChanged: ->
|
||||
updateProgress: (progress) ->
|
||||
super(progress)
|
||||
return if @seenDocs
|
||||
return unless @levelLoader.session.loaded and @levelLoader.level.loaded
|
||||
return unless showFrequency = @levelLoader.level.get('showsGuide')
|
||||
|
|
|
@ -106,7 +106,6 @@ module.exports = class SpectateLevelView extends View
|
|||
spectateMode: true
|
||||
team: @getQueryVariable("team")
|
||||
@listenToOnce(@levelLoader, 'loaded-all', @onLevelLoaderLoaded)
|
||||
@listenTo(@levelLoader, 'progress', @onLevelLoaderProgressChanged)
|
||||
@god = new God maxWorkerPoolSize: 1, maxAngels: 1
|
||||
|
||||
getRenderData: ->
|
||||
|
@ -121,7 +120,8 @@ module.exports = class SpectateLevelView extends View
|
|||
super()
|
||||
$('body').addClass('is-playing')
|
||||
|
||||
onLevelLoaderProgressChanged: ->
|
||||
updateProgress: (progress) ->
|
||||
super(progress)
|
||||
return if @seenDocs
|
||||
return unless showFrequency = @levelLoader.level.get('showGuide')
|
||||
session = @levelLoader.session
|
||||
|
@ -141,7 +141,10 @@ module.exports = class SpectateLevelView extends View
|
|||
Backbone.Mediator.subscribeOnce 'modal-closed', @onLevelLoaderLoaded, @
|
||||
return true
|
||||
|
||||
onLevelLoaderLoaded: ->
|
||||
onLoaded: ->
|
||||
_.defer => @onLevelLoaded()
|
||||
|
||||
onLevelLoaded: ->
|
||||
return unless @levelLoader.progress() is 1 # double check, since closing the guide may trigger this early
|
||||
# Save latest level played in local storage
|
||||
if window.currentModal and not window.currentModal.destroyed
|
||||
|
|
Loading…
Reference in a new issue