This commit is contained in:
monsterkodi 2016-08-15 01:08:47 +02:00
parent 910ba6d2fa
commit 24af8b6cce
9 changed files with 219 additions and 199 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -50,6 +50,7 @@ class Event
removeAction: (action) ->
action.event = null
action.reset()
_.pull @actions, action
_.pull @save_actions, action
_.pull @finished_actions, action

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -26,6 +26,7 @@ class Timer
@removeAction: (a) ->
log "Timer.removeAction #{a.name}"
a.reset()
@event.removeAction a
module.exports = Timer

View File

@ -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