This commit is contained in:
monsterkodi 2016-08-14 01:11:09 +02:00
parent 6b977041d0
commit 9fc36398b5
7 changed files with 228 additions and 205 deletions

View File

@ -11,6 +11,8 @@ class Action
@NOOP = 0 @NOOP = 0
@PUSH = 1 @PUSH = 1
@EXPLODE = 1
@FLY = 2
@FALL = 2 @FALL = 2
@FORWARD = 3 @FORWARD = 3
@CLIMB_UP = 4 @CLIMB_UP = 4
@ -21,10 +23,9 @@ class Action
@JUMP_FORWARD = 9 @JUMP_FORWARD = 9
@FALL_FORWARD = 10 @FALL_FORWARD = 10
@SHOOT = 11 @SHOOT = 11
@END = 12 @LOOK_UP = 12
@LOOK_UP = 13 @LOOK_DOWN = 13
@LOOK_DOWN = 14 @LOOK_RESET = 14
@LOOK_RESET = 15
@ONCE = 0 @ONCE = 0
@CONTINUOUS = 1 @CONTINUOUS = 1

View File

@ -4,20 +4,19 @@
# 000 000 000 000 000 # 000 000 000 000 000
# 0000000 0000000 000 # 0000000 0000000 000
log = require '/Users/kodi/s/ko/js/tools/log' log = require '/Users/kodi/s/ko/js/tools/log'
Pushable = require './pushable' Pushable = require './pushable'
Action = require './action' Action = require './action'
Timer = require './timer' Timer = require './timer'
Pos = require './lib/pos' Bullet = require './bullet'
Vector = require './lib/vector' Pos = require './lib/pos'
Vector = require './lib/vector'
Quaternion = require './lib/quaternion' Quaternion = require './lib/quaternion'
class Bot extends Pushable class Bot extends Pushable
constructor: () -> constructor: () ->
super
@direction = new Quaternion @direction = new Quaternion
@orientation = new Quaternion @orientation = new Quaternion
@current_orientation = new Quaternion @current_orientation = new Quaternion
@ -29,18 +28,17 @@ class Bot extends Pushable
geom = new THREE.SphereGeometry 0.5, 32, 32 geom = new THREE.SphereGeometry 0.5, 32, 32
mat = new THREE.MeshPhongMaterial mat = new THREE.MeshPhongMaterial
color: 0x222288 color: 0x222266
side: THREE.FrontSide side: THREE.FrontSide
shading: THREE.SmoothShading shading: THREE.SmoothShading
transparent: true transparent: true
opacity: 0.9 opacity: 0.9
shininess: 0.99 shininess: 0.99
@mesh = new THREE.Mesh geom, mat @mesh = new THREE.Mesh geom, mat
world.scene.add @mesh
geom = new THREE.TorusGeometry 0.5, tireRadius, 16, 16 geom = new THREE.TorusGeometry 0.5, tireRadius, 16, 16
mat = new THREE.MeshPhongMaterial mat = new THREE.MeshPhongMaterial
color: 0x000044 color: 0x111155
side: THREE.FrontSide side: THREE.FrontSide
shading: THREE.SmoothShading shading: THREE.SmoothShading
transparent: true transparent: true
@ -78,6 +76,8 @@ class Bot extends Pushable
@dir_sgn = 1.0 @dir_sgn = 1.0
super
@addAction new Action @, Action.NOOP, "noop", 0 @addAction new Action @, Action.NOOP, "noop", 0
@addAction new Action @, Action.FORWARD, "move forward", 200 @addAction new Action @, Action.FORWARD, "move forward", 200
@addAction new Action @, Action.CLIMB_UP, "climb up", 200 @addAction new Action @, Action.CLIMB_UP, "climb up", 200
@ -293,48 +293,49 @@ class Bot extends Pushable
# 000 000 000 000 000 0000000 000 000 # 000 000 000 000 000 0000000 000 000
finishAction: (action) -> finishAction: (action) ->
actionId = action.id
return if actionId == Action.NOOP or actionId == Action.SHOOT # log "Bot.finishAction #{actionId} #{action.name}"
log "Bot.finishAction #{actionId} #{action.name}"
if actionId == Action.PUSH switch action.id
super action when Action.NOOP, Action.SHOOT
return return
when Action.PUSH
if actionId == Action.TURN_LEFT or actionId == Action.TURN_RIGHT super action
@rotate_action = null return
when Action.TURN_LEFT or Action.TURN_RIGHT
if @move_action # bot currently performing a move action -> store rotation in @rest_orientation @rotate_action = null
@rest_orientation = @rest_orientation.mul @rotate_orientation if @move_action # bot currently performing a move action -> store rotation in @rest_orientation
@rotate_orientation.reset() @rest_orientation = @rest_orientation.mul @rotate_orientation
else @rotate_orientation.reset()
@orientation = @orientation.mul @rotate_orientation.mul @rest_orientation # update rotation matrix
@rotate_orientation.reset()
@rest_orientation.reset()
else if actionId < Action.END
@move_action = null
@orientation = @orientation.mul @climb_orientation # update climb @orientation
@climb_orientation.reset()
if @rotate_action and actionId != Action.JUMP_FORWARD # bot is currently performing a rotation ->
# take over result of rotation to prevent sliding
if @rotate_action.id == Action.TURN_LEFT
@orientation = @orientation.mul Quaternion.rotationAroundVector(90.0, new Vector(0,1,0)).mul @rest_orientation
@rest_orientation = Quaternion.rotationAroundVector -90.0, new Vector 0,1,0
else else
@orientation = @orientation.mul Quaternion.rotationAroundVector(-90.0, new Vector(0,1,0)).mul @rest_orientation @orientation = @orientation.mul @rotate_orientation.mul @rest_orientation # update rotation matrix
@rest_orientation = Quaternion.rotationAroundVector 90.0, new Vector 0,1,0 @rotate_orientation.reset()
@rest_orientation.reset()
return
if actionId != Action.CLIMB_UP return if action.id > Action.SHOOT
world.objectMovedFromPos @, @position # update world @position
@position = @current_position.round()
if actionId != Action.JUMP_FORWARD and @rotate_action == null # if not jumping forward @move_action = null
@orientation = @orientation.mul @rest_orientation # update rotation @orientation
@rest_orientation.reset() @orientation = @orientation.mul @climb_orientation # update climb @orientation
@climb_orientation.reset()
if @rotate_action and action.id != Action.JUMP_FORWARD # bot is currently performing a rotation ->
# take over result of rotation to prevent sliding
if @rotate_action.id == Action.TURN_LEFT
@orientation = @orientation.mul Quaternion.rotationAroundVector(90.0, new Vector(0,1,0)).mul @rest_orientation
@rest_orientation = Quaternion.rotationAroundVector -90.0, new Vector 0,1,0
else
@orientation = @orientation.mul Quaternion.rotationAroundVector(-90.0, new Vector(0,1,0)).mul @rest_orientation
@rest_orientation = Quaternion.rotationAroundVector 90.0, new Vector 0,1,0
if action.id != Action.CLIMB_UP
world.objectMovedFromPos @, @position # update world @position
@position = @current_position.round()
if action.id != Action.JUMP_FORWARD and @rotate_action == null # if not jumping forward
@orientation = @orientation.mul @rest_orientation # update rotation @orientation
@rest_orientation.reset()
# 00000000 000 000 000 000 0000000 000 000 00000000 0000000 # 00000000 000 000 000 000 0000000 000 000 00000000 0000000
# 000 000 0000 000 000 000 000 000 000 000 000 # 000 000 0000 000 000 000 000 000 000 000 000
@ -343,8 +344,7 @@ class Bot extends Pushable
# 000 000 000 000 000 0000000 000 000 00000000 0000000 # 000 000 000 000 000 0000000 000 000 00000000 0000000
actionFinished: (action) -> actionFinished: (action) ->
actionId = action.id log "bot.actionFinished #{action.name} #{action.id}"
log "bot.actionFinished #{action.name} #{actionId}"
# if @isDead() # if @isDead()
# log "DIE!" # log "DIE!"
@ -359,7 +359,7 @@ class Bot extends Pushable
@startTimedAction @getActionWithId(Action.NOOP), 0 @startTimedAction @getActionWithId(Action.NOOP), 0
return return
if actionId == Action.PUSH or not @direction.isZero() if action.id == Action.PUSH or not @direction.isZero()
log 'super action!' log 'super action!'
super action super action
return return
@ -369,7 +369,7 @@ class Bot extends Pushable
return return
# find next action depending on type of finished action and surrounding environment # find next action depending on type of finished action and surrounding environment
if actionId == Action.JUMP_FORWARD if action.id == Action.JUMP_FORWARD
forwardPos = @position.plus @getDir() forwardPos = @position.plus @getDir()
log 'jump forwardPos', forwardPos log 'jump forwardPos', forwardPos
if world.isUnoccupiedPos forwardPos if world.isUnoccupiedPos forwardPos
@ -405,7 +405,7 @@ class Bot extends Pushable
@move_action = @getActionWithId Action.FALL @move_action = @getActionWithId Action.FALL
@move_action.takeRest action @move_action.takeRest action
else if actionId == Action.FALL or actionId == Action.FALL_FORWARD # landed else if action.id == Action.FALL or action.id == Action.FALL_FORWARD # landed
log 'fall|forward!' log 'fall|forward!'
if @ == world.player if @ == world.player
world.playSound 'BOT_LAND' world.playSound 'BOT_LAND'
@ -424,7 +424,7 @@ class Bot extends Pushable
@moveBot() @moveBot()
else else
@dir_sgn = 1 @dir_sgn = 1
@jump_once = false if actionId != Action.NOOP @jump_once = false if action.id != Action.NOOP
# keep action chain flowinwg in order to detect environment changes # keep action chain flowinwg in order to detect environment changes
# @startTimedAction @getActionWithId(Action.NOOP), 0 # @startTimedAction @getActionWithId(Action.NOOP), 0

