diff --git a/coffee/action.coffee b/coffee/action.coffee index e8835e6..dd29437 100644 --- a/coffee/action.coffee +++ b/coffee/action.coffee @@ -10,24 +10,25 @@ _ = require 'lodash' class Action @NOOP = 0 - @PUSH = 1 - @EXPLODE = 1 - @TOGGLE = 1 - @ROTATE = 2 - @FLY = 2 - @FALL = 2 - @FORWARD = 3 - @CLIMB_UP = 4 - @CLIMB_DOWN = 5 - @TURN_LEFT = 6 - @TURN_RIGHT = 7 - @JUMP = 8 - @JUMP_FORWARD = 9 - @FALL_FORWARD = 10 - @SHOOT = 11 - @LOOK_UP = 12 - @LOOK_DOWN = 13 - @LOOK_RESET = 14 + @ROTATE = 1 # switch, gate, bomb + @FLY = 2 # bullet + @TOGGLE = 3 # switch, gate + @FALL = 4 # pushable + @PUSH = 5 # pushable + @EXPLODE = 6 # bomb + @IMPLODE = 7 # bomb + @FORWARD = 8 # bot + @CLIMB_UP = 9 # bot + @CLIMB_DOWN = 10 # ... + @TURN_LEFT = 11 + @TURN_RIGHT = 12 + @JUMP = 13 + @JUMP_FORWARD = 14 + @FALL_FORWARD = 15 + @SHOOT = 16 + @LOOK_UP = 17 + @LOOK_DOWN = 18 + @LOOK_RESET = 19 @ONCE = 0 @CONTINUOUS = 1 @@ -44,7 +45,7 @@ class Action i ?= -1 m ?= Action.ONCE d ?= 0 - # log "newAction #{i} #{n} #{d} #{m}" + log "newAction #{i} #{n} #{d} #{m}" @object = o @name = n @id = i @@ -55,7 +56,7 @@ class Action @reset() del: -> - log "Action.del #{@name} #{@event?} #{@object?}" + # log "Action.del #{@name} #{@event?} #{@object?}" if @event? then @event.removeAction @ if @object? then @object.removeAction @ @deleted = true diff --git a/coffee/actor.coffee b/coffee/actor.coffee index 97aee95..bc9d852 100644 --- a/coffee/actor.coffee +++ b/coffee/actor.coffee @@ -60,10 +60,10 @@ class Actor extends Emitter removeAction: (action) -> @actions[action.id] = null - getActionWithId: (actionId) -> - if @actions[actionId]?.id? and @actions[actionId].id != actionId - throw new Error - @actions[actionId] + getActionWithId: (actionId) -> _.find @actions, (a) -> a?.id == actionId + # if @actions[actionId]?.id? and @actions[actionId].id != actionId + # throw new Error + # @actions[actionId] # if actionId < @actions.length and @actions[actionId].id == actionId # return @actions[actionId] # diff --git a/coffee/bomb.coffee b/coffee/bomb.coffee new file mode 100644 index 0000000..56b0a30 --- /dev/null +++ b/coffee/bomb.coffee @@ -0,0 +1,98 @@ +# 0000000 0000000 00 00 0000000 +# 000 000 000 000 000 000 000 000 +# 0000000 000 000 000000000 0000000 +# 000 000 000 000 000 0 000 000 000 +# 0000000 0000000 000 000 0000000 + +Pushable = require './pushable' +Action = require './action' +Vector = require './lib/vector' + +class Bomb extends Pushable + + isSpaceEgoistic: -> true + constructor: () -> + + @angle = 0.0 + @size = 0.55 + @splitted = false + + # glScalef(size*0.3, size*0.3, size*0.3); + # glRotatef(angle, 1.0, 0.0, 0.0); + # glRotatef(90, 0.0, 1.0, 0.0); + # glRotatef(angle, 1.0, 0.0, 0.0); + # glutSolidDodecahedron (); + # glRotatef(90, 1.0, 0.0, 0.0); + # glutSolidDodecahedron (); + + @geom = new THREE.DodecahedronGeometry @size + + @mat = new THREE.MeshPhongMaterial + color: 0xff0000 + side: THREE.FrontSide + shading: THREE.FlatShading + transparent: true + opacity: 0.7 + shininess: 20 + + @mesh = new THREE.Mesh @geom, @mat + super + + @addEventWithName 'explode' + + @addAction new Action @, Action.ROTATE, "rotation", 2000, Action.CONTINUOUS + @addAction new Action @, Action.IMPLODE, "implode", 100 + @addAction new Action @, Action.EXPLODE, "explode", 100 + + @startTimedAction @getActionWithId Action.ROTATE + + splitterInDirection: (dir) -> + + splitter = false + pos = @getPos().plus dir + + if world.isUnoccupiedPos pos + splitter = true + else + occupant = world.getRealOccupantAtPos pos + if occupant + if occupant instanceof Bomb + occupant.bulletImpact() + return + if world.mayObjectPushToPos @, pos, @getActionWithId(Action.EXPLODE).duration + splitter = true + + if splitter + Splitter = require './splitter' + world.addObjectAtPos new Splitter(dir), pos + + bulletImpact: -> + if not @splitted + @splitted = true + directions = [[1,0,0], [0,1,0], [0,0,1], [-1,0,0], [0,-1,0], [0,0,-1]] + for i in [0...6] + @splitterInDirection new Vector directions[i][0], directions[i][1], directions[i][2] + + @startTimedAction @getActionWithId Action.IMPLODE + world.playSound 'BOMB_EXPLODE', @getPos() + @getEventWithName("explode").triggerActions() + + performAction: (action) -> + switch action.id + when Action.ROTATE then @angle += action.getRelativeDelta() * 360 + when Action.IMPLODE then @size = 1.0 - action.getRelativeTime() + when Action.EXPLODE then @size = action.getRelativeTime() + else + super action + + actionFinished: (action) -> + switch action.id + when Action.IMPLODE then @del() + when Action.EXPLODE + @splitterInDirection @direction + world.playSound 'BOMB_SPLITTER', @getPos() + @startTimedAction @getActionWithId Action.IMPLODE + else + super action + +module.exports = Bomb diff --git a/coffee/bot.coffee b/coffee/bot.coffee index 06da0ed..dd9b91f 100644 --- a/coffee/bot.coffee +++ b/coffee/bot.coffee @@ -479,7 +479,6 @@ class Bot extends Pushable @move_action = @getActionWithId Action.JUMP else if @move if world.isUnoccupiedPos forwardPos # forward is empty - log 'forwardEmpty:', forwardPos if world.isUnoccupiedPos forwardPos.plus @getDown() # below forward also empty @move_action = @getActionWithId Action.CLIMB_DOWN diff --git a/coffee/item.coffee b/coffee/item.coffee index 246a673..6777969 100644 --- a/coffee/item.coffee +++ b/coffee/item.coffee @@ -25,7 +25,7 @@ class Item extends Actor del: -> super - log "item del !!!!!!!!!!!!!!!!!!!!!! #{@name}" + # log "item del !!!!!!!!!!!!!!!!!!!!!! #{@name}" world.scene.remove @mesh if @mesh? world.removeObject @ @emit 'deleted' diff --git a/coffee/levels.coffee b/coffee/levels.coffee index a3acafc..0832ce9 100644 --- a/coffee/levels.coffee +++ b/coffee/levels.coffee @@ -28,8 +28,8 @@ class Levels # "bombs", # "sandbox", # "energy", - "maze", - "love", + # "maze", + # "love", # medium "towers", "edge", "random", "plate", "nice", "entropy", # owen hay's levels (TODO: sort in) diff --git a/coffee/levels/edge.coffee b/coffee/levels/edge.coffee index 21ebf72..85a5425 100644 --- a/coffee/levels/edge.coffee +++ b/coffee/levels/edge.coffee @@ -17,7 +17,7 @@ module.exports = ] create: -> s=world.size - + Stone = require './stone' # for (i,j,l) in [ (m,n,o) for m in range(3) for n in range(3) for o in range(3)] for i in [0...3] for j in [0...3] @@ -25,8 +25,8 @@ module.exports = if (i==2 or j==2 or l==2) and i>=1 and j>=1 and l >=1 c = 0.6 - (0.3)*Math.pow(-1, i+j+l) d = 0.6 + (0.3)*Math.pow(-1, i+j+l) - world.addObjectAtPos(KikiStone(KColor(c ,0, d, 0.8), false), i,j,l) - world.addObjectAtPos(KikiStone(KColor(c ,0, d, 0.8), false), s.x-i-1,s.y-j-1,s.z-l-1) - world.addObjectAtPos(KikiStone(KColor(c ,0, d, 0.8), false), s.x-i-1,j,l) - world.addObjectAtPos(KikiStone(KColor(c ,0, d, 0.8), false), i,s.y-j-1,s.z-l-1) + world.addObjectAtPos new Stone(color:[c ,0, d, 0.8]), i,j,l + world.addObjectAtPos new Stone(color:[c ,0, d, 0.8]), s.x-i-1,s.y-j-1,s.z-l-1 + world.addObjectAtPos new Stone(color:[c ,0, d, 0.8]), s.x-i-1,j,l + world.addObjectAtPos new Stone(color:[c ,0, d, 0.8]), i,s.y-j-1,s.z-l-1 \ No newline at end of file diff --git a/coffee/levels/love.coffee b/coffee/levels/love.coffee index b05159a..4bb89e7 100644 --- a/coffee/levels/love.coffee +++ b/coffee/levels/love.coffee @@ -17,7 +17,7 @@ module.exports = heart = [[0,0], [ 1,1], [ 2,1], [ 3,0], [ 3,-1], [ 2,-2], [ 1,-3], [0,-4], [-1,1], [-2,1], [-3,0], [-3,-1], [-2,-2], [-1,-3]] for h in heart - world.addObjectAtPos(KikiBomb(), world.decenter(h[0],h[1]+1,4)) - world.addObjectAtPos(KikiStone(), world.decenter(h[0],h[1]+1,-4)) + # world.addObjectAtPos('KikiBomb', world.decenter(h[0],h[1]+1,4)) + world.addObjectAtPos('KikiStone', world.decenter(h[0],h[1]+1,-4)) - world.addObjectAtPos(KikiMutant(), world.decenter(0,-4,0)) \ No newline at end of file + # world.addObjectAtPos('KikiMutant', world.decenter(0,-4,0)) \ No newline at end of file diff --git a/coffee/levels/maze.coffee b/coffee/levels/maze.coffee index fd7af63..d42c143 100644 --- a/coffee/levels/maze.coffee +++ b/coffee/levels/maze.coffee @@ -71,7 +71,7 @@ module.exports = world.addObjectAtPos('KikiWall', 2,2,3) world.addObjectAtPos('KikiWall', 1,3,3) - world.addObjectAtPos(KikiLight(), 3,0,0) + world.addObjectAtPos('KikiLight', 3,0,0) - world.setCameraMode(world.CAMERA_INSIDE) + # world.setCameraMode(world.CAMERA_INSIDE) \ No newline at end of file diff --git a/coffee/levels/stones.coffee b/coffee/levels/stones.coffee index f331a17..4a23924 100644 --- a/coffee/levels/stones.coffee +++ b/coffee/levels/stones.coffee @@ -26,18 +26,18 @@ module.exports = num = 4 for i in [1..num] - world.addObjectPoly(KikiWall, [[s.x/2-i, s.y/2-i, i-1], - [s.x/2+i, s.y/2-i, i-1], - [s.x/2+i, s.y/2+i, i-1], - [s.x/2-i, s.y/2+i, i-1]]) + world.addObjectPoly 'Wall', [[s.x/2-i, s.y/2-i, i-1], + [s.x/2+i, s.y/2-i, i-1], + [s.x/2+i, s.y/2+i, i-1], + [s.x/2-i, s.y/2+i, i-1]] - world.addObjectAtPos(KikiStone(), s.x/2-2, s.y/2, 3) - world.addObjectAtPos(KikiStone(), s.x/2+2, s.y/2, 3) - world.addObjectAtPos(KikiStone(), s.x/2, s.y/2+2, 3) - world.addObjectAtPos(KikiStone(), s.x/2, s.y/2-2, 3) - - world.addObjectAtPos(KikiStone(), s.x/2-1, s.y/2, 2) - world.addObjectAtPos(KikiStone(), s.x/2+1, s.y/2, 2) - world.addObjectAtPos(KikiStone(), s.x/2, s.y/2+1, 2) - world.addObjectAtPos(KikiStone(), s.x/2, s.y/2-1, 2) + world.addObjectAtPos 'Stone', s.x/2-2, s.y/2, 3 + world.addObjectAtPos 'Stone', s.x/2+2, s.y/2, 3 + world.addObjectAtPos 'Stone', s.x/2, s.y/2+2, 3 + world.addObjectAtPos 'Stone', s.x/2, s.y/2-2, 3 + + world.addObjectAtPos 'Stone', s.x/2-1, s.y/2, 2 + world.addObjectAtPos 'Stone', s.x/2+1, s.y/2, 2 + world.addObjectAtPos 'Stone', s.x/2, s.y/2+1, 2 + world.addObjectAtPos 'Stone', s.x/2, s.y/2-1, 2 \ No newline at end of file diff --git a/coffee/levels/towers.coffee b/coffee/levels/towers.coffee index 8aca519..51283b9 100644 --- a/coffee/levels/towers.coffee +++ b/coffee/levels/towers.coffee @@ -16,10 +16,10 @@ module.exports = ], create: -> s = world.size - world.addObjectAtPos(KikiStone(), s.x/2-1, s.y/2+1, 0) - world.addObjectAtPos(KikiStone(), s.x/2-1, s.y/2+1, 1) - world.addObjectAtPos(KikiStone(), s.x/2-1, s.y/2+1, 2) - world.addObjectAtPos(KikiStone(), s.x/2+1, s.y/2+1, 0) - world.addObjectAtPos(KikiStone(), s.x/2+1, s.y/2+1, 1) - world.addObjectAtPos(KikiStone(), s.x/2+1, s.y/2+1, 2) - world.addObjectAtPos(KikiStone(), s.x/2+1, s.y/2+1, 3) + world.addObjectAtPos 'Stone', s.x/2-1, s.y/2+1, 0 + world.addObjectAtPos 'Stone', s.x/2-1, s.y/2+1, 1 + world.addObjectAtPos 'Stone', s.x/2-1, s.y/2+1, 2 + world.addObjectAtPos 'Stone', s.x/2+1, s.y/2+1, 0 + world.addObjectAtPos 'Stone', s.x/2+1, s.y/2+1, 1 + world.addObjectAtPos 'Stone', s.x/2+1, s.y/2+1, 2 + world.addObjectAtPos 'Stone', s.x/2+1, s.y/2+1, 3 diff --git a/coffee/pushable.coffee b/coffee/pushable.coffee index ca95332..1f3bd6e 100644 --- a/coffee/pushable.coffee +++ b/coffee/pushable.coffee @@ -30,7 +30,7 @@ class Pushable extends Item # log "Pushable.setOrientation direction:", @direction pushedByObjectInDirection: (object, dir, duration) -> - log "pushedByObjectInDirection #{object.name} duration:#{duration}" + # log "pushedByObjectInDirection #{object.name} duration:#{duration}" pushAction = @getActionWithId Action.PUSH @pusher = object @@ -63,10 +63,10 @@ class Pushable extends Item @setPosition targetPos actionFinished: (action) -> - Bot = require './bot' + Bot = require './bot' + Bomb = require './bomb' if action.id in [Action.PUSH, Action.FALL] gravityDir = @direction - if action.id == Action.PUSH if @pusher instanceof Bot gravityDir = @pusher.getDown() diff --git a/coffee/splitter.coffee b/coffee/splitter.coffee new file mode 100644 index 0000000..d2bd619 --- /dev/null +++ b/coffee/splitter.coffee @@ -0,0 +1,22 @@ +# 0000000 00000000 000 000 000000000 000000000 00000000 00000000 +# 000 000 000 000 000 000 000 000 000 000 +# 0000000 00000000 000 000 000 000 0000000 0000000 +# 000 000 000 000 000 000 000 000 000 +# 0000000 000 0000000 000 000 000 00000000 000 000 + +Bomb = require './bomb' +Action = require './action' + +class Splitter extends Bomb + + isSpaceEgoistic: -> false + + constructor: (dir) -> + super + @size = 0.0 + @splitted = true + @direction = dir + + @startTimedAction @getActionWithId Action.EXPLODE + +module.exports = Splitter diff --git a/coffee/stone.coffee b/coffee/stone.coffee index 3fffd4f..77861c5 100644 --- a/coffee/stone.coffee +++ b/coffee/stone.coffee @@ -8,21 +8,22 @@ Pushable = require './pushable' class Stone extends Pushable - constructor: (@slippery=false) -> - + constructor: (opt) -> + @slippery = opt?.slippery or false + @color = opt?.color or 0xff8800 @geom = new THREE.BoxGeometry 0.98,0.98,0.98 @mat = new THREE.MeshPhongMaterial - color: 0xff8800 + color: @color side: THREE.DoubleSide shading: THREE.SmoothShading transparent: true opacity: 0.7 shininess: 20 - # alphaTest: 0.05 - # depthWrite: false @mesh = new THREE.Mesh @geom, @mat + @mesh.receiveShadow = true + @mesh.castShadow = true super isSlippery: -> return @slippery diff --git a/coffee/wall.coffee b/coffee/wall.coffee index 3bcc8c9..1a76c3d 100644 --- a/coffee/wall.coffee +++ b/coffee/wall.coffee @@ -25,6 +25,7 @@ class Wall extends Item geom.translate -0.5, -0.5, -0.5 @raster = new THREE.Mesh geom, Wall.rasterMat @raster.receiveShadow = true + @raster.castShadow = true geom = Cage.wallTiles new Pos(1,1,1), 'outside', Cage.gap geom.translate -0.5, -0.5, -0.5 diff --git a/coffee/world.coffee b/coffee/world.coffee index d7d7802..fd7d021 100644 --- a/coffee/world.coffee +++ b/coffee/world.coffee @@ -65,7 +65,7 @@ class World extends Actor @renderer = new THREE.WebGLRenderer antialias: true - logarithmicDepthBuffer: false + logarithmicDepthBuffer: true autoClear: true sortObjects: true @@ -519,9 +519,9 @@ class World extends Actor # 0000000 00000000 0000000 00000000 000 00000000 deleteObject: (object) -> - log "world.deleteObject #{object.name}" + # log "world.deleteObject #{object.name}" if not object? - log "WARNING: World.deleteObject null" + log "world.deleteObject [WARNING] no object?" return @removeObject object object.del()