From 24af8b6cce30319324cc22f196b48fb246df2064 Mon Sep 17 00:00:00 2001 From: monsterkodi Date: Mon, 15 Aug 2016 01:08:47 +0200 Subject: [PATCH] follo --- coffee/action.coffee | 30 ++++---- coffee/bot.coffee | 138 +++++++++++++++++++------------------ coffee/cage.coffee | 18 +++-- coffee/event.coffee | 1 + coffee/levels/steps.coffee | 8 +-- coffee/player.coffee | 114 ++++++++++++++++-------------- coffee/pushable.coffee | 19 ++--- coffee/timer.coffee | 1 + coffee/world.coffee | 89 ++++++++++++------------ 9 files changed, 219 insertions(+), 199 deletions(-) diff --git a/coffee/action.coffee b/coffee/action.coffee index 7d328cc..2566b94 100644 --- a/coffee/action.coffee +++ b/coffee/action.coffee @@ -75,21 +75,21 @@ class Action log "action.reset #{@name}" @start = 0 # world time @rest = 0 - @last = 0 # relative - @current = 0 # relative + @last = 0 # relative (ms since @start) + @current = 0 # relative (ms since @start) + #@event = null - takeRest: (action) -> - @current = action.rest + takeOver: (action) -> + log "takeOver #{action.rest} from #{action.name} this: #{@name}" + @current = action.current @start = action.start - @last = 0 - @rest = 0 + @last = action.last + @rest = action.rest keepRest: () -> if @rest != 0 @current = @rest @rest = 0 - # @last = 0 - # @current = 0 getRelativeTime: -> @current / @getDuration() getRelativeDelta: -> (@current-@last) / @getDuration() @@ -109,15 +109,17 @@ class Action @finished() if @duration == 0 and @mode == Action.ONCE else currentDiff = eventTime - @start - if currentDiff >= @getDuration() - @current = @getDuration() - - @start += @current - @rest = eventTime - @start + msDur = @getDuration() + if currentDiff >= msDur + @current = msDur + # @start = msDur + @rest = currentDiff - msDur + # log "action #{name} performWithEvent start #{@start} rest #{currentDiff}-#{msDur} = #{@rest}" if @name != 'noop' @perform() @last = 0 if @mode == Action.CONTINUOUS + log 'Action.CONTINUOUS' @current = @rest return event.removeAction @ if @mode == Action.ONCE @@ -125,7 +127,7 @@ class Action @finish() if @mode == Action.REPEAT - if @current == @getDuration() # if keepRest wasn't called -> reset start and current values + if @current >= @getDuration() # if keepRest wasn't called -> reset start and current values @reset() return diff --git a/coffee/bot.coffee b/coffee/bot.coffee index bbf85df..cd3d50f 100644 --- a/coffee/bot.coffee +++ b/coffee/bot.coffee @@ -17,29 +17,26 @@ class Bot extends Pushable constructor: () -> - @direction = new Quaternion + @direction = new Vector @orientation = new Quaternion @current_orientation = new Quaternion @rotate_orientation = new Quaternion @climb_orientation = new Quaternion @rest_orientation = new Quaternion - tireRadius = 0.15 + tireRadius = 0.05 nose = new THREE.ConeGeometry 0.404, 0.5, 32, 16, true geom = new THREE.SphereGeometry 0.5, 32, 32, 16, Math.PI geom = new THREE.SphereGeometry 0.5, 32, 32, 0, 2*Math.PI, 0, 2.2 noseMat = new THREE.Matrix4() - trans = new THREE.Vector3 0,-0.543,0 - rot = new THREE.Quaternion().setFromEuler new THREE.Euler Vector.DEG2RAD(180), 0, 0 + trans = new THREE.Vector3 0,-0.543,0 + rot = new THREE.Quaternion().setFromEuler new THREE.Euler Vector.DEG2RAD(180), 0, 0 noseMat.compose trans, rot, new THREE.Vector3 1,1,1 geom.merge nose, noseMat geom.rotateX Vector.DEG2RAD -90 - # geom.mergeVertices() - # geom.computeFaceNormals() - # geom.computeVertexNormals() geom.scale 0.7, 0.7, 0.7 botMat = new THREE.MeshPhongMaterial @@ -48,30 +45,27 @@ class Bot extends Pushable shading: THREE.SmoothShading roughness: 0.9 metalness: 1 - transparent: true - opacity: 0.9 shininess: 5 @mesh = new THREE.Mesh geom, botMat - geom = new THREE.TorusGeometry 0.5-tireRadius, tireRadius, 16, 16 + geom = new THREE.TorusGeometry 0.5-tireRadius, tireRadius, 16, 32 + geom.scale 1,1,2.5 tireMat = new THREE.MeshPhongMaterial color: 0x000066 specular: 0x222255 side: THREE.FrontSide shading: THREE.FlatShading - transparent: true - opacity: 0.7 shininess: 4 @leftTire = new THREE.Mesh geom, tireMat - @leftTire.position.set 0.5-tireRadius,0,0 + @leftTire.position.set 0.35,0,0 @leftTire.rotation.set 0, Vector.DEG2RAD(90), 0 @mesh.add @leftTire @rightTire = new THREE.Mesh geom, tireMat - @rightTire.position.set -0.5+tireRadius,0,0 + @rightTire.position.set -0.35,0,0 @rightTire.rotation.set 0, Vector.DEG2RAD(-90), 0 @mesh.add @rightTire @@ -113,10 +107,20 @@ class Bot extends Pushable @startTimedAction @getActionWithId(Action.NOOP), 500 - getDown: -> @orientation.rotate(new Vector 0,1,0).neg() - getUp: -> @orientation.rotate(new Vector 0,1,0) - getDir: -> @orientation.rotate(new Vector 0,0,1).mul @dir_sgn - getCurrentDir: -> @current_orientation.rotate(new Vector(0,0,1)).normal() + + # 0000000 000 00000000 00000000 0000000 000000000 000 0000000 000 000 + # 000 000 000 000 000 000 000 000 000 000 000 0000 000 + # 000 000 000 0000000 0000000 000 000 000 000 000 000 0 000 + # 000 000 000 000 000 000 000 000 000 000 000 000 0000 + # 0000000 000 000 000 00000000 0000000 000 000 0000000 000 000 + + getDown: -> @orientation.rotate new Vector 0,-1,0 + getUp: -> @orientation.rotate new Vector 0,1,0 + getDir: -> @orientation.rotate new Vector 0,0,@dir_sgn + + getCurrentDir: -> @current_orientation.rotate(new Vector 0,0,1).normal() + getCurrentUp: -> @current_orientation.rotate(new Vector 0,1,0).normal() + getCurrentLeft: -> @current_orientation.rotate(new Vector 1,0,0).normal() addMoves: (m) -> @moves += m addHealth: (h) -> @health = Math.max @health+h @@ -176,7 +180,7 @@ class Bot extends Pushable initAction: (action) -> newPos = new Pos @position - log "initAction #{action.name} pos", newPos + # log "initAction #{action.name} pos", newPos switch action.id when Action.NOOP then return @@ -189,15 +193,13 @@ class Bot extends Pushable if not @direction.isZero() super action return - else - newPos.add @getDown() - break + newPos.add @getDown() else super action return if not newPos.eql new Pos @position - log 'bot.initAction objectWillMoveToPos:', newPos + # log 'bot.initAction objectWillMoveToPos:', newPos world.objectWillMoveToPos @, newPos, action.getDuration() # 00000000 00000000 00000000 00000000 0000000 00000000 00 00 @@ -213,7 +215,10 @@ class Bot extends Pushable # log "Bot.performAction #{action.name} #{action.current} #{action.last} #{action.duration} id #{action.id}" # log "Bot.performAction #{action.name} #{relTime} #{dltTime} id #{action.id}" - + # cosFac = 1.0 - Math.cos(Math.PI/2 * relTime) + cosFac = Math.cos Math.PI/2 - Math.PI/2 * relTime + sinFac = Math.sin Math.PI/2 * relTime + # log "bot.performAction peform #{action.name} #{relTime} #{action.current} #{action.getDuration()}" switch action.id when Action.SHOOT if relTime == 0 @@ -225,25 +230,25 @@ class Bot extends Pushable @left_tire_rot += @dir_sgn * dltTime @right_tire_rot += @dir_sgn * dltTime - @current_position = @position.plus @getDir().mul relTime + @current_position = @position.plus @getDir().mul(relTime) # log 'bot.forward', @current_position return when Action.JUMP - @current_position = @position.plus @getUp().mul Math.cos(Math.PI/2 - Math.PI/2 * relTime) + @current_position = @position.plus @getUp().mul(sinFac) return when Action.JUMP_FORWARD - @left_tire_rot += Math.cos(Math.PI/2 - Math.PI/2 * dltTime) - @right_tire_rot += Math.cos(Math.PI/2 - Math.PI/2 * dltTime) - @current_position = @position.plus @getDir().mul(1.0 - Math.cos(Math.PI/2 * relTime)).plus @getUp().mul Math.cos(Math.PI/2 - Math.PI/2 * relTime) + @left_tire_rot += 1 - Math.cos(Math.PI/2 * dltTime) + @right_tire_rot += 1 - Math.cos(Math.PI/2 * dltTime) + @current_position = @position.plus @getDir().mul(relTime).plus @getUp().mul(sinFac) return when Action.FALL_FORWARD - @current_position = @position.plus @getDir().mul(Math.cos(Math.PI/2 - Math.PI/2 * relTime)).plus @getDown().mul (1.0 - Math.cos(Math.PI/2 * relTime)) + @current_position = @position.plus @getDir().mul(cosFac).plus @getDown().mul(cosFac) return when Action.FALL @@ -251,14 +256,14 @@ class Bot extends Pushable if not @direction.isZero() super action return - @current_position = @position.plus @getDown().mul relTime + @current_position = @position.plus @getDown().mul(relTime) return when Action.CLIMB_UP @left_tire_rot += @dir_sgn * dltTime/2 @right_tire_rot += @dir_sgn * dltTime/2 - @climb_orientation = Quaternion.rotationAroundVector @dir_sgn * relTime * -90.0, new Vector(1,0,0) + @climb_orientation = Quaternion.rotationAroundVector @dir_sgn * relTime * -90.0, new Vector 1,0,0 break when Action.CLIMB_DOWN @@ -378,7 +383,7 @@ class Bot extends Pushable @startTimedAction @getActionWithId(Action.NOOP), 0 return - if action.id == Action.PUSH #or action.id == Action.FALL # not @direction.isZero() + if action.id == Action.PUSH and not @direction.isZero() #or action.id == Action.FALL # not @direction.isZero() log 'super (Pushable) action!' super action return @@ -390,13 +395,13 @@ class Bot extends Pushable # find next action depending on type of finished action and surrounding environment if action.id == Action.JUMP_FORWARD forwardPos = @position.plus @getDir() - log 'jump forwardPos', forwardPos + # log 'jump forwardPos', forwardPos if world.isUnoccupiedPos forwardPos # forward will be empty if world.isUnoccupiedPos forwardPos.minus @getUp() # below forward will also be empty @move_action = @getActionWithId Action.FALL_FORWARD - @move_action.takeRest action + # @move_action.takeRwest action else @move_action = @getActionWithId Action.FORWARD world.playSound 'BOT_LAND', @getPos(), 0.25 @@ -404,7 +409,7 @@ class Bot extends Pushable if world.isUnoccupiedPos @position.minus @getUp() # below is empty @move_action = @getActionWithId Action.CLIMB_UP world.playSound 'BOT_LAND', @getPos(), 0.5 - else if world.isUnoccupiedPos @position.minus @getUp() # below will be empty + else if world.isUnoccupiedPos @position.plus @getDown() # below will be empty log 'below will be empty!' if @move # sticky if moving if world.isUnoccupiedPos @position.plus @getDir() @@ -420,9 +425,9 @@ class Bot extends Pushable @move_action = @getActionWithId Action.CLIMB_UP if @move_action == null - log 'fall!' + log 'bot.actionFinished fall!' @move_action = @getActionWithId Action.FALL - @move_action.takeRest action + # @move_action.takeRest action else if action.id == Action.FALL or action.id == Action.FALL_FORWARD # landed log 'fall|forward!' @@ -432,14 +437,14 @@ class Bot extends Pushable world.playSound 'BOT_LAND', @getPos() if @move_action - log 'move_action!' + log "add move_action! #{@move_action.name}" Timer.addAction @move_action return return if @rotate_action - if @move - log '!move' + if @move or @jump + log '!move or jump!' @moveBot() else @dir_sgn = 1 @@ -455,37 +460,38 @@ class Bot extends Pushable moveBot: () -> @move_action = null - # log "bot.moveBot @position", @position - # log "bot.moveBot @getDir", @getDir() forwardPos = @position.plus @getDir() - # log "bot.moveBot", forwardPos - if @jump or @jump_once and # jump mode or jump activated while moving + if @move and (@jump or @jump_once) and # jump mode or jump activated while moving @dir_sgn == 1.0 and # and moving forward - world.isUnoccupiedPos @position.plus @getUp() # and above empty - if world.isUnoccupiedPos forwardPos.plus @getUp() and - world.isUnoccupiedPos forwardPos # forward and above forward also empty + world.isUnoccupiedPos(@position.plus @getUp()) # and above empty + if world.isUnoccupiedPos(forwardPos.plus @getUp()) and + world.isUnoccupiedPos(forwardPos) # forward and above forward also empty @move_action = @getActionWithId Action.JUMP_FORWARD else # no space to jump forward -> jump up @move_action = @getActionWithId Action.JUMP - else if world.isUnoccupiedPos forwardPos # forward is empty - log 'forward is empty' - if world.isUnoccupiedPos forwardPos.plus @getDown() - # below forward also empty - @move_action = @getActionWithId Action.CLIMB_DOWN - else # forward down is solid - @move_action = @getActionWithId Action.FORWARD - else # forward is not empty - log 'forward is not empty' - moveAction = @getActionWithId Action.FORWARD - if @push and world.mayObjectPushToPos @, forwardPos, moveAction.getDuration() - moveAction.reset() - # player in push mode and pushing object is possible - if world.isUnoccupiedPos forwardPos.plus @getDown() # below forward is empty + else if @move + if world.isUnoccupiedPos forwardPos # forward is empty + log 'forward is empty' + if world.isUnoccupiedPos forwardPos.plus @getDown() + # below forward also empty @move_action = @getActionWithId Action.CLIMB_DOWN - else - @move_action = moveAction - else # just climb up - @move_action = @getActionWithId Action.CLIMB_UP + else # forward down is solid + @move_action = @getActionWithId Action.FORWARD + else # forward is not empty + log 'forward is not empty' + moveAction = @getActionWithId Action.FORWARD + if @push and world.mayObjectPushToPos @, forwardPos, moveAction.getDuration() + moveAction.reset() + # player in push mode and pushing object is possible + if world.isUnoccupiedPos forwardPos.plus @getDown() # below forward is empty + @move_action = @getActionWithId Action.CLIMB_DOWN + else + @move_action = moveAction + else # just climb up + @move_action = @getActionWithId Action.CLIMB_UP + else if @jump or @jump_once + if world.isUnoccupiedPos(@position.plus @getUp()) + @move_action = @getActionWithId Action.JUMP # reset the jump once flag (either we jumped or it's not possible to jump at current @position) @jump_once = false diff --git a/coffee/cage.coffee b/coffee/cage.coffee index c817b80..d191e93 100644 --- a/coffee/cage.coffee +++ b/coffee/cage.coffee @@ -21,22 +21,20 @@ class Cage side: THREE.FrontSide shading: THREE.SmoothShading shininess: 20 - - geom = @wallTiles @gap - - @cage = new THREE.Mesh geom, cageMat - @cage.translateX -0.5 - @cage.translateY -0.5 - @cage.translateZ -0.5 - world.scene.add @cage geom = @wallTiles 0 - @raster = new THREE.Mesh geom, rasterMat @raster.translateX -0.5 @raster.translateY -0.5 @raster.translateZ -0.5 world.scene.add @raster + + geom = @wallTiles @gap + @cage = new THREE.Mesh geom, cageMat + @cage.translateX -0.5 + @cage.translateY -0.5 + @cage.translateZ -0.5 + world.scene.add @cage del: -> world.scene.remove @raster @@ -52,7 +50,7 @@ class Cage s = 1-raster o = raster i = -1 - offset = raster/10 + offset = raster/20 z = offset n = 1 diff --git a/coffee/event.coffee b/coffee/event.coffee index dacf795..5e90a2d 100644 --- a/coffee/event.coffee +++ b/coffee/event.coffee @@ -50,6 +50,7 @@ class Event removeAction: (action) -> action.event = null + action.reset() _.pull @actions, action _.pull @save_actions, action _.pull @finished_actions, action diff --git a/coffee/levels/steps.coffee b/coffee/levels/steps.coffee index e755f60..2529200 100644 --- a/coffee/levels/steps.coffee +++ b/coffee/levels/steps.coffee @@ -30,8 +30,8 @@ module.exports = ] create: -> - world.addObjectAtPos('KikiWall', world.decenter(0,0,3)) - world.addObjectAtPos('KikiWall', world.decenter(0,-1,1)) - world.addObjectAtPos('KikiWall', world.decenter(0,-2,-1)) - world.addObjectAtPos('KikiWall', world.decenter(0,-3,-3)) + world.addObjectAtPos 'KikiWall', world.decenter 0,0,3 + world.addObjectAtPos 'KikiWall', world.decenter 0,-1,1 + world.addObjectAtPos 'KikiWall', world.decenter 0,-2,-1 + world.addObjectAtPos 'KikiWall', world.decenter 0,-3,-3 \ No newline at end of file diff --git a/coffee/player.coffee b/coffee/player.coffee index 049329d..bab352e 100644 --- a/coffee/player.coffee +++ b/coffee/player.coffee @@ -153,100 +153,89 @@ class Player extends Bot getFollowProjection: () -> - cameraPos = @projection.getPosition() + camPos = @projection.getPosition() desiredDistance = 2.0 # desired distance from camera to bot - playerPos = @current_position # desired look pos + playerPos = @current_position playerDir = @getCurrentDir() - playerUp = @current_orientation.rotate new Vector(0,1,0).normal() - playerRight = playerDir.cross(playerUp).normal() + playerUp = @getCurrentUp() + playerLeft = @getCurrentLeft() - # ____________________________________________________ camera follows bot # first, adjust distance from camera to bot - botToCamera = cameraPos.minus playerPos # vector from bot to current pos + botToCamera = camPos.minus playerPos # vector from bot to current pos cameraBotDistance = botToCamera.length() # distance from camera to bot - # log 'getFollowProjection 1', botToCamera, cameraPos, playerPos - if cameraBotDistance >= desiredDistance difference = cameraBotDistance - desiredDistance - delta = difference*difference/400.0 # weight for following speed - cameraPos = cameraPos.mul(1.0-delta).plus playerPos.mul delta + delta = difference*difference/400.0 # weight for following speed + camPos = camPos.mul(1.0-delta).plus playerPos.mul delta else difference = desiredDistance - cameraBotDistance - delta = difference/20.0 # weight for negative following speed - cameraPos = cameraPos.mul(1.0-delta).plus (playerPos.plus botToCamera.normal().mul desiredDistance).mul delta + delta = difference/20.0 # weight for negative following speed + camPos = camPos.mul(1.0-delta).plus (playerPos.plus botToCamera.normal().mul desiredDistance).mul delta - # log 'getFollowProjection 2', botToCamera, cameraPos, playerPos - - # ____________________________________________________ refining camera position # second, rotate around bot - botToCamera = cameraPos.minus playerPos + botToCamera = camPos.minus playerPos botToCameraNormal = botToCamera.normal() - - # ____________________________________________________ try view bot from above + # if camera below bot, rotate up if botToCameraNormal.dot(playerUp) < 0 # calculate angle between player to camera vector and player up vector - verticalAngle = Vector.RAD2DEG Math.acos(clamp(-1.0, 1.0, botToCameraNormal.dot playerUp)) - 90.0 - cameraPos = playerPos.plus Quaternion.rotationAroundVector(verticalAngle/40.0, botToCameraNormal.cross(playerUp)).rotate botToCamera - - botToCamera = cameraPos.minus playerPos + verticalAngle = Vector.RAD2DEG Math.acos(clamp(-1.0, 1.0, botToCameraNormal.dot playerUp)) + log "verticalAngle #{verticalAngle}" + rotQuat = Quaternion.rotationAroundVector(verticalAngle/40.0, botToCameraNormal.cross(playerUp)) + botToCamera = rotQuat.rotate botToCamera botToCameraNormal = botToCamera.normal() + camPos = playerPos.plus botToCamera - # log 'getFollowProjection 3', botToCamera, cameraPos, playerPos - rotFactor = 1.0 - wall_distance = world.getWallDistanceForPos playerPos.plus botToCamera - if wall_distance < 0.5 - # ____________________________________________________ piercing walls + wall_distance = world.getWallDistanceForPos camPos + if wall_distance < 0.5 # try avoid piercing walls if wall_distance < 0.2 - cameraPos = world.getInsideWallPosWithDelta cameraPos, 0.2 - botToCamera = cameraPos.minus playerPos + camPos = world.getInsideWallPosWithDelta camPos, 0.2 + botToCamera = camPos.minus playerPos botToCameraNormal = botToCamera.normal() - rotFactor = 0.5 / (wall_distance-0.2) - - # ____________________________________________________ try view bot from behind + log "rotFactor #{rotFactor}" + + # try view bot from behind # calculate horizontal angle between bot orientation and vector to camera mappedToXZ = (botToCamera.minus playerUp.mul(botToCamera.dot playerUp)).normal() horizontalAngle = Vector.RAD2DEG Math.acos(clamp(-1.0, 1.0, -playerDir.dot mappedToXZ)) - if botToCameraNormal.dot(playerRight) > 0 + if botToCameraNormal.dot(playerLeft) < 0 horizontalAngle = -horizontalAngle - - cameraPos = playerPos.plus Quaternion.rotationAroundVector(horizontalAngle/(rotFactor*400.0), playerUp).rotate botToCamera - - botToCamera = cameraPos.minus playerPos + log "horizontalAngle #{horizontalAngle}" + rotQuat = Quaternion.rotationAroundVector horizontalAngle/(rotFactor*400.0), playerUp + camPos = playerPos.plus rotQuat.rotate botToCamera + + botToCamera = camPos.minus playerPos botToCameraNormal = botToCamera.normal() - # ____________________________________________________ finally, set the position + # finally, set the position - @projection.setPosition cameraPos - # log 'cameraPos:', cameraPos - # ____________________________________________________ refining camera orientation + @projection.setPosition camPos # slowly adjust look direction by interpolating current and desired directions - lookDelta = 2.0 - @projection.getZVector().dot botToCameraNormal + lookDelta = @projection.getZVector().dot botToCameraNormal lookDelta *= lookDelta / 30.0 - # newLookVector = @projection.getZVector().mul(1.0-lookDelta).plus botToCameraNormal.mul(lookDelta) newLookVector = @projection.getZVector().mul(1.0-lookDelta).plus botToCameraNormal.neg().mul(lookDelta) newLookVector.normalize() # slowly adjust up vector by interpolating current and desired up vectors - upDelta = 2.0 - @projection.getYVector().dot playerUp + upDelta = @projection.getYVector().dot playerUp upDelta *= upDelta / 100.0 - newRightVector = (@projection.getYVector().mul(1.0-upDelta).plus playerUp.mul(upDelta)).cross newLookVector - newRightVector.normalize() - newUpVector = newLookVector.cross(newRightVector).normal() + newUpVector = @projection.getYVector().mul(1.0-upDelta).plus playerUp.mul(upDelta) + newUpVector.normalize() + + newLeftVector = newUpVector.cross newLookVector # finished interpolations, update camera matrix - @projection.setZVector newLookVector - @projection.setXVector newRightVector + @projection.setXVector newLeftVector @projection.setYVector newUpVector - # log 'Player.getFollowProjection', @projection.getPosition() + @projection.setZVector newLookVector @projection # 0000000 0000000 000000000 000 0000000 000 000 @@ -349,6 +338,14 @@ class Player extends Bot @new_dir_sgn = @dir_sgn = (combo == @key.backward) and -1 or 1 @moveBot() # perform new move action (depending on environment) else + if @move_action.name == 'jump' and @move_action.getRelativeTime() < 1 + if world.isUnoccupiedPos(@position.plus(@getUp()).plus(@getDir())) and + world.isUnoccupiedPos(@position.plus(@getDir())) # forward and above forward also empty + action = @getActionWithId Action.JUMP_FORWARD + action.takeOver @move_action + Timer.removeAction @move_action + @move_action = action + Timer.addAction @move_action @new_dir_sgn = (combo == @key.backward) and -1 or 1 return true @@ -365,6 +362,23 @@ class Player extends Bot when @key.jump @jump = true # switch to jump mode until jump_key released @jump_once = true + if not @move_action? + @moveBot() # perform new move action (depending on environment) + @jump_once = false + else + if @move_action.name == 'move forward' and @move_action.getRelativeTime() < 0.6 or + @move_action.name == 'climb down' and @move_action.getRelativeTime() < 0.4 + if world.isUnoccupiedPos @position.plus @getUp() + if world.isUnoccupiedPos @position.plus @getUp().plus @getDir() + action = @getActionWithId Action.JUMP_FORWARD + else + action = @getActionWithId Action.JUMP + action.takeOver @move_action + Timer.removeAction @move_action + @move_action = action + Timer.addAction @move_action + else + log "cant jump #{@move_action.name}" return true when @key.push diff --git a/coffee/pushable.coffee b/coffee/pushable.coffee index d69f6be..b9620ba 100644 --- a/coffee/pushable.coffee +++ b/coffee/pushable.coffee @@ -14,7 +14,7 @@ class Pushable extends Item constructor: () -> super @pusher = null - @direction = new Vector() + @direction = new Vector @addAction new Action @, Action.NOOP, "noop" @addAction new Action @, Action.PUSH, "push" @@ -34,21 +34,22 @@ class Pushable extends Item initAction: (action) -> switch action.id when Action.FALL - log 'fall!' + log 'Pushable.initAction FALL direction:', @direction world.objectWillMoveToPos @, @position.plus(@direction), action.getDuration() performAction: (action) -> + # log "Pushable.performAction action #{action.name}" switch action.id when Action.PUSH, Action.FALL @setCurrentPosition @position.plus @direction.mul action.getRelativeTime() finishAction: (action) -> - log "Pushable.finishAction #{action.name}" + # log "Pushable.finishAction #{action.name}" switch action.id when Action.PUSH, Action.FALL @move_action = null world.objectMovedFromPos @, @position - log "Pushable.finishAction setPosition #{@current_position}" + # log "Pushable.finishAction setPosition #{@current_position}" @setPosition @current_position actionFinished: (action) -> @@ -57,17 +58,17 @@ class Pushable extends Item if action.id == Action.PUSH if @pusher instanceof Bot - gravityDir = pusher.getDown() - else if pusher instanceof Bomb + gravityDir = @pusher.getDown() + else if @pusher instanceof Bomb if @ instanceof Bot - if @direction == @getUp() + if @direction.eql @getUp() # bots don't fall through bomb splitter @direction.reset() return else gravityDir = @getDown() # bots pushed by bombs fall down else - direction.reset() + @direction.reset() return # objects pushed by bombs don't fall if world.isUnoccupiedPos @position.plus gravityDir @@ -76,6 +77,6 @@ class Pushable extends Item Timer.addAction @move_action else @direction.reset() - world.playSound @landing_sound, position + world.playSound @landing_sound, @position module.exports = Pushable diff --git a/coffee/timer.coffee b/coffee/timer.coffee index c0535f6..9cdaca4 100644 --- a/coffee/timer.coffee +++ b/coffee/timer.coffee @@ -26,6 +26,7 @@ class Timer @removeAction: (a) -> log "Timer.removeAction #{a.name}" + a.reset() @event.removeAction a module.exports = Timer diff --git a/coffee/world.coffee b/coffee/world.coffee index 248eddf..2a71556 100644 --- a/coffee/world.coffee +++ b/coffee/world.coffee @@ -47,7 +47,7 @@ class World extends Actor constructor: (@view) -> - @speed = 6 + @speed = 4 @raster_size = 0.05 # @camera_mode = World.CAMERA_INSIDE @camera_mode = World.CAMERA_BEHIND @@ -130,37 +130,36 @@ class World extends Actor # 0000000 00000000 0 00000000 0000000 0000000 @levelList = [ - # intro - "start", - # "steps", - #"move", "electro", "elevate", - # "throw", - # easy - "gold", "jump", "escape", "gears", - # "gamma", - "cube", "switch", "borg", - "mini", - # "blocks", - "bombs", "sandbox", "energy", "maze", "love", - # medium - "towers", "edge", "random", "plate", "nice", "entropy", - # owen hay's levels (TODO: sort in) - "grasp", "fallen", "cheese", "invisimaze", "spiral", - # difficult - "slick", "bridge", "flower", "stones", "walls", "grid", - "rings", - # "core", - "bronze", "pool", - # tough - "hidden", "church", - # "strange", - "mesh", "columns", "machine", - # very hard - # "neutron", - "captured", "circuit", "regal", "conductor", "evil", - # outro - "mutants", - ] + # intro + # "start", + "steps", + #"move", "electro", "elevate", + # "throw", + # easy + "gold", "jump", "escape", "gears", + # "gamma", + "cube", "switch", "borg", + "mini", + # "blocks", + "bombs", "sandbox", "energy", "maze", "love", + # medium + "towers", "edge", "random", "plate", "nice", "entropy", + # owen hay's levels (TODO: sort in) + "grasp", "fallen", "cheese", "invisimaze", "spiral", + # difficult + "slick", "bridge", "flower", "stones", "walls", "grid", + "rings", + # "core", + "bronze", "pool", + # tough + "hidden", "church", + # "strange", + "mesh", "columns", "machine", + # very hard + # "neutron", + "captured", "circuit", "regal", "conductor", "evil", + # outro + "mutants"] # import the levels for levelName in @levelList @@ -719,17 +718,18 @@ class World extends Actor else log "world.objectWillMoveToPos [WARNING] already occupied:", pos - @unsetObject object # remove object from cell grid - # log 'tmpObject at new pos', pos - tmpObject = new TmpObject object # insert tmp object at new pos - tmpObject.setPosition pos - tmpObject.time = duration - @addObjectAtPos tmpObject, pos - # log 'tmpObject at old pos', object.position - tmpObject = new TmpObject object # insert tmp object at old pos - tmpObject.setPosition object.position - tmpObject.time = -duration - @addObjectAtPos tmpObject, object.getPos() + if object != @player + @unsetObject object # remove object from cell grid + # log 'tmpObject at new pos', pos + tmpObject = new TmpObject object # insert tmp object at new pos + tmpObject.setPosition pos + tmpObject.time = duration + @addObjectAtPos tmpObject, pos + # log 'tmpObject at old pos', object.position + tmpObject = new TmpObject object # insert tmp object at old pos + tmpObject.setPosition object.position + tmpObject.time = -duration + @addObjectAtPos tmpObject, object.getPos() updateStatus: () -> @@ -807,9 +807,6 @@ class World extends Actor # log "unmapMsTime #{mapped} #{@speed} #{parseInt mapped * @speed/10.0}" parseInt mapped * @speed/10.0 - getRelativeTime: -> @frame_time % (10000/@speed)/(10000.0/@speed) - getRelativeDelta: -> (@frame_time - @last_time)/(10000.0/@speed) - continuous: (cb) -> new Action func: cb