86
coffee/bullet.coffee Normal file
View File

@ -0,0 +1,86 @@
# 0000000 000 000 000 000 00000000 000000000
# 000 000 000 000 000 000 000 000
# 0000000 000 000 000 000 0000000 000
# 000 000 000 000 000 000 000 000
# 0000000 0000000 0000000 0000000 00000000 000
log = require '/Users/kodi/s/ko/js/tools/log'
Item = require './item'
Action = require './action'
Timer = require './timer'
class Bullet extends Item
constructor: () ->
@size = 0.2
@src_object = null
geom = new THREE.SphereGeometry 1, 16, 16
mat = new THREE.MeshPhongMaterial
color: 0x222266
side: THREE.FrontSide
shading: THREE.SmoothShading
transparent: true
opacity: 0.9
shininess: 0.99
@mesh = new THREE.Mesh geom, mat
@mesh.scale.set @size, @size, @size
super
@addAction new Action @, Action.FLY, "fly", 40
@addAction new Action @, Action.EXPLODE, "explode", 200
@shootFromBot: (bot) ->
bullet = new Bullet()
world.addObject bullet
bullet.direction = bot.getCurrentDir()
bullet.setPosition bot.position.plus bullet.direction.mul 1/2.0
bullet.src_object = bot
log 'shootFromBot', bullet.direction, bullet.position
world.playSound 'BULLET_SHOT', bot.getPos()
return if bullet.hitObjectAtPos bullet.position.plus bullet.direction.mul 1/2.0
Timer.addAction bullet.getActionWithId Action.FLY
performAction: (action) ->
relTime = action.getRelativeTime()
if action.id == Action.FLY
@current_position = @position.plus @direction.mul relTime
else if action.id == Action.EXPLODE
@size = 0.2 + relTime/2.0
# color.setAlpha(0.8 * (1.0-relTime))
step: (step) ->
@mesh.position.copy @current_position
@mesh.scale.set @size, @size, @size
hitObjectAtPos: (pos) ->
if world.isInvalidPos(pos) or world.isOccupiedPos pos
hitObject = world.getRealOccupantAtPos pos
if hitObject != @src_object
if hitObject?
hitObject.bulletImpact()
if hitObject instanceof Mutant and not hitObject.isDead()
world.playSound 'BULLET_HIT_MUTANT', pos
else if hitObject == world.player
world.playSound 'BULLET_HIT_PLAYER', pos
else
world.playSound 'BULLET_HIT_OBJECT', pos
else
world.playSound 'BULLET_HIT_WALL', pos
Timer.addAction @getActionWithId Action.EXPLODE
return true
false
finishAction: (action) -> @position = @current_position if action.name == "fly"
actionFinished: (action) ->
if action.id == Action.FLY
if @hitObjectAtPos @position.plus @direction.mul 1/2.0
return
Timer.addAction @getActionWithId Action.FLY
else if action.id == Action.EXPLODE
world.deleteObject @
module.exports = Bullet

