From 9fc36398b5f7a200ef49d1258e428710b2ba08f5 Mon Sep 17 00:00:00 2001 From: monsterkodi Date: Sun, 14 Aug 2016 01:11:09 +0200 Subject: [PATCH] bullet --- coffee/action.coffee | 9 +- coffee/bot.coffee | 112 +++++++++++----------- coffee/bullet.coffee | 86 +++++++++++++++++ coffee/item.coffee | 2 + coffee/main.coffee | 7 +- coffee/player.coffee | 215 +++++++++++++++---------------------------- coffee/world.coffee | 2 +- 7 files changed, 228 insertions(+), 205 deletions(-) create mode 100644 coffee/bullet.coffee diff --git a/coffee/action.coffee b/coffee/action.coffee index 8dc3b8c..1ef03b8 100644 --- a/coffee/action.coffee +++ b/coffee/action.coffee @@ -11,6 +11,8 @@ class Action @NOOP = 0 @PUSH = 1 + @EXPLODE = 1 + @FLY = 2 @FALL = 2 @FORWARD = 3 @CLIMB_UP = 4 @@ -21,10 +23,9 @@ class Action @JUMP_FORWARD = 9 @FALL_FORWARD = 10 @SHOOT = 11 - @END = 12 - @LOOK_UP = 13 - @LOOK_DOWN = 14 - @LOOK_RESET = 15 + @LOOK_UP = 12 + @LOOK_DOWN = 13 + @LOOK_RESET = 14 @ONCE = 0 @CONTINUOUS = 1 diff --git a/coffee/bot.coffee b/coffee/bot.coffee index 17fb2bf..5574e88 100644 --- a/coffee/bot.coffee +++ b/coffee/bot.coffee @@ -4,20 +4,19 @@ # 000 000 000 000 000 # 0000000 0000000 000 -log = require '/Users/kodi/s/ko/js/tools/log' -Pushable = require './pushable' -Action = require './action' -Timer = require './timer' -Pos = require './lib/pos' -Vector = require './lib/vector' +log = require '/Users/kodi/s/ko/js/tools/log' +Pushable = require './pushable' +Action = require './action' +Timer = require './timer' +Bullet = require './bullet' +Pos = require './lib/pos' +Vector = require './lib/vector' Quaternion = require './lib/quaternion' class Bot extends Pushable constructor: () -> - - super - + @direction = new Quaternion @orientation = new Quaternion @current_orientation = new Quaternion @@ -29,18 +28,17 @@ class Bot extends Pushable geom = new THREE.SphereGeometry 0.5, 32, 32 mat = new THREE.MeshPhongMaterial - color: 0x222288 + color: 0x222266 side: THREE.FrontSide shading: THREE.SmoothShading transparent: true opacity: 0.9 shininess: 0.99 @mesh = new THREE.Mesh geom, mat - world.scene.add @mesh geom = new THREE.TorusGeometry 0.5, tireRadius, 16, 16 mat = new THREE.MeshPhongMaterial - color: 0x000044 + color: 0x111155 side: THREE.FrontSide shading: THREE.SmoothShading transparent: true @@ -78,6 +76,8 @@ class Bot extends Pushable @dir_sgn = 1.0 + super + @addAction new Action @, Action.NOOP, "noop", 0 @addAction new Action @, Action.FORWARD, "move forward", 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 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 - super action - return - - if actionId == Action.TURN_LEFT or actionId == Action.TURN_RIGHT - @rotate_action = null - - if @move_action # bot currently performing a move action -> store rotation in @rest_orientation - @rest_orientation = @rest_orientation.mul @rotate_orientation - @rotate_orientation.reset() - else - @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 + switch action.id + when Action.NOOP, Action.SHOOT + return + when Action.PUSH + super action + return + when Action.TURN_LEFT or Action.TURN_RIGHT + @rotate_action = null + if @move_action # bot currently performing a move action -> store rotation in @rest_orientation + @rest_orientation = @rest_orientation.mul @rotate_orientation + @rotate_orientation.reset() 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 + @orientation = @orientation.mul @rotate_orientation.mul @rest_orientation # update rotation matrix + @rotate_orientation.reset() + @rest_orientation.reset() + return + + return if action.id > Action.SHOOT - if actionId != Action.CLIMB_UP - world.objectMovedFromPos @, @position # update world @position - @position = @current_position.round() - - if actionId != Action.JUMP_FORWARD and @rotate_action == null # if not jumping forward - @orientation = @orientation.mul @rest_orientation # update rotation @orientation - @rest_orientation.reset() + @move_action = null + + @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 # 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 actionFinished: (action) -> - actionId = action.id - log "bot.actionFinished #{action.name} #{actionId}" + log "bot.actionFinished #{action.name} #{action.id}" # if @isDead() # log "DIE!" @@ -359,7 +359,7 @@ class Bot extends Pushable @startTimedAction @getActionWithId(Action.NOOP), 0 return - if actionId == Action.PUSH or not @direction.isZero() + if action.id == Action.PUSH or not @direction.isZero() log 'super action!' super action return @@ -369,7 +369,7 @@ class Bot extends Pushable return # 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() log 'jump forwardPos', forwardPos if world.isUnoccupiedPos forwardPos @@ -405,7 +405,7 @@ class Bot extends Pushable @move_action = @getActionWithId Action.FALL @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!' if @ == world.player world.playSound 'BOT_LAND' @@ -424,7 +424,7 @@ class Bot extends Pushable @moveBot() else @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 # @startTimedAction @getActionWithId(Action.NOOP), 0 diff --git a/coffee/bullet.coffee b/coffee/bullet.coffee new file mode 100644 index 0000000..f7aeacb --- /dev/null +++ b/coffee/bullet.coffee @@ -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 diff --git a/coffee/item.coffee b/coffee/item.coffee index 52daeef..25245e1 100644 --- a/coffee/item.coffee +++ b/coffee/item.coffee @@ -15,12 +15,14 @@ class Item extends Actor constructor: -> super + world.scene.add @mesh if @mesh? @position = new Vector @current_position = new Vector @direction = new Vector @move_action = null del: -> + world.scene.remove @mesh if @mesh? world.removeObject @ @emit 'deleted' diff --git a/coffee/main.coffee b/coffee/main.coffee index cd0d510..28e3fa7 100644 --- a/coffee/main.coffee +++ b/coffee/main.coffee @@ -50,10 +50,7 @@ class Kiki extends Stage resized: (w,h) -> @world.resized w, h - modKeyComboEventDown: (mod, key, combo, event) -> - world.modKeyComboEventDown mod, key, combo, event - - modKeyComboEventUp: (mod, key, combo, event) -> - world.modKeyComboEventUp mod, key, combo, event + modKeyComboEventDown: (mod, key, combo, event) -> world.modKeyComboEventDown mod, key, combo, event + modKeyComboEventUp: (mod, key, combo, event) -> world.modKeyComboEventUp mod, key, combo, event module.exports = Kiki diff --git a/coffee/player.coffee b/coffee/player.coffee index ade2676..cad63c7 100644 --- a/coffee/player.coffee +++ b/coffee/player.coffee @@ -38,7 +38,7 @@ class Player extends Bot lookUp: 'up' lookDown: 'down' shoot: 'space' - jump: 'command' + jump: 'j' view: 'v' @look_action = null @@ -62,43 +62,7 @@ class Player extends Bot # @projection.getLight().setCutoff 90.0 # @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: () -> if @move_action relTime = (world.getTime() - @move_action.start) / @move_action.duration @@ -365,14 +329,12 @@ class Player extends Bot Timer.addAction @rotate_action die: () -> - # Controller.removeKeyHandler @ super # Controller.displayText "game over" world.playSound 'BOT_DEATH' world.setCameraMode world.CAMERA_FOLLOW reborn: () -> - # Controller.addKeyHandler @ @died = false reset: () -> @@ -384,20 +346,6 @@ class Player extends Bot @new_dir_sgn = 1.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 000 000 000 # 0000000 0000000 00000 @@ -406,56 +354,48 @@ class Player extends Bot modKeyComboEventDown: (mod, key, combo, event) -> # log "player.modKeyComboEventDown mod:#{mod} key:#{key} combo:#{combo}" - keyHandled = -> - # @recorder?.recordKey combo - true - if combo == @key.forward or combo == @key.backward - # log 'move!' - @move = true # try to move as long as the key is not released + switch combo + when @key.forward, @key.backward + @move = true # try to move as long as the key is not released + if not @move_action? + @new_dir_sgn = @dir_sgn = (combo == @key.backward) and -1 or 1 + @moveBot() # perform new move action (depending on environment) + else + @new_dir_sgn = (combo == @key.backward) and -1 or 1 + return true + + when @key.left, @key.right + @rotate = (combo == @key.left) and Action.TURN_LEFT or Action.TURN_RIGHT + if not @rotate_action? and not @spiked # player is not performing a rotation and unspiked + @rotate_action = @getActionWithId @rotate + Timer.addAction @rotate_action + return true - if @move_action == null # player is currently not performing a move action - # forward or backward direction - @new_dir_sgn = @dir_sgn = (combo == @key.backward) and -1 or 1 - @moveBot() # perform new move action (depending on environment) - else - @new_dir_sgn = (combo == @key.backward) and -1 or 1 + when @key.jump + @jump = true # switch to jump mode until jump_key released + @jump_once = true + return true - return keyHandled() - - if combo == @key.left or combo == @key.right - @rotate = (combo == @key.left) and Action.TURN_LEFT or Action.TURN_RIGHT + when @key.push + @push = true + return true - if @rotate_action == null and not @spiked # player is not performing a rotation and unspiked - @rotate_action = @getActionWithId @rotate - Timer.addAction @rotate_action + when @key.shoot + if not @shoot + @shoot = true + Timer.addAction @getActionWithId Action.SHOOT + return true - return keyHandled() - - if combo == @key.jump - @jump = true # switch to jump mode until jump_key released - @jump_once = 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() + 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 + + when @key.view + world.changeCameraMode() + return true false @@ -467,46 +407,43 @@ class Player extends Bot modKeyComboEventUp: (mod, key, combo, event) -> # log "player.modKeyComboEventUp mod:#{mod} key:#{key} combo:#{combo}" - releaseHandled = -> - # @recorder?.recordKeyRelease combo - true + switch combo + when @key.shoot + Timer.removeAction @getActionWithId Action.SHOOT + @shoot = false + return true - if combo == @key.shoot - Timer.removeAction @getActionWithId Action.SHOOT - @shoot = false - return releaseHandled() - - if combo == @key.forward or combo == @key.backward - @move = false - return releaseHandled() - - if key.name == @key.jump - @jump = false - if @jump_once - 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 - @rotate = 0 - return releaseHandled() - - if key.name == @key.push - @push = false - return releaseHandled() - - if combo == @key.lookDown or combo == @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 releaseHandled() - - if combo == @key.view - return releaseHandled() + when @key.forward, @key.backward + @move = false + return true + + when @key.jump + @jump = false + 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() + + when @key.left, @key.right + @rotate = 0 + return true + + when @key.push + @push = false + return releaseHandled() + + 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 diff --git a/coffee/world.coffee b/coffee/world.coffee index 8d5b69f..06a63ad 100644 --- a/coffee/world.coffee +++ b/coffee/world.coffee @@ -745,7 +745,7 @@ class World extends Actor Timer.event.triggerActions() Timer.event.finishActions() - @player.step step + o.step?(step) for o in @objects @display() @sun.position.copy @camera.position @renderer.render @scene, @camera