diff --git a/app/lib/Angel.coffee b/app/lib/Angel.coffee index 474b8fe54..8a9714410 100644 --- a/app/lib/Angel.coffee +++ b/app/lib/Angel.coffee @@ -190,7 +190,7 @@ module.exports = class Angel extends CocoClass goalStates = testGM?.getGoalStates() serialized = testWorld.serialize().serializedWorld window.BOX2D_ENABLED = false - World.deserialize serialized, @angelsShare.worldClassMap, @hsared.lastSerializedWorldFrames, @finishBeholdingWorld(goalStates) + World.deserialize serialized, @angelsShare.worldClassMap, @shared.lastSerializedWorldFrames, @finishBeholdingWorld(goalStates) window.BOX2D_ENABLED = true @shared.lastSerializedWorldFrames = serialized.frames diff --git a/app/lib/scripts/SurfaceScriptModule.coffee b/app/lib/scripts/SurfaceScriptModule.coffee index 7642cfd33..d6c3b3016 100644 --- a/app/lib/scripts/SurfaceScriptModule.coffee +++ b/app/lib/scripts/SurfaceScriptModule.coffee @@ -30,7 +30,6 @@ module.exports = class SurfaceScriptModule extends ScriptModule e.pos = focus.target if _.isPlainObject focus.target e.thangID = focus.target if _.isString focus.target e.zoom = focus.zoom or 2.0 # TODO: test only doing this if e.pos, e.thangID, or focus.zoom? - e.zoom *= 2 if e.zoom # On 2014-03-16, we doubled the canvas width/height, so now we have a legacy zoom multipler. e.duration = if focus.duration? then focus.duration else 1500 e.duration = 0 if instant e.bounds = focus.bounds if focus.bounds? diff --git a/app/lib/surface/Camera.coffee b/app/lib/surface/Camera.coffee index 151d6d33a..bbc7b36b9 100644 --- a/app/lib/surface/Camera.coffee +++ b/app/lib/surface/Camera.coffee @@ -10,6 +10,8 @@ MIN_ZOOM = 0.1 DEFAULT_ZOOM = 2.0 DEFAULT_TARGET = {x:0, y:0} DEFAULT_TIME = 1000 +STANDARD_ZOOM_WIDTH = 924 +STANDARD_ZOOM_HEIGHT = 589 # You can't mutate any of the constructor parameters after construction. # You can only call zoomTo to change the zoom target and zoom level. @@ -46,12 +48,16 @@ module.exports = class Camera extends CocoClass constructor: (@canvasWidth, @canvasHeight, angle=Math.asin(0.75), hFOV=d2r(30)) -> super() - @offset = {x: 0, y:0} + @offset = {x: 0, y: 0} @calculateViewingAngle angle @calculateFieldOfView hFOV @calculateAxisConversionFactors() + @calculateMinMaxZoom() @updateViewports() - @calculateMinZoom() + + onResize: (newCanvasWidth, newCanvasHeight) -> + @canvasScaleFactorX = newCanvasWidth / @canvasWidth + @canvasScaleFactorY = newCanvasHeight / @canvasHeight calculateViewingAngle: (angle) -> # Operate on open interval between 0 - 90 degrees to make the math easier @@ -91,15 +97,11 @@ module.exports = class Camera extends CocoClass surfaceToCanvas: (pos) -> {x: (pos.x - @surfaceViewport.x) * @zoom, y: (pos.y - @surfaceViewport.y) * @zoom} - # TODO: do we even need separate screen coordinates? - # We would need some other properties for the actual ratio of screen size to canvas size. canvasToScreen: (pos) -> - #{x: pos.x * @someCanvasToScreenXScaleFactor, y: pos.y * @someCanvasToScreenYScaleFactor} - {x: pos.x, y: pos.y} + {x: pos.x * @canvasScaleFactorX, y: pos.y * @canvasScaleFactorY} screenToCanvas: (pos) -> - #{x: pos.x / @someCanvasToScreenXScaleFactor, y: pos.y / @someCanvasToScreenYScaleFactor} - {x: pos.x, y: pos.y} + {x: pos.x / @canvasScaleFactorX, y: pos.y / @canvasScaleFactorY} canvasToSurface: (pos) -> {x: pos.x / @zoom + @surfaceViewport.x, y: pos.y / @zoom + @surfaceViewport.y} @@ -161,11 +163,9 @@ module.exports = class Camera extends CocoClass newHeight = @canvasHeight / newZoom newTargetX = mousePoint.x - (newWidth * ratioPosX) + (newWidth / 2) newTargetY = mousePoint.y - (newHeight * ratioPosY) + (newHeight / 2) - target = {x: newTargetX, y:newTargetY} + target = {x: newTargetX, y: newTargetY} else target = @target - newZoom = Math.min newZoom, MAX_ZOOM - newZoom = Math.max newZoom, MIN_ZOOM, @minZoom @zoomTo target, newZoom, 0 onMouseDown: (e) -> @@ -175,10 +175,9 @@ module.exports = class Camera extends CocoClass onMouseDragged: (e) -> return if @dragDisabled target = @boundTarget(@target, @zoom) - newPos = { + newPos = x: target.x + (@lastPos.x - e.originalEvent.rawX) / @zoom y: target.y + (@lastPos.y - e.originalEvent.rawY) / @zoom - } @zoomTo newPos, @zoom, 0 @lastPos = {x: e.originalEvent.rawX, y: e.originalEvent.rawY} Backbone.Mediator.publish 'camera:dragged' @@ -192,7 +191,7 @@ module.exports = class Camera extends CocoClass # receives an array of two world points. Normalize and apply them @firstBounds = worldBounds unless @firstBounds @bounds = @normalizeBounds(worldBounds) - @calculateMinZoom() + @calculateMinMaxZoom() @updateZoom true if updateZoom @target = @currentTarget unless @focusedOnSprite() @@ -208,29 +207,31 @@ module.exports = class Camera extends CocoClass p2 = @worldToSurface({x:right, y:bottom}) {x:p1.x, y:p1.y, width:p2.x-p1.x, height:p2.y-p1.y} - calculateMinZoom: -> + calculateMinMaxZoom: -> # Zoom targets are always done in Surface coordinates. - if not @bounds - @minZoom = 0.5 - return + @maxZoom = MAX_ZOOM + return @minZoom = MIN_ZOOM unless @bounds @minZoom = Math.max @canvasWidth / @bounds.width, @canvasHeight / @bounds.height - @zoom = Math.max(@minZoom, @zoom) if @zoom + if @zoom + @zoom = Math.max @minZoom, @zoom + @zoom = Math.min @maxZoom, @zoom zoomTo: (newTarget=null, newZoom=1.0, time=1500) -> # Target is either just a {x, y} pos or a display object with {x, y} that might change; surface coordinates. time = 0 if @instant - newTarget ?= {x:0, y:0} + newTarget ?= {x: 0, y: 0} newTarget = (@newTarget or @target) if @locked - newZoom = Math.min((Math.max @minZoom, newZoom), MAX_ZOOM) + newZoom = Math.max newZoom, @minZoom + newZoom = Math.min newZoom, @maxZoom thangType = @target?.sprite?.thangType if thangType - @offset = _.clone(thangType.get('positions')?.torso or {x: 0, y:0}) + @offset = _.clone(thangType.get('positions')?.torso or {x: 0, y: 0}) scale = thangType.get('scale') or 1 @offset.x *= scale @offset.y *= scale else - @offset = {x: 0, y:0} + @offset = {x: 0, y: 0} return if @zoom is newZoom and newTarget is newTarget.x and newTarget.y is newTarget.y @@ -311,4 +312,4 @@ module.exports = class Camera extends CocoClass super() onZoomTo: (pos, time) -> - @zoomTo(@worldToSurface(pos), @zoom, time) + @zoomTo @worldToSurface(pos), @zoom, time diff --git a/app/lib/surface/CoordinateDisplay.coffee b/app/lib/surface/CoordinateDisplay.coffee index 3094e49f2..63dbc61b3 100644 --- a/app/lib/surface/CoordinateDisplay.coffee +++ b/app/lib/surface/CoordinateDisplay.coffee @@ -24,7 +24,7 @@ module.exports = class CoordinateDisplay extends createjs.Container build: -> @mouseEnabled = @mouseChildren = false @addChild @background = new createjs.Shape() - @addChild @label = new createjs.Text("", "bold 32px Arial", "#FFFFFF") + @addChild @label = new createjs.Text("", "bold 16px Arial", "#FFFFFF") @label.name = 'Coordinate Display Text' @label.shadow = new createjs.Shadow("#000000", 1, 1, 0) @background.name = "Coordinate Display Background" @@ -37,7 +37,7 @@ module.exports = class CoordinateDisplay extends createjs.Container $('#surface').addClass('flag-cursor') unless $('#surface').hasClass('flag-cursor') else if @mouseInBounds $('#surface').removeClass('flag-cursor') if $('#surface').hasClass('flag-cursor') - wop = @camera.canvasToWorld x: e.x, y: e.y + wop = @camera.screenToWorld x: e.x, y: e.y wop.x = Math.round(wop.x) wop.y = Math.round(wop.y) return if wop.x is @lastPos?.x and wop.y is @lastPos?.y @@ -47,7 +47,7 @@ module.exports = class CoordinateDisplay extends createjs.Container onMouseDown: (e) -> return unless key.shift - wop = @camera.canvasToWorld x: e.x, y: e.y + wop = @camera.screenToWorld x: e.x, y: e.y wop.x = Math.round wop.x wop.y = Math.round wop.y Backbone.Mediator.publish 'surface:coordinate-selected', wop @@ -63,8 +63,8 @@ module.exports = class CoordinateDisplay extends createjs.Container @uncache() updateSize: -> - margin = 6 - radius = 5 + margin = 3 + radius = 2.5 width = @label.getMeasuredWidth() + 2 * margin height = @label.getMeasuredHeight() + 2 * margin @label.regX = @background.regX = width / 2 - margin @@ -85,7 +85,7 @@ module.exports = class CoordinateDisplay extends createjs.Container [width, height] = @updateSize() sup = @camera.worldToSurface @lastPos @x = sup.x - @y = sup.y - 5 + @y = sup.y - 2.5 @addChild @background @addChild @label @cache -width / 2, -height / 2, width, height diff --git a/app/lib/surface/DebugDisplay.coffee b/app/lib/surface/DebugDisplay.coffee index 925d98592..a53059bf4 100644 --- a/app/lib/surface/DebugDisplay.coffee +++ b/app/lib/surface/DebugDisplay.coffee @@ -25,10 +25,10 @@ module.exports = class DebugDisplay extends createjs.Container build: -> @mouseEnabled = @mouseChildren = false - @addChild @frameText = new createjs.Text "...", "40px Arial", "#FFF" + @addChild @frameText = new createjs.Text "...", "20px Arial", "#FFF" @frameText.name = 'frame text' - @frameText.x = @canvasWidth - 100 - @frameText.y = @canvasHeight - 50 + @frameText.x = @canvasWidth - 50 + @frameText.y = @canvasHeight - 25 @frameText.alpha = 0.5 updateFrame: (currentFrame) -> @@ -42,4 +42,4 @@ module.exports = class DebugDisplay extends createjs.Container @framesRenderedThisSecond = 0 @frameText.text = Math.round(currentFrame) + (if @fps? then " - " + @fps + ' fps' else '') - @frameText.x = @canvasWidth - @frameText.getMeasuredWidth() - 20 + @frameText.x = @canvasWidth - @frameText.getMeasuredWidth() - 10 diff --git a/app/lib/surface/Label.coffee b/app/lib/surface/Label.coffee index ef8e742cd..3609546d7 100644 --- a/app/lib/surface/Label.coffee +++ b/app/lib/surface/Label.coffee @@ -61,7 +61,7 @@ module.exports = class Label extends CocoClass o.fontWeight = {D: "bold", S: "bold", N: "bold"}[st] o.shadow = {D: false, S: true, N: true}[st] o.shadowColor = {D: "#FFF", S: "#000", N: "#FFF"}[st] - o.fontSize = {D: 50, S: 24, N: 24}[st] + o.fontSize = {D: 25, S: 12, N: 12}[st] fontFamily = {D: "Arial", S: "Arial", N: "Arial"}[st] o.fontDescriptor = "#{o.fontWeight} #{o.fontSize}px #{fontFamily}" o.fontColor = {D: "#000", S: "#FFF", N: "#00a"}[st] @@ -174,6 +174,8 @@ module.exports = class Label extends CocoClass if width > maxWidth if row.length is 1 # one long word, truncate it row[0] = _.string.truncate(row[0], 40) + text.text = row[0] + textWidth = Math.max(text.getMeasuredWidth(), textWidth) rows.push(row) row = [] else @@ -182,7 +184,7 @@ module.exports = class Label extends CocoClass row = [word] else textWidth = Math.max(textWidth, width) - rows.push(row) + rows.push(row) if row.length for row, i in rows rows[i] = _.string.join(" ", row...) text: _.string.join("\n", rows...), textWidth: textWidth diff --git a/app/lib/surface/Mark.coffee b/app/lib/surface/Mark.coffee index 7c9abb91f..8cc3bcfa7 100644 --- a/app/lib/surface/Mark.coffee +++ b/app/lib/surface/Mark.coffee @@ -81,7 +81,7 @@ module.exports = class Mark extends CocoClass shape.graphics.endStroke() shape.graphics.endFill() - text = new createjs.Text "" + index, "40px Arial", color.replace('0.5', '1') + text = new createjs.Text "" + index, "20px Arial", color.replace('0.5', '1') text.regX = text.getMeasuredWidth() / 2 text.regY = text.getMeasuredHeight() / 2 text.shadow = new createjs.Shadow("#000000", 1, 1, 0) diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee index dc93b812f..b325596f4 100644 --- a/app/lib/surface/SpriteBoss.coffee +++ b/app/lib/surface/SpriteBoss.coffee @@ -264,7 +264,7 @@ module.exports = class SpriteBoss extends CocoClass worldPos = sprite?.thang?.pos worldPos ?= @camera.canvasToWorld {x: e.originalEvent.rawX, y: e.originalEvent.rawY} if e if worldPos and (@options.navigateToSelection or not sprite or treemaThangSelected) - @camera.zoomTo(sprite?.displayObject or @camera.worldToSurface(worldPos), @camera.zoom, 1000) + @camera.zoomTo(sprite?.displayObject or @camera.worldToSurface(worldPos), @camera.zoom, 1000, true) sprite = null if @options.choosing # Don't select sprites while choosing if sprite isnt @selectedSprite @selectedSprite?.selected = false diff --git a/app/lib/surface/Surface.coffee b/app/lib/surface/Surface.coffee index 43384a42f..a45fdafec 100644 --- a/app/lib/surface/Surface.coffee +++ b/app/lib/surface/Surface.coffee @@ -81,6 +81,8 @@ module.exports = Surface = class Surface extends CocoClass @options = _.extend(@options, givenOptions) if givenOptions @initEasel() @initAudio() + @onResize = _.debounce @onResize, 500 + $(window).on 'resize', @onResize destroy: -> @dead = true @@ -102,6 +104,7 @@ module.exports = Surface = class Surface extends CocoClass @stage.enableDOMEvents false @stage.enableMouseOver 0 @canvas.off 'mousewheel', @onMouseWheel + $(window).off 'resize', @onResize super() setWorld: (@world) -> @@ -377,8 +380,8 @@ module.exports = Surface = class Surface extends CocoClass initEasel: -> # takes DOM objects, not jQuery objects @stage = new createjs.Stage(@canvas[0]) - canvasWidth = parseInt(@canvas.attr('width'), 10) - canvasHeight = parseInt(@canvas.attr('height'), 10) + canvasWidth = parseInt @canvas.attr('width'), 10 + canvasHeight = parseInt @canvas.attr('height'), 10 @camera?.destroy() @camera = new Camera canvasWidth, canvasHeight AudioPlayer.camera = @camera @@ -398,6 +401,18 @@ module.exports = Surface = class Surface extends CocoClass @hookUpChooseControls() if @options.choosing createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED createjs.Ticker.setFPS @options.frameRate + @onResize() + + onResize: (e) => + oldWidth = parseInt @canvas.attr('width'), 10 + oldHeight = parseInt @canvas.attr('height'), 10 + newWidth = @canvas.width() + newHeight = @canvas.height() + console.log "had size", oldWidth, oldHeight, "moving to", newWidth, newHeight + @canvas.attr width: newWidth, height: newHeight + @stage.scaleX *= newWidth / oldWidth + @stage.scaleY *= newHeight / oldHeight + @camera.onResize newWidth, newHeight showLevel: -> return if @dead diff --git a/app/lib/world/GoalManager.coffee b/app/lib/world/GoalManager.coffee index 324297db9..09e611d07 100644 --- a/app/lib/world/GoalManager.coffee +++ b/app/lib/world/GoalManager.coffee @@ -237,12 +237,12 @@ module.exports = class GoalManager extends CocoClass # saveThangs: by default we would want to save all the Thangs, which means that we would want none of them to be "done" numNeeded = _.size(stateThangs) - Math.max((goal.howMany ? 1), _.size stateThangs) + 1 numDone = _.filter(stateThangs).length - console.log "needed", numNeeded, "done", numDone, "of total", _.size(stateThangs), "with how many", goal.howMany, "and stateThangs", stateThangs + #console.log "needed", numNeeded, "done", numDone, "of total", _.size(stateThangs), "with how many", goal.howMany, "and stateThangs", stateThangs return unless numDone >= numNeeded return if state.status and not success # already failed it; don't wipe keyframe state.status = if success then "success" else "failure" state.keyFrame = frameNumber - console.log goalID, "became", success, "on frame", frameNumber, "with overallStatus", @checkOverallStatus true + #console.log goalID, "became", success, "on frame", frameNumber, "with overallStatus", @checkOverallStatus true if overallStatus = @checkOverallStatus true matchedGoals = (_.find(@goals, {id: goalID}) for goalID, goalState of @goalStates when goalState.status is overallStatus) mostEagerGoal = _.min matchedGoals, 'worldEndsAfter' diff --git a/app/styles/play/level/gold.sass b/app/styles/play/level/gold.sass index 59c2e73dd..c1efa04bb 100644 --- a/app/styles/play/level/gold.sass +++ b/app/styles/play/level/gold.sass @@ -2,6 +2,7 @@ @import "app/styles/bootstrap/mixins" #gold-view + display: none position: absolute right: 46% top: 42px diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee index 069a0e508..72c88f9c6 100644 --- a/app/views/play/level_view.coffee +++ b/app/views/play/level_view.coffee @@ -466,7 +466,7 @@ module.exports = class PlayLevelView extends View onSessionWillSave: (e) -> # Something interesting has happened, so (at a lower frequency), we'll save a screenshot. - @saveScreenshot e.session + #@saveScreenshot e.session # Throttled saveScreenshot: (session) => diff --git a/scripts/transpile.coffee b/scripts/transpile.coffee new file mode 100644 index 000000000..09065bbc9 --- /dev/null +++ b/scripts/transpile.coffee @@ -0,0 +1,84 @@ +do (setupLodash = this) -> + GLOBAL._ = require 'lodash' + _.str = require 'underscore.string' + _.mixin _.str.exports() +Aether = require "aether" +async = require 'async' + +serverSetup = require '../server_setup' +Level = require '../server/levels/Level.coffee' +LevelSession = require '../server/levels/sessions/LevelSession.coffee' + +Aether.addGlobal 'Vector', require '../app/lib/world/vector' +Aether.addGlobal '_', _ + +transpileLevelSession = (sessionID, cb) -> + query = LevelSession + .find("_id": sessionID) + .select("submittedCode") + .lean() + query.exec (err, session) -> + if err then return cb err + submittedCode = session.submittedCode + transpiledCode = {} + + for thang, spells of submittedCode + transpiledCode[thang] = {} + for spellID, spell of spells + aetherOptions = + problems: {} + language: "javascript" + functionName: spellID + functionParameters: {} + yieldConditionally: spellID is "plan" + globals: ['Vector', '_'] + protectAPI: true + includeFlow: false + aether = new Aether aetherOptions + transpiledCode[thang][spellID] = aether.transpile spell + cb "Prematurely ended" + + + + +findLadderLevelSessions = (levelID, cb) -> + queryParameters = + level: + original: levelID + "" + submitted: true + + selectString = "_id" + query = LevelSession + .find(queryParameters) + .select(selectString) + .lean() + query.exec (err, levelSessions) -> + if err then return cb err + levelSessionIDs = _.pluck levelSessions, "_id" + async.each levelSessionIDs, transpileLevelSession, (err) -> + if err then return cb err + cb null + + +transpileLadderSessions = -> + queryParameters = + type: "ladder" + version: + "isLatestMajor": true + "isLatestMinor": true + selectString = "original" + query = Level + .find(queryParameters) + .select(selectString) + .lean() + query.exec (err, ladderLevels) -> + throw err if err + ladderLevels = _.pluck ladderLevels, "original" + console.log "Found ladderlevels" + console.log ladderLevels + async.each ladderLevels, findLadderLevelSessions, (err) -> + throw err if err +serverSetup.connectToDatabase() +transpileLadderSessions() + + \ No newline at end of file