View File

@ -15,12 +15,14 @@ class Item extends Actor
constructor: -> constructor: ->
super super
world.scene.add @mesh if @mesh?
@position = new Vector @position = new Vector
@current_position = new Vector @current_position = new Vector
@direction = new Vector @direction = new Vector
@move_action = null @move_action = null
del: -> del: ->
world.scene.remove @mesh if @mesh?
world.removeObject @ world.removeObject @
@emit 'deleted' @emit 'deleted'

View File

@ -50,10 +50,7 @@ class Kiki extends Stage
resized: (w,h) -> @world.resized w, h resized: (w,h) -> @world.resized w, h
modKeyComboEventDown: (mod, key, combo, event) -> modKeyComboEventDown: (mod, key, combo, event) -> world.modKeyComboEventDown mod, key, combo, event
world.modKeyComboEventDown mod, key, combo, event modKeyComboEventUp: (mod, key, combo, event) -> world.modKeyComboEventUp mod, key, combo, event
modKeyComboEventUp: (mod, key, combo, event) ->
world.modKeyComboEventUp mod, key, combo, event
module.exports = Kiki module.exports = Kiki

View File

@ -38,7 +38,7 @@ class Player extends Bot
lookUp: 'up' lookUp: 'up'
lookDown: 'down' lookDown: 'down'
shoot: 'space' shoot: 'space'
jump: 'command' jump: 'j'
view: 'v' view: 'v'
@look_action = null @look_action = null
@ -63,42 +63,6 @@ class Player extends Bot
# @projection.getLight().setCutoff 90.0 # @projection.getLight().setCutoff 90.0
# @projection.getLight().setAttenuation 1.0, 0.0, 0.05 # @projection.getLight().setAttenuation 1.0, 0.0, 0.05
# getActionForKey: (keyName) ->
# index = 0
# while actionKeyMapping[index].actionName
# if keyName == actionKeyMapping[index].keyName
# return actionKeyMapping[index].actionName
# index += 1
# return ''
#
# getKeyForAction: (actionName) ->
# index = 0
# while actionKeyMapping[index].actionName
# if actionName == actionKeyMapping[index].actionName
# return actionKeyMapping[index].keyName
# index += 1
# return ''
#
# setKeyForAction: (keyName, actionName) ->
# index = 0
# while actionKeyMapping[index].actionName
# if actionName == actionKeyMapping[index].actionName
# actionKeyMapping[index].keyName = keyName
# index += 1
# recordKeyForAction: (actionName) ->
# RecordingActionName = actionName
# KeyRecorder.startRecordingSequence @, @setRecordedKey, 1
#
# setRecordedKey: (keyName) ->
# index = 0
# while actionKeyMapping[index].actionName
# if keyName == actionKeyMapping[index].keyName and actionKeyMapping[index].actionName != RecordingActionName
# setKeyForAction "", actionKeyMapping[index].actionName
# index += 1
# setKeyForAction keyName, RecordingActionName
# getEventWithName("keyset").triggerActions()
updatePosition: () -> updatePosition: () ->
if @move_action if @move_action
relTime = (world.getTime() - @move_action.start) / @move_action.duration relTime = (world.getTime() - @move_action.start) / @move_action.duration
@ -365,14 +329,12 @@ class Player extends Bot
Timer.addAction @rotate_action Timer.addAction @rotate_action
die: () -> die: () ->
# Controller.removeKeyHandler @
super super
# Controller.displayText "game over" # Controller.displayText "game over"
world.playSound 'BOT_DEATH' world.playSound 'BOT_DEATH'
world.setCameraMode world.CAMERA_FOLLOW world.setCameraMode world.CAMERA_FOLLOW
reborn: () -> reborn: () ->
# Controller.addKeyHandler @
@died = false @died = false
reset: () -> reset: () ->
@ -384,20 +346,6 @@ class Player extends Bot
@new_dir_sgn = 1.0 @new_dir_sgn = 1.0
@rotate = 0 @rotate = 0
# @recorder = null
# @playback = null
# saveRecorder: () ->
# if @recorder
# @recorder.save()
# @recorder = null
#
# startRecorder: (file) ->
# if @recorder
# saveRecorder()
# @recorder = new KikiRecorder file
# 000 000 00000000 000 000 # 000 000 00000000 000 000
# 000 000 000 000 000 # 000 000 000 000 000
# 0000000 0000000 00000 # 0000000 0000000 00000
@ -406,56 +354,48 @@ class Player extends Bot
modKeyComboEventDown: (mod, key, combo, event) -> modKeyComboEventDown: (mod, key, combo, event) ->
# log "player.modKeyComboEventDown mod:#{mod} key:#{key} combo:#{combo}" # log "player.modKeyComboEventDown mod:#{mod} key:#{key} combo:#{combo}"
keyHandled = -> switch combo
# @recorder?.recordKey combo when @key.forward, @key.backward
true @move = true # try to move as long as the key is not released
if combo == @key.forward or combo == @key.backward if not @move_action?
# log 'move!' @new_dir_sgn = @dir_sgn = (combo == @key.backward) and -1 or 1
@move = true # try to move as long as the key is not released @moveBot() # perform new move action (depending on environment)
else
@new_dir_sgn = (combo == @key.backward) and -1 or 1
return true
if @move_action == null # player is currently not performing a move action when @key.left, @key.right
# forward or backward direction @rotate = (combo == @key.left) and Action.TURN_LEFT or Action.TURN_RIGHT
@new_dir_sgn = @dir_sgn = (combo == @key.backward) and -1 or 1 if not @rotate_action? and not @spiked # player is not performing a rotation and unspiked
@moveBot() # perform new move action (depending on environment) @rotate_action = @getActionWithId @rotate
else Timer.addAction @rotate_action
@new_dir_sgn = (combo == @key.backward) and -1 or 1 return true
return keyHandled() when @key.jump
@jump = true # switch to jump mode until jump_key released
@jump_once = true
return true
if combo == @key.left or combo == @key.right when @key.push
@rotate = (combo == @key.left) and Action.TURN_LEFT or Action.TURN_RIGHT @push = true
return true
if @rotate_action == null and not @spiked # player is not performing a rotation and unspiked when @key.shoot
@rotate_action = @getActionWithId @rotate if not @shoot
Timer.addAction @rotate_action @shoot = true
Timer.addAction @getActionWithId Action.SHOOT
return true
return keyHandled() when @key.lookUp, @key.lookDown
if not @look_action
@look_action = @getActionWithId (combo == @key.lookUp) and Action.LOOK_UP or Action.LOOK_DOWN
@look_action.reset()
Timer.addAction @look_action
return true
if combo == @key.jump when @key.view
@jump = true # switch to jump mode until jump_key released world.changeCameraMode()
@jump_once = true return true
return keyHandled()
if combo == @key.push
@push = true
return keyHandled()
if combo == @key.shoot
if not @shoot
@shoot = true
Timer.addAction @getActionWithId Action.SHOOT
return keyHandled()
if combo == @key.lookUp or combo == @key.lookDown
if not @look_action
@look_action = @getActionWithId (combo == @key.lookUp) and Action.LOOK_UP or Action.LOOK_DOWN
@look_action.reset()
Timer.addAction @look_action
return keyHandled()
if combo == @key.view
world.changeCameraMode()
return keyHandled()
false false
@ -467,46 +407,43 @@ class Player extends Bot
modKeyComboEventUp: (mod, key, combo, event) -> modKeyComboEventUp: (mod, key, combo, event) ->
# log "player.modKeyComboEventUp mod:#{mod} key:#{key} combo:#{combo}" # log "player.modKeyComboEventUp mod:#{mod} key:#{key} combo:#{combo}"
releaseHandled = -> switch combo
# @recorder?.recordKeyRelease combo when @key.shoot
true Timer.removeAction @getActionWithId Action.SHOOT
@shoot = false
return true
if combo == @key.shoot when @key.forward, @key.backward
Timer.removeAction @getActionWithId Action.SHOOT @move = false
@shoot = false return true
return releaseHandled()
if combo == @key.forward or combo == @key.backward when @key.jump
@move = false @jump = false
return releaseHandled() if @jump_once
if not @move_action? and world.isUnoccupiedPos @position.plus @getUp()
@jump_once = false
@move_action = @getActionWithId Action.JUMP
world.playSound 'BOT_JUMP'
Timer.addAction @move_action
return releaseHandled()
if key.name == @key.jump when @key.left, @key.right
@jump = false @rotate = 0
if @jump_once return true
if @move_action == null and world.isUnoccupiedPos position.plus @getUp()
@jump_once = false
@move_action = @getActionWithId Action.JUMP
world.playSound 'BOT_JUMP'
Timer.addAction @move_action
return releaseHandled()
if combo == @key.left or combo == @key.right when @key.push
@rotate = 0 @push = false
return releaseHandled() return releaseHandled()
if key.name == @key.push when @key.lookDown, @key.lookUp
@push = false if @look_action and @look_action.id != Action.LOOK_RESET
return releaseHandled() Timer.removeAction @look_action
@look_action = @getActionWithId Action.LOOK_RESET
Timer.addAction @look_action
return true
if combo == @key.lookDown or combo == @key.lookUp when @key.view
if @look_action and @look_action.id != Action.LOOK_RESET return true
Timer.removeAction @look_action
@look_action = @getActionWithId Action.LOOK_RESET
Timer.addAction @look_action
return releaseHandled()
if combo == @key.view
return releaseHandled()
false false

View File

@ -745,7 +745,7 @@ class World extends Actor
Timer.event.triggerActions() Timer.event.triggerActions()
Timer.event.finishActions() Timer.event.finishActions()
@player.step step o.step?(step) for o in @objects
@display() @display()
@sun.position.copy @camera.position @sun.position.copy @camera.position
@renderer.render @scene, @camera @renderer.render @scene, @camera