From 1ce6de6d7e0e3a1ae246a1efa9b6a8fd5ee174d7 Mon Sep 17 00:00:00 2001 From: monsterkodi Date: Sat, 13 Aug 2016 15:20:23 +0200 Subject: [PATCH] bots --- coffee/action.coffee | 36 ++++++++-------- coffee/actor.coffee | 95 +++++++++++++++++++++++----------------- coffee/bot.coffee | 98 +++++++++++++++++++++--------------------- coffee/event.coffee | 35 ++++++++------- coffee/player.coffee | 21 ++++----- coffee/pushable.coffee | 20 ++++----- coffee/timer.coffee | 22 ++++++++-- coffee/world.coffee | 73 ++++++++++++++++++------------- 8 files changed, 225 insertions(+), 175 deletions(-) diff --git a/coffee/action.coffee b/coffee/action.coffee index 4805646..fb1e1ea 100644 --- a/coffee/action.coffee +++ b/coffee/action.coffee @@ -4,7 +4,8 @@ # 000 000 000 000 000 000 000 000 0000 # 000 000 0000000 000 000 0000000 000 000 -_ = require 'lodash' +log = require '/Users/kodi/s/ko/js/tools/log' +_ = require 'lodash' class Action @@ -21,18 +22,26 @@ class Action @FALL_FORWARD = 10 @SHOOT = 11 @END = 12 + @LOOK_UP = 13 + @LOOK_DOWN = 14 + @LOOK_RESET = 15 @ONCE = 0 @CONTINUOUS = 1 @REPEAT = 2 - constructor: (o, i, n, d, m) -> + constructor: (o, i, n, d, m) -> if _.isPlainObject o - i = o.id ? 0 + i = o.id ? -1 n = o.name d = o.duration ? 0 m = o.mode ? Action.ONCE o = o.func + else + i ?= -1 + m ?= Action.ONCE + d ?= 0 + log "newAction #{i} #{n} #{d} #{m}" @object = o @name = n @id = i @@ -87,11 +96,9 @@ class Action @current = @rest @rest = 0 - getRelativeTime: () -> - return @current / @getDuration() - - getDuration: () -> - return world.mapMsTime @duration + getRelativeTime: -> @current / @getDuration() + getRelativeDelta: -> (@current-@last) / @getDuration() + getDuration: -> world.mapMsTime @duration performWithEvent: (event) -> eventTime = event.getTime() @@ -101,15 +108,11 @@ class Action @current = 0 @rest = 0 @last = 0 - if @duration == 0 and @mode == Action.ONCE - event.removeAction @ - + event.removeAction @ if @duration == 0 and @mode == Action.ONCE @perform() - @last = @current - - if @duration == 0 and @mode == Action.ONCE - @finished() + @finished() if @duration == 0 and @mode == Action.ONCE + else currentDiff = eventTime - @start if currentDiff >= @getDuration() @@ -123,8 +126,7 @@ class Action if @mode == Action.CONTINUOUS @current = @rest return - if @mode == Action.ONCE - event.removeAction @ + event.removeAction @ if @mode == Action.ONCE @finish() diff --git a/coffee/actor.coffee b/coffee/actor.coffee index 44737a2..d0153b8 100644 --- a/coffee/actor.coffee +++ b/coffee/actor.coffee @@ -9,6 +9,7 @@ last } = require '/Users/kodi/s/ko/js/tools/tools' log = require '/Users/kodi/s/ko/js/tools/log' Action = require './action' +Timer = require './timer' Event = require './event' Emitter = require 'events' _ = require 'lodash' @@ -19,48 +20,13 @@ class Actor extends Emitter @actions = [] @events = [] super - - addAction: (action) -> - @actions.push action if not _.find @actions, action - del: -> @deleteActions() - - deleteActions: -> - last(@actions).del() while @actions.length - - initAction: -> - performAction: -> - finishAction: -> - actionFinished: -> - - stopAction: (action) -> - # Controller.timer_event.removeAction action - - startTimer: (duration, mode) -> - action = new Action @, 0, "timer", duration, mode - @actions.push action - # Controller.timer_event.addAction action - - startTimedAction: (action, duration) -> - action.duration = duration if duration >= 0 - # Controller.timer_event.addAction action - - removeAction: (action) -> - _.pull @actions, action - - getActionWithId: (actionId) -> - if actionId < @actions.length and @actions[actionId].id == actionId - return @actions[actionId] + # 00000000 000 000 00000000 000 000 000000000 + # 000 000 000 000 0000 000 000 + # 0000000 000 000 0000000 000 0 000 000 + # 000 000 000 000 0000 000 + # 00000000 0 00000000 000 000 000 - # to be deleted... - log "[WARNING] Actor.getActionWithId #{actionId} [#{@actions.length}]" - for a in @actions - return a if a.id == actionId - - getActionWithName: (name) -> - for a in @actions - return a if action.name = name - addEventWithName: (eventName) -> log "Actor.addEventWithName eventName:#{eventName}" if @getEventWithName eventName # to be removed @@ -75,5 +41,54 @@ class Actor extends Emitter getEventWithId: (eventId) -> return @events[eventId] + + # 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 + + addAction: (action) -> @actions[action.id] = action + + del: -> @deleteActions() + + deleteActions: -> last(@actions).del() while @actions.length + + removeAction: (action) -> _.pull @actions, action + + getActionWithId: (actionId) -> + if actionId < @actions.length and @actions[actionId].id == actionId + return @actions[actionId] + + # to be deleted... + log "[WARNING] Actor.getActionWithId #{actionId} [#{@actions.length}]", (a.id for a in @actions) + for a in @actions + return a if a.id == actionId + + getActionWithName: (name) -> + for a in @actions + return a if action.name = name + + initAction: -> + performAction: -> + finishAction: -> + actionFinished: -> + + # 000000000 000 00 00 00000000 00000000 + # 000 000 000 000 000 000 000 + # 000 000 000000000 0000000 0000000 + # 000 000 000 0 000 000 000 000 + # 000 000 000 000 00000000 000 000 + + stopAction: (action) -> Timer.removeAction action + + startTimer: (duration, mode) -> + action = new Action @, 0, "timer", duration, mode + @actions.push action + Timer.addAction action + + startTimedAction: (action, duration) -> + action.duration = duration if duration >= 0 + Timer.addAction action module.exports = Actor diff --git a/coffee/bot.coffee b/coffee/bot.coffee index 4f03ed0..23e6a25 100644 --- a/coffee/bot.coffee +++ b/coffee/bot.coffee @@ -8,6 +8,7 @@ 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' Quaternion = require './lib/quaternion' @@ -35,7 +36,6 @@ class Bot extends Pushable @mesh = new THREE.Mesh @geom, @mat world.scene.add @mesh - # @mesh.matrixAutoUpdate = true @left_tire_rot = 0.0 @right_tire_rot = 0.0 @@ -113,7 +113,8 @@ class Bot extends Pushable isFalling: -> @move_action and @move_action.id == Action.FALL initAction: (action) -> - newPos = new KikiPos @position + log "initAction #{action.name}" + newPos = new Pos @position switch action.id when Action.NOOP then return @@ -134,14 +135,16 @@ class Bot extends Pushable super action return - # if newPos != @position - # world.objectWillMoveToPos (@, newPos, action.getDuration()) + if newPos != @position + world.objectWillMoveToPos @, newPos, action.getDuration() performAction: (action) -> actionId = action.id relTime = action.getRelativeTime() dltTime = action.getRelativeDelta() + log "performAction #{action.name} #{relTime} #{dltTime} id #{actionId}" + switch actionId when Action.SHOOT if relTime == 0 @@ -151,27 +154,27 @@ class Bot extends Pushable when Action.FORWARD - @left_tire_rot += dir_sgn * dltTime - @right_tire_rot += dir_sgn * dltTime - @current_position = @position + relTime * @getDir() - + @left_tire_rot += @dir_sgn * dltTime + @right_tire_rot += @dir_sgn * dltTime + @current_position = @position.plus @getDir().mul relTime + log 'forward', @current_position return when Action.JUMP - @current_position = @position + Math.cos(Math.PI/2 - Math.PI/2 * relTime) * @getUp() + @current_position = @position.plus @getUp().mul Math.cos(Math.PI/2 - Math.PI/2 * relTime) 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 + (1.0 - Math.cos(Math.PI/2 * relTime)) * @getDir() + Math.cos(Math.PI/2 - Math.PI/2 * relTime) * @getUp() + @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) return when Action.FALL_FORWARD - @current_position = @position + Math.cos(Math.PI/2 - Math.PI/2 * relTime) * @getDir() + (1.0 - Math.cos(Math.PI/2 * relTime)) * @getDown() + @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)) return when Action.FALL @@ -179,28 +182,28 @@ class Bot extends Pushable if not @direction.isZero() super action return - @current_position = @position + relTime * @getDown() + @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, KVector(1,0,0)) + @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) break when Action.CLIMB_DOWN - @left_tire_rot += dir_sgn * dltTime - @right_tire_rot += dir_sgn * dltTime + @left_tire_rot += @dir_sgn * dltTime + @right_tire_rot += @dir_sgn * dltTime if relTime <= 0.2 - @current_position = @position + (relTime/0.2)/2 * @getDir() + @current_position = @position.plus @getDir().mul (relTime/0.2)/2 else if (relTime >= 0.8) - @climb_orientation = Quaternion.rotationAroundVector(dir_sgn * 90.0, KVector(1,0,0)) - @current_position = @position + @getDir() + (0.5+(relTime-0.8)/0.2/2) * @getDown() + @climb_orientation = Quaternion.rotationAroundVector @dir_sgn * 90.0, new Vector 1,0,0 + @current_position = @position.plus @getDir().plus @getDown().mul 0.5+(relTime-0.8)/0.2/2 else - @climb_orientation = Quaternion.rotationAroundVector(dir_sgn * (relTime-0.2)/0.6 * 90.0, KVector(1,0,0)) - rotVec = (orientation * @climb_orientation).rotate(KVector(0.0, 1.0, 0.0)) + @climb_orientation = Quaternion.rotationAroundVector @dir_sgn * (relTime-0.2)/0.6 * 90.0, new Vector 1,0,0 + rotVec = (orientation.mul @climb_orientation).rotate new Vector 0,1,0 @current_position = @position.plus @getDir().plus(@getDown()).plus(rotVec).mul 0.5 break @@ -209,20 +212,20 @@ class Bot extends Pushable if @move_action == null and relTime == 0.0 # if not performing move action and start of rotation # update @orientation now, so next move action will move in desired @direction if actionId == Action.TURN_LEFT - @orientation *= Quaternion.rotationAroundVector(90.0, KVector(0,1,0)) - @rest_orientation = Quaternion.rotationAroundVector(-90.0, KVector(0,1,0)) + @orientation *= Quaternion.rotationAroundVector 90.0, new Vector 0,1,0 + @rest_orientation = Quaternion.rotationAroundVector -90.0, new Vector 0,1,0 else - @orientation *= Quaternion.rotationAroundVector(-90.0, KVector(0,1,0)) - @rest_orientation = Quaternion.rotationAroundVector(90.0, KVector(0,1,0)) + @orientation *= Quaternion.rotationAroundVector -90.0, new Vector 0,1,0 + @rest_orientation = Quaternion.rotationAroundVector 90.0, new Vector 0,1,0 if actionId == Action.TURN_LEFT @left_tire_rot += -dltTime @right_tire_rot += dltTime - @rotate_orientation = Quaternion.rotationAroundVector(relTime * 90.0, KVector(0,1,0)) + @rotate_orientation = Quaternion.rotationAroundVector relTime * 90.0, new Vector 0,1,0 else @left_tire_rot += dltTime @right_tire_rot += -dltTime - @rotate_orientation = Quaternion.rotationAroundVector(relTime * -90.0, KVector(0,1,0)) + @rotate_orientation = Quaternion.rotationAroundVector relTime * -90.0, new Vector 0,1,0 break else @@ -230,8 +233,7 @@ class Bot extends Pushable super action return - @current_orientation = @orientation * @climb_orientation * @rotate_orientation * @rest_orientation - + @current_orientation = @orientation.mul @climb_orientation.mul @rotate_orientation.mul @rest_orientation finishAction: (action) -> actionId = action.id @@ -246,33 +248,33 @@ class Bot extends Pushable @rotate_action = null if move_action # bot currently performing a move action -> store rotation in @rest_orientation - @rest_orientation *= @rotate_orientation + @rest_orientation = @rest_orientation.mul @rotate_orientation @rotate_orientation.reset() else - @orientation *= @rotate_orientation * @rest_orientation # update rotation matrix + @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 *= @climb_orientation # update climb @orientation + @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 *= Quaternion.rotationAroundVector(90.0, KVector(0,1,0)) * @rest_orientation - @rest_orientation = Quaternion.rotationAroundVector(-90.0, KVector(0,1,0)) + @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 *= Quaternion.rotationAroundVector(-90.0, KVector(0,1,0)) * @rest_orientation - @rest_orientation = Quaternion.rotationAroundVector(90.0, KVector(0,1,0)) + @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 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 *= @rest_orientation # update rotation @orientation + @orientation = @orientation.mul @rest_orientation # update rotation @orientation @rest_orientation.reset() actionFinished: (action) -> @@ -285,7 +287,7 @@ class Bot extends Pushable # dead player may only fall, nothing else return - if spiked + if @spiked @move_action = null @startTimedAction getActionWithId(Action.NOOP), 0 return @@ -308,22 +310,22 @@ class Bot extends Pushable @move_action.takeRest (action) else @move_action = @getActionWithId Action.FORWARD - playSoundAtPos(KikiSound.BOT_LAND, @getPos(), 0.25) + world.playSound 'BOT_LAND', @getPos(), 0.25 else # forward will not be empty if world.isUnoccupiedPos position.minus @getUp() # below is empty @move_action = @getActionWithId Action.CLIMB_UP - playSoundAtPos KikiSound.BOT_LAND, @getPos(), 0.5 + world.playSound 'BOT_LAND', @getPos(), 0.5 else if world.isUnoccupiedPos position.minus @getUp() # below will be empty if move # sticky if moving if world.isUnoccupiedPos position.plus @getDir() # forward will be empty if world.isOccupiedPos position.plus @getDir().minus @getUp() # below forward is solid - KikiObject * occupant = world.getOccupantAtPos position.plus @getDir().minus @getUp() + occupant = world.getOccupantAtPos position.plus @getDir().minus @getUp() if occupant == null or not occupant.isSlippery() @move_action = @getActionWithId (Action.FORWARD) else - KikiObject * occupant = world.getOccupantAtPos position.plus @getDir() + occupant = world.getOccupantAtPos position.plus @getDir() if occupant == null or not occupant.isSlippery() @move_action = @getActionWithId (Action.CLIMB_UP) @@ -331,10 +333,10 @@ class Bot extends Pushable @move_action = @getActionWithId Action.FALL @move_action.takeRest action else if actionId == Action.FALL or actionId == Action.FALL_FORWARD # landed - if @ == player - playSound KikiSound.BOT_LAND + if @ == world.player + world.playSound 'BOT_LAND' else - playSoundAtPos KikiSound.BOT_LAND, @getPos() + world.playSound 'BOT_LAND', @getPos() if @move_action Timer.addAction @move_action @@ -345,8 +347,8 @@ class Bot extends Pushable if @move @moveBot() else - dir_sgn = 1.0 - if actionId != Action.NOOP then jump_once = false + @dir_sgn = 1.0 + if actionId != Action.NOOP then @jump_once = false # keep action chain flowing in order to detect environment changes @startTimedAction @getActionWithId(Action.NOOP), 0 diff --git a/coffee/event.coffee b/coffee/event.coffee index efe9024..ddd5b74 100644 --- a/coffee/event.coffee +++ b/coffee/event.coffee @@ -12,28 +12,30 @@ _ = require 'lodash' class Event constructor: (obj, name) -> - @object = obj - @name = name + @object = obj + @name = name + @time = 0 + @actions = [] @save_actions = [] + @finished_actions = [] + getTime: -> @time hasAction: (action) -> _.find @actions, action addAction: (action) -> - if @hasAction action - actions.push action + log "Event.addAction #{action.name}" + if action? and not @hasAction action + @actions.push action action.event = @ action.init() + else + log 'no action?', action removeAllActions: () -> - while actions.length + while @actions.length @removeAction last @actions - getActionsOfObject: (object) -> - actions = [] - for a in _.clone @actions - if a.object == object - actions.push a - actions + getActionsOfObject: (object) -> @actions.filter (a) -> a.object == object removeActionsOfObject: (object) -> for a in @actions @@ -41,8 +43,7 @@ class Event removeActionWithName: (actionName) -> for a in @actions - if a.name == actionName - @removeAction a + @removeAction a if a.name == actionName removeAction: (action) -> action.event = null @@ -51,10 +52,12 @@ class Event _.pull @finished_actions, action triggerActions: () -> - time = KEventHandler.getTime() - @save_actions = KikiActionList (actions) + @time = world.getTime() + log 'trigger actions', @time, @actions.length + @save_actions = _.clone @actions while @save_actions.length - action= last @save_actions + action = last @save_actions + log "performAction #{action.name}" action.performWithEvent @ if @save_actions.length and action == last @save_actions @save_actions.pop() diff --git a/coffee/player.coffee b/coffee/player.coffee index 406cde3..5ede12b 100644 --- a/coffee/player.coffee +++ b/coffee/player.coffee @@ -292,15 +292,16 @@ class Player extends Bot # 000 000 0000000 000 000 0000000 000 000 initAction: (action) -> + log "initAction #{action.id} #{action.name}" actionId = action.id switch actionId when Action.CLIMB_DOWN, Action.FORWARD @status.addMoves 1 when Action.TURN_LEFT, Action.TURN_RIGHT - sound.playSound KikiSound.BOT_MOVE + world.playSound 'BOT_MOVE' when Action.JUMP, Action.JUMP_FORWARD @status.addMoves actionId == Action.JUMP and 1 or 2 - sound.playSound KikiSound.BOT_JUMP + world.playSound 'BOT_JUMP' super action @@ -352,11 +353,11 @@ class Player extends Bot @dir_sgn = @new_dir_sgn if actionId != Action.LOOK_UP and actionId != Action.LOOK_DOWN - KikiBot.finishAction(action) + super action if actionId == Action.TURN_LEFT or actionId == Action.TURN_RIGHT if rotate - @rotate_action = getActionWithId rotate + @rotate_action = @getActionWithId rotate rotate_action.reset() Timer.addAction rotate_action @@ -364,7 +365,7 @@ class Player extends Bot # Controller.removeKeyHandler @ super # Controller.displayText "game over" - # sound.playSound KikiSound.BOT_DEATH + world.playSound 'BOT_DEATH' world.setCameraMode world.CAMERA_FOLLOW reborn: () -> @@ -421,8 +422,8 @@ class Player extends Bot if combo == @key.turn or combo == @key.right rotate = (combo == @key.left) and Action.TURN_LEFT or Action.TURN_RIGHT - if @rotate_action == null and spiked == false # player is not performing a rotation and unspiked - @rotate_action = getActionWithId rotate + if @rotate_action == null and not @spiked # player is not performing a rotation and unspiked + @rotate_action = @getActionWithId rotate Timer.addAction @rotate_action return keyHandled() @@ -481,8 +482,8 @@ class Player extends Bot if jump_once if @move_action == null and world.isUnoccupiedPos position.plus @getUp() jump_once = false - @move_action = getActionWithId Action.JUMP - sound.playSound KikiSound.BOT_JUMP + @move_action = @getActionWithId Action.JUMP + world.playSound 'BOT_JUMP' Timer.addAction @move_action return releaseHandled() @@ -497,7 +498,7 @@ class Player extends Bot 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 + @look_action = @getActionWithId Action.LOOK_RESET Timer.addAction @look_action return releaseHandled() diff --git a/coffee/pushable.coffee b/coffee/pushable.coffee index 097a895..2989396 100644 --- a/coffee/pushable.coffee +++ b/coffee/pushable.coffee @@ -26,13 +26,13 @@ class Pushable extends Item @move_action = pushAction @direction = dir - # pushAction->setDuration Controller.unmapMsTime duration - # Controller.timer_event->addAction (pushAction); + pushAction.setDuration world.unmapMsTime duration + Timer.addAction pushAction initAction: (action) -> - # switch action->getId() - # when Action.FALL - # Controller.world->objectWillMoveToPos @, @position + @direction, action->getDuration() + switch action.id + when Action.FALL + world.objectWillMoveToPos @, @position.plus(@direction), action.getDuration() performAction: (action) -> switch action.id @@ -53,10 +53,10 @@ class Pushable extends Item gravityDir = @direction if actionId == Action.PUSH - if @pusher instanceof KikiBot + if @pusher instanceof Bot gravityDir = pusher.getDown() - else if pusher instanceof KikiBomb - if @ instanceof KikiBot + else if pusher instanceof Bomb + if @ instanceof Bot if @direction == @getUp() # bots don't fall through bomb splitter @direction.reset() @@ -70,9 +70,9 @@ class Pushable extends Item if world.isUnoccupiedPos @position + gravityDir @direction = gravityDir @move_action = @getActionWithId Action.FALL - # Controller.timer_event->addAction (move_action) + Timer.addAction @move_action else @direction.reset() - # playSoundAtPos landing_sound, position + world.playSound @landing_sound, position module.exports = Pushable diff --git a/coffee/timer.coffee b/coffee/timer.coffee index 1aa660e..07a9b00 100644 --- a/coffee/timer.coffee +++ b/coffee/timer.coffee @@ -8,8 +8,24 @@ log = require '/Users/kodi/s/ko/js/tools/log' class Timer - @removeActionsOfObject: (o) -> log "removeActionsOfObject" - @addAction: (a) -> log "addAction" - @removeAction: (a) -> log "removeAction" + @event = null + @eventID = -1 + + @init: -> + @eventID = world.addEventWithName 'timer' + @event = world.getEventWithId @eventID + log "Timer.@init @eventID:#{@eventID} #{@event.name}" + + @removeActionsOfObject: (o) -> + log "removeActionsOfObject" + @event.removeActionsOfObject o + + @addAction: (a) -> + log "addAction" + @event.addAction a + + @removeAction: (a) -> + log "removeAction" + @event.removeAction a module.exports = Timer diff --git a/coffee/world.coffee b/coffee/world.coffee index 5631e36..ecb4af7 100644 --- a/coffee/world.coffee +++ b/coffee/world.coffee @@ -14,15 +14,17 @@ Cell = require './cell' Light = require './light' Player = require './player' Timer = require './timer' +Actor = require './actor' TmpObject = require './tmpobject' Quaternion = require './lib/quaternion' Vector = require './lib/vector' Pos = require './lib/pos' _ = require 'lodash' +now = require 'performance-now' world = null -class World +class World extends Actor @CAMERA_INSIDE = 0 @CAMERA_BEHIND = 1 @@ -30,11 +32,14 @@ class World @levelList = [] @levelDict = [] + @speed = 5 - constructor: (@view) -> + constructor: (@view) -> + + super @screenSize = new Size @view.clientWidth, @view.clientHeight - log "view @screenSize:", @screenSize + # log "view @screenSize:", @screenSize @renderer = new THREE.WebGLRenderer antialias: true @@ -181,6 +186,7 @@ class World log "create world in view:", view world = new World view global.world = world + Timer.init() world.create first @levelList world @@ -192,7 +198,7 @@ class World create: (worldDict={}) -> # creates the world from a level name or a dictionary - log "world.create", worldDict + # log "world.create", worldDict if worldDict if _.isString worldDict @@ -205,7 +211,8 @@ class World # ............................................................ appearance @setSize @dict["size"] - log "world size set", @size + # log "world size set", @size + # if "scheme" in @dict # @applyColorScheme eval(@dict["scheme"]) # else @@ -244,7 +251,7 @@ class World log "exits" exit_id = 0 for entry in @dict.exits - exit_gate = new KikiGate entry["active"] + exit_gate = new Gate entry["active"] if "name" in entry name = entry["name"] @@ -253,7 +260,7 @@ class World exit_gate.setName name exit_action = once "exit " + str(exit_id) - delay_action = once (a=exit_action) -> Controller.timer_event.addAction(a) + delay_action = once (a=exit_action) -> Timer.addAction a # exit_gate.getEventWithName("enter").addAction(delay_action) if entry.position? pos = @decenter entry.position @@ -334,8 +341,9 @@ class World world.moveObjectToPos player, world.decenter(player_dict["position"]) performAction: (name, time) -> + log "world.performAction #{name}" # action callback. used to exit current world - if name.find ("exit") == 0 + if /exit/.test name @finish() @player.status.setMoves 0 if "world" in @dict["exits"][parseInt name.slice 5] @@ -344,18 +352,15 @@ class World w.create() else if _.isFunction w w() - else - exec "World().create(" + world + ")" + # else + # exec "World().create(" + world + ")" else - KikiPyWorld().create (levelList[world.level_index+1]) + world.create levelList[world.level_index+1] activate: (objectName) -> # activates object with name objectName - object = @getObjectWithName(objectName) - if object.getClassName() == "KikiSwitch" - kikiObjectToSwitch(object).setActive(1) - else if object.getClassName() == "KikiGate" - kikiObjectToGate(object).setActive(1) + object = @getObjectWithName objectName + object?.setActive? 1 decenter: (x,y,z) -> new Pos(x,y,z).plus @size.div 2 @@ -400,9 +405,9 @@ class World # adds number objects of type at random positions to the world for i in [0...number] if type (object) == types.StringType - @setObjectRandom (eval(object)) + @setObjectRandom eval object else - @setObjectRandom (object()) + @setObjectRandom object() setObjectRandom: (object) -> # adds number objects of type at random positions to the world @@ -480,8 +485,8 @@ class World exec @dict["escape"] in globals() return - menu = KikiMenu() - menu.getEventWithName ("hide").addAction (once(@resetProjection)) + menu = new Menu() + menu.getEventWithName("hide").addAction once @resetProjection # if Controller.isDebugVersion() # menu.addItem (Controller.getLocalizedString("next level"), once(lambda w=self: w.performAction("exit 0",0))) @@ -489,12 +494,12 @@ class World # menu.addItem (Controller.getLocalizedString("help"), once(@help)) menu.addItem(Controller.getLocalizedString("restart"), once(@restart)) - esc_menu_action = once (@escape) - console.out("level_index %d" % world.level_index) + esc_menu_action = once @escape + log "level_index #{world.level_index}" menu.addItem(Controller.getLocalizedString("load level"), (i=world.level_index,a=esc_menu_action) -> levelSelection(i, a)) - menu.addItem(Controller.getLocalizedString("setup"), once(quickSetup)) - menu.addItem(Controller.getLocalizedString("about"), once(display_about)) - menu.addItem(Controller.getLocalizedString("quit"), once(Controller.quit)) + menu.addItem(Controller.getLocalizedString("setup"), once @quickSetup) + menu.addItem(Controller.getLocalizedString("about"), once @display_about) + menu.addItem(Controller.getLocalizedString("quit"), once world.quit) setSize: (size) -> @deleteAllObjects() @@ -559,7 +564,7 @@ class World newObject: (object) -> if _.isString object - log "newObject:", object + # log "newObject:", object if object.startsWith 'Kiki' return new (require "./#{object.slice(4).toLowerCase()}")() object @@ -587,9 +592,7 @@ class World @unsetObject object @setObjectAtPos object, pos - - # Controller.sound.playSound(KikiSound::BOT_LAND) - + world.playSound 'BOT_LAND' true deleteObject: (object) -> @@ -649,6 +652,7 @@ class World @moved_objects.push object objectWillMoveToPos: (object, pos, duration) -> + log "world.objectWillMoveToPos", pos cell = @getCellAtPos pos if @isInvalidPos pos @@ -729,14 +733,18 @@ class World @camera.position.set(center.x,center.y,center.z+@dist).applyQuaternion quat @camera.quaternion.copy quat + Timer.event.triggerActions() + Timer.event.finishActions() + @player.getProjection().apply @camera @sun.position.copy @camera.position @renderer.render @scene, @camera + getTime: -> now().toFixed 0 setSpeed: (s) -> @speed = s getSpeed: -> @speed - mapMsTime: (unmapped) -> parseInt 10.0 * unmapped/speed - unmapMsTime: (mapped) -> parseInt mapped * speed/10.0 + mapMsTime: (unmapped) -> parseInt 10.0 * unmapped/@speed + unmapMsTime: (mapped) -> parseInt mapped * @speed/10.0 getRelativeTime: -> @frame_time % (10000/@speed)/(10000.0/@speed) getRelativeDelta: -> (@frame_time - @last_time)/(10000.0/@speed) @@ -865,6 +873,9 @@ class World when World.CAMERA_BEHIND then @projection = @player.getBehindProjection() when World.CAMERA_FOLLOW then @projection = @player.getFollowProjection() @projection.apply @camera + + playSound: (sound, pos, time) -> + log "World.playSound #{sound} #{time}", pos # 000 000 00000000 000 000 # 000 000 000 000 000