252 lines
10 KiB
CoffeeScript
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
|