kiki/coffee/player.coffee
monsterkodi 4f4d8556f0 levels
2016-08-25 01:26:09 +02:00

252 lines
10 KiB
CoffeeScript

# 00000000 000 0000000 000 000 00000000 00000000
# 000 000 000 000 000 000 000 000 000 000
# 00000000 000 000000000 00000 0000000 0000000
# 000 000 000 000 000 000 000 000
# 000 0000000 000 000 000 00000000 000 000
{
clamp
} = require '/Users/kodi/s/ko/js/tools/tools'
log = require '/Users/kodi/s/ko/js/tools/log'
Bot = require './bot'
Action = require './action'
Timer = require './timer'
Vector = require './lib/vector'
Camera = require './camera'
Quaternion = require './lib/quaternion'
class Player extends Bot
constructor: ->
super
@name = 'player'
@key =
forward: 'w'
backward: 's'
left: 'a'
right: 'd'
lookUp: 'up'
lookDown: 'down'
shoot: 'enter'
jump: 'space'
view: 'c'
push: 'shift'
@camera = new Camera @,
aspect: world.view.offsetWidth / world.view.offsetHeight
@look_action = null
@look_angle = 0.0
@new_dir_sgn = 1.0
@rotate = 0
@recorder = null
@playback = null
@addAction new Action @, Action.LOOK_UP, "look up", 220
@addAction new Action @, Action.LOOK_DOWN, "look down", 220
@addAction new Action @, Action.LOOK_RESET, "look reset", 60
@addEventWithName "landed"
bulletHitSound: -> 'BULLET_HIT_PLAYER'
# 0000000 0000000 000000000 000 0000000 000 000
# 000 000 000 000 000 000 000 0000 000
# 000000000 000 000 000 000 000 000 0 000
# 000 000 000 000 000 000 000 000 0000
# 000 000 0000000 000 000 0000000 000 000
initAction: (action) ->
# log "initAction #{action.id} #{action.name}"
switch action.id
when Action.CLIMB_DOWN
# @addMoves 1
world.playSound 'BOT_CLIMB'
when Action.FORWARD
# @addMoves 1
world.playSound 'BOT_MOVE'
when Action.TURN_LEFT, Action.TURN_RIGHT
world.playSound 'BOT_TURN'
when Action.JUMP
# @addMoves actionId == Action.JUMP and 1 or 2
world.playSound 'BOT_JUMP'
super action
# 00000000 00000000 00000000 00000000 0000000 00000000 00 00
# 000 000 000 000 000 000 000 000 000 000 000 000
# 00000000 0000000 0000000 000000 000 000 0000000 000000000
# 000 000 000 000 000 000 000 000 000 000 0 000
# 000 00000000 000 000 000 0000000 000 000 000 000
performAction: (action) ->
relTime = action.getRelativeTime()
switch action.id
when Action.NOOP then return
when Action.LOOK_UP then @look_angle = relTime * 90.0
when Action.LOOK_DOWN then @look_angle = relTime * -90.0
when Action.LOOK_RESET
if @look_angle > 0 then @look_angle = Math.min @look_angle, (1.0-relTime) * 90.0
else @look_angle = Math.max @look_angle, (1.0-relTime) * -90.0
else
super action
# 00000000 000 000 000 000 0000000 000 000
# 000 000 0000 000 000 000 000 000
# 000000 000 000 0 000 000 0000000 000000000
# 000 000 000 0000 000 000 000 000
# 000 000 000 000 000 0000000 000 000
finishAction: (action) ->
if action.id == Action.LOOK_RESET
@look_action = null
@look_angle = 0.0
else
if action.id == @move_action?.id # move finished, update direction
@dir_sgn = @new_dir_sgn
if action.id != Action.LOOK_UP and action.id != Action.LOOK_DOWN
super action
if action.id == Action.TURN_LEFT or action.id == Action.TURN_RIGHT
if @rotate
@rotate_action = @getActionWithId @rotate
@rotate_action.reset()
Timer.addAction @rotate_action
die: () ->
# 000 000 00000000 000 000
# 000 000 000 000 000
# 0000000 0000000 00000
# 000 000 000 000
# 000 000 00000000 000
modKeyComboEventDown: (mod, key, combo, event) ->
# log "player.modKeyComboEventDown mod:#{mod} key:#{key} combo:#{combo}"
switch key
when @key.forward, @key.backward
@push = mod == @key.push
@move = true # try to move as long as the key is not released
if not @move_action?
@new_dir_sgn = @dir_sgn = (key == @key.backward) and -1 or 1
@moveBot() # perform new move action (depending on environment)
else
if @move_action.id == Action.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 = (key == @key.backward) and -1 or 1
return true
when @key.left, @key.right
@rotate = (key == @key.left) and Action.TURN_LEFT or Action.TURN_RIGHT
if not @rotate_action? # player is not performing a rotation
@rotate_action = @getActionWithId @rotate
Timer.addAction @rotate_action
return true
when @key.jump
@jump = true # switch to jump mode until jump_key released
@jump_once = true
if not @move_action?
@moveBot() # perform jump action (depending on environment)
@jump_once = false
else
# log 'jump:moving'
if @move_action.id == Action.FORWARD and @move_action.getRelativeTime() < 0.6 or
@move_action.id == Action.CLIMB_DOWN and @move_action.getRelativeTime() < 0.4
# abort current move and jump instead
# log 'jump:move or climb down'
if world.isUnoccupiedPos @position.plus @getUp()
# log 'jump:can do'
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
@jump_once = false
Timer.addAction @move_action
else if @move_action.id in [Action.JUMP, Action.JUMP_FORWARD]
@jump_once = false
return true
when @key.push
@push = true
return true
when @key.shoot
if not @shoot
@shoot = true
Timer.addAction @getActionWithId Action.SHOOT
return true
when @key.lookUp, @key.lookDown
if not @look_action
@look_action = @getActionWithId (key == @key.lookUp) and Action.LOOK_UP or Action.LOOK_DOWN
@look_action.reset()
Timer.addAction @look_action
return true
when @key.view
world.changeCameraMode()
return true
false
# 00000000 00000000 000 00000000 0000000 0000000 00000000
# 000 000 000 000 000 000 000 000 000
# 0000000 0000000 000 0000000 000000000 0000000 0000000
# 000 000 000 000 000 000 000 000 000
# 000 000 00000000 0000000 00000000 000 000 0000000 00000000
modKeyComboEventUp: (mod, key, combo, event) ->
@push = false if @key.push == 'shift'
# log "player.modKeyComboEventUp mod:#{mod} key:#{key} combo:#{combo}"
switch key
when @key.shoot
Timer.removeAction @getActionWithId Action.SHOOT
@shoot = false
return true
when @key.forward, @key.backward
@move = false
return true
when @key.jump
@jump = false
return true
when @key.left, @key.right
@rotate = 0
return true
when @key.push
@push = false
return true
when @key.lookDown, @key.lookUp
if @look_action and @look_action.id != Action.LOOK_RESET
Timer.removeAction @look_action
@look_action = @getActionWithId Action.LOOK_RESET
Timer.addAction @look_action
return true
when @key.view
return true
false
module.exports = Player