Permalink
Browse files

Initial commit

  • Loading branch information...
dhotson committed Jun 16, 2012
0 parents commit c985f44e8caafbabcf03dbefe8b25efd00de115b
Showing with 291 additions and 0 deletions.
  1. +4 −0 Guardfile
  2. +168 −0 adventure.rb
  3. +12 −0 index.html
  4. +107 −0 lib/adventure.coffee
@@ -0,0 +1,4 @@
+# A sample Guardfile
+# More info at https://github.com/guard/guard#readme
+
+guard :coffeescript, :input => 'lib', :output => 'lib'
@@ -0,0 +1,168 @@
+require 'em-websocket'
+require 'json'
+
+class Vector
+ attr_reader :x, :y
+
+ def initialize(x, y)
+ @x = x
+ @y = y
+ end
+
+ def +(other)
+ self.class.new(@x + other.x, @y + other.y)
+ end
+
+ def -(other)
+ self.class.new(@x - other.x, @y - other.y)
+ end
+
+ def *(n)
+ self.class.new(@x * n, @y * n)
+ end
+
+ def /(n)
+ self.class.new(@x / n, @y / n)
+ end
+
+ def magnitude
+ (@x ** 2 + @y ** 2) ** 0.5
+ end
+
+ def normalise
+ self / magnitude
+ end
+end
+
+class World
+ attr_reader :players, :rockets
+ def initialize
+ @players = []
+ @rockets = []
+ end
+
+ def new_player
+ p = Player.new
+ @players.push(p)
+ p
+ end
+
+ def new_rocket(position, direction)
+ r = Rocket.new(position, direction)
+ @rockets.push(r)
+ r
+ end
+
+ def remove_player(player)
+ @players.delete(player)
+ end
+
+ def tick(dt)
+ @rockets.each { |p| p.tick(dt) }
+ @players.each { |r| r.tick(dt) }
+ end
+
+ def to_h(player=nil)
+ {
+ players: @players.map { |p| p.to_h(player) },
+ rockets: @rockets.map { |r| r.to_h },
+ }
+ end
+
+ def to_json(player=nil)
+ to_h(player).to_json
+ end
+end
+
+class Player
+ attr_reader :name, :position
+
+ def initialize
+ @@n ||= 0
+ @id = (@@n += 1)
+ @name = "Player #{@id.to_s}"
+ @position = Vector.new(rand(800).to_f, rand(600).to_f)
+ @velocity = Vector.new(rand(50).to_f - 25, rand(50).to_f - 25)
+ end
+
+ def move(direction)
+ @velocity += direction.normalise * 10.0
+ end
+
+ def tick(dt)
+ if @velocity.magnitude > 200.0
+ @velocity = @velocity.normalise * 200.0
+ end
+ @velocity *= 0.96
+ @position += @velocity * dt
+ end
+
+ def to_h(you=nil)
+ {
+ name: @name,
+ you: (self === you),
+ pos: {x: @position.x, y: @position.y},
+ }
+ end
+end
+
+class Rocket
+ def initialize(owner, direction)
+ @owner = owner
+ @position = owner.position
+ @velocity = direction.normalise * 300.0
+ end
+
+ def tick(dt)
+ @position += @velocity * dt
+ end
+
+ def to_h
+ {
+ pos: {x: @position.x, y: @position.y},
+ }
+ end
+end
+
+$world = World.new
+
+EventMachine::WebSocket.start(:host => '0.0.0.0', :port => 8080) do |ws|
+
+ player = $world.new_player
+
+ ws.onopen do
+ # ws.send "Welcome!"
+ end
+
+ dt = 1.0 / 60.0
+ timer = EventMachine::PeriodicTimer.new(dt) do
+ $world.tick(dt)
+ ws.send $world.to_json(player)
+ end
+
+ ws.onmessage do |msg|
+ command = JSON.load(msg)
+
+ case command['type']
+ when 'move'
+ keys = command['keys']
+ keys.each do |key|
+ dir = ({
+ 'up' => Vector.new(0, -1),
+ 'down' => Vector.new(0, 1),
+ 'left' => Vector.new(-1, 0),
+ 'right' => Vector.new(1, 0),
+ })[key]
+
+ player.move(Vector.new(dir.x, dir.y))
+ end
+ when 'shoot'
+ direction = Vector.new(command['x'], command['y']) - player.position
+ $world.new_rocket(player, direction)
+ end
+ end
+
+ ws.onclose do
+ $world.remove_player(player)
+ end
+end
@@ -0,0 +1,12 @@
+<html>
+<head><title></title></head>
+<body>
+<style>
+body {
+ margin: 0;
+}
+</style>
+<canvas id="canvas"></canvas>
+<script src="lib/adventure.js"></script>
+</body>
+
@@ -0,0 +1,107 @@
+canvas = document.getElementById 'canvas'
+
+# window.addEventListener 'resize', ->
+# canvas.width = document.width
+# canvas.height = document.height
+
+canvas.width = 800 # document.width
+canvas.height = 600 # document.height
+canvas.style.backgroundColor = '#EEEEEE'
+canvas.style.cursor = 'none'
+
+ctx = canvas.getContext '2d'
+
+window.Game = {}
+
+Game.ws = ws = new WebSocket "ws://10.0.1.142:8080"
+
+up = false
+down = false
+left = false
+right = false
+
+crosshair = { x: 0, y: 0 }
+window.addEventListener 'mousemove', (event) ->
+ crosshair.x = event.clientX
+ crosshair.y = event.clientY
+
+
+
+window.addEventListener 'keydown', (event) ->
+ if event.keyCode == 87 then up = true
+ if event.keyCode == 83 then down = true
+ if event.keyCode == 65 then left = true
+ if event.keyCode == 68 then right = true
+
+window.addEventListener 'keyup', (event) ->
+ if event.keyCode == 87 then up = false
+ if event.keyCode == 83 then down = false
+ if event.keyCode == 65 then left = false
+ if event.keyCode == 68 then right = false
+
+window.addEventListener 'mousedown', (event) ->
+ ws.send(JSON.stringify({
+ type: 'shoot',
+ x: event.clientX,
+ y: event.clientY,
+ }))
+
+# setInterval((->
+# keys = []
+# if up then ws.send 'up'
+# if down then ws.send 'down'
+# if left then ws.send 'left'
+# if right then ws.send 'right'
+# ), 10)
+
+Game.world = world = {players: [], rockets: []}
+
+ws.onmessage = (evt) ->
+ Game.world = world = JSON.parse(evt.data)
+
+drawStuff = ->
+ keys = []
+ if up then keys.push 'up'
+ if down then keys.push 'down'
+ if left then keys.push 'left'
+ if right then keys.push 'right'
+ if up || down || left || right
+ ws.send JSON.stringify({type: 'move', keys: keys})
+
+ ctx.clearRect 0, 0, canvas.width, canvas.height
+
+ for rocket in world.rockets
+ ctx.lineWidth = 1
+ ctx.fillStyle = '#330000'
+ ctx.strokeStyle = '#000000'
+ ctx.beginPath()
+ ctx.arc(rocket.pos.x, rocket.pos.y, 5, 0, Math.PI * 2)
+ ctx.fill()
+ ctx.stroke()
+
+ for player in world.players
+ if player.you
+ ctx.fillStyle = '#FF0000'
+ ctx.strokeStyle = '#000000'
+ else
+ ctx.fillStyle = '#0000FF'
+ ctx.strokeStyle = '#000000'
+
+ ctx.lineWidth = 5
+ ctx.beginPath()
+ ctx.arc(player.pos.x, player.pos.y, 20, 0, Math.PI * 2)
+ ctx.fill()
+ ctx.stroke()
+
+ ctx.fillStyle = 'rgba(0,0,0,0.2)'
+ ctx.beginPath()
+ ctx.arc(crosshair.x, crosshair.y, 10, 0, Math.PI * 2)
+ ctx.fill()
+
+ webkitRequestAnimationFrame(drawStuff)
+
+webkitRequestAnimationFrame(drawStuff)
+ws.onclose = ->
+
+ws.onopen = ->
+

0 comments on commit c985f44

Please sign in to comment.