summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
l---------client/common1
-rw-r--r--client/conf.lua3
-rw-r--r--client/main.lua122
-rw-r--r--common/words.lua17
l---------server/common1
-rw-r--r--server/server.lua111
6 files changed, 255 insertions, 0 deletions
diff --git a/client/common b/client/common
new file mode 120000
index 0000000..60d3b0a
--- /dev/null
+++ b/client/common
@@ -0,0 +1 @@
+../common \ No newline at end of file
diff --git a/client/conf.lua b/client/conf.lua
new file mode 100644
index 0000000..5c58cb3
--- /dev/null
+++ b/client/conf.lua
@@ -0,0 +1,3 @@
+function love.conf(t)
+ t.window.title = "rectangle emulator"
+end
diff --git a/client/main.lua b/client/main.lua
new file mode 100644
index 0000000..4375ed3
--- /dev/null
+++ b/client/main.lua
@@ -0,0 +1,122 @@
+local enet = require"enet"
+local words = require"common.words"
+
+
+local PLAYER_SIZE = 30
+
+local local_player = false
+
+-- {
+-- pos={100,100},
+-- color={love.math.colorFromBytes(0xdf,0x73,0xff)},
+-- }
+
+local host,peer
+
+local function draw_player(pl,me)
+ local hplsz = PLAYER_SIZE/2
+ love.graphics.setColor(pl.color)
+ love.graphics.rectangle("fill",pl.pos[1]-hplsz,pl.pos[2]-hplsz,PLAYER_SIZE,PLAYER_SIZE)
+ love.graphics.setColor(0,0,0)
+ love.graphics.print(tostring(pl.id),pl.pos[1],pl.pos[2])
+ if me then
+ love.graphics.setColor(1,1,1)
+ love.graphics.rectangle("line",pl.pos[1]-hplsz,pl.pos[2]-hplsz,PLAYER_SIZE,PLAYER_SIZE)
+ end
+end
+
+local remote_players = {}
+
+local function update_local_player(pl,dt)
+ local SPEED = 300 -- pixels/sec
+ local function kd(code)
+ if love.keyboard.isScancodeDown(code) then return 1 else return 0 end
+ end
+ local dx = kd"d"-kd"a"
+ local dy = kd"s"-kd"w"
+
+ if dx == 0 and dy == 0 then
+ pl.pos_dirty = false
+ return
+ end
+
+ if dx ~= 0 and dy ~= 0 then
+ dx = dx / math.sqrt(2)
+ dy = dy / math.sqrt(2)
+ end
+
+ pl.pos[1] = pl.pos[1] + SPEED * dt * dx
+ pl.pos[2] = pl.pos[2] + SPEED * dt * dy
+ pl.pos_dirty = true
+end
+
+local function sync_local_player(pl,peer)
+ -- send updated info about local player to server
+ if pl.pos_dirty then
+ peer:send(words.join("ppos",pl.pos[1],pl.pos[2]))
+ end
+end
+
+function love.update(dt)
+ if local_player then
+ update_local_player(local_player,dt)
+ sync_local_player(local_player,peer)
+ end
+ repeat
+ local ev = host:service()
+ if ev and ev.type == "receive" then
+ local w = words.split(ev.data)
+ local op = w[1]
+ if op == "join" then
+ local id,x,y,r,g,b = unpack(w,2)
+ -- blegh
+ id=tonumber(id)
+ x=tonumber(x)
+ y=tonumber(y)
+ r=tonumber(r)
+ g=tonumber(g)
+ b=tonumber(b)
+ remote_players[id] = {pos={x,y},color={r,g,b},id=id}
+ elseif op == "leave" then
+ local id = tonumber(w[2])
+ remote_players[id]=nil
+ elseif op == "move" then
+ local id,x,y = unpack(w,2)
+ id=tonumber(id)
+ x=tonumber(x)
+ y=tonumber(y)
+ assert(remote_players[id],"wheeze")
+ remote_players[id].pos[1] = x
+ remote_players[id].pos[2] = y
+ elseif op == "you" then
+ local id,x,y,r,g,b = unpack(w,2)
+ id=tonumber(id)
+ x=tonumber(x)
+ y=tonumber(y)
+ r=tonumber(r)
+ g=tonumber(g)
+ b=tonumber(b)
+ local_player = {pos={x,y},color={r,g,b},id=id}
+ end
+ end
+ until not ev
+end
+
+function love.draw()
+ if local_player then
+ draw_player(local_player,true)
+ end
+ for _,pl in pairs(remote_players) do
+ draw_player(pl)
+ end
+end
+
+function love.load()
+ host = enet.host_create()
+ peer = host:connect("localhost:8473")
+end
+
+function love.quit()
+ peer:disconnect()
+ host:flush()
+end
diff --git a/common/words.lua b/common/words.lua
new file mode 100644
index 0000000..4d6904e
--- /dev/null
+++ b/common/words.lua
@@ -0,0 +1,17 @@
+local function join(...)
+ return table.concat({...}," ")
+end
+
+local function split(s)
+ local o = {}
+ for w in string.gmatch(s,"(%S+)") do
+ table.insert(o,w)
+ end
+ return o
+end
+
+return {
+ join=join,
+ split=split,
+}
+
diff --git a/server/common b/server/common
new file mode 120000
index 0000000..60d3b0a
--- /dev/null
+++ b/server/common
@@ -0,0 +1 @@
+../common \ No newline at end of file
diff --git a/server/server.lua b/server/server.lua
new file mode 100644
index 0000000..4db0207
--- /dev/null
+++ b/server/server.lua
@@ -0,0 +1,111 @@
+local enet = require"enet"
+local words = require"common.words"
+local unpack = unpack or table.unpack
+
+math.randomseed(os.time())
+
+local host = enet.host_create("*:8473")
+print(host)
+
+-- sequential list of all players
+local playerlist = {}
+
+-- this is maybe suboptimal
+-- but it is simplest for now
+local function player_by_id(id)
+ for i,pl in ipairs(playerlist) do
+ if pl.id == id then return pl, i end
+ end
+ return nil
+end
+local function player_by_peer(peer)
+ for i,pl in ipairs(playerlist) do
+ if pl.peer == peer then return pl, i end
+ end
+ return nil
+end
+
+
+local function gen_id()
+ local x = math.random(100000)
+ -- if players[x] then error("cough") end
+ return x
+end
+local function random_color()
+ return {math.random(),math.random(),math.random()}
+end
+local function make_player(peer)
+ return {pos={100,100},color=random_color(),peer=peer}
+end
+
+-- maybe json could be used for this
+-- or something
+local function player_info_part(player)
+ return words.join(
+ player.id,
+ player.pos[1],
+ player.pos[2],
+ player.color[1],
+ player.color[2],
+ player.color[3])
+end
+local function player_join_packet(player)
+ return "join "..player_info_part(player)
+end
+local function player_you_packet(player)
+ return "you "..player_info_part(player)
+end
+local function player_leave_packet(player)
+ return words.join("leave",player.id)
+end
+local function player_move_packet(player,x,y)
+ return words.join("move",player.id,x,y)
+end
+
+while true do
+ local ev = host:service(100)
+ if ev then
+ if ev.type == "connect" then
+ local player = make_player(ev.peer)
+ table.insert(playerlist,player)
+ player.id = #playerlist
+ print("connect",player.peer,player.id)
+ player.peer:send(player_you_packet(player))
+
+ for i,otherplayer in ipairs(playerlist) do
+ if otherplayer ~= player then
+ -- tell new player about each other player
+ player.peer:send(player_join_packet(otherplayer))
+ -- tell each other player about new player
+ otherplayer.peer:send(player_join_packet(player))
+ end
+ end
+ elseif ev.type == "disconnect" then
+ local player, idx = player_by_peer(ev.peer)
+ if not player then error("sneeze "..ev.peer) end
+ table.remove(playerlist,idx)
+ for i,otherplayer in ipairs(playerlist) do
+ otherplayer.peer:send(player_leave_packet(player))
+ end
+ elseif ev.type == "receive" then
+ local player = player_by_peer(ev.peer)
+ if not player then error("sneezey "..ev.peer) end
+ local w = words.split(ev.data)
+ local op = w[1]
+ if op == "ppos" then
+ local _,x,y,a = unpack(w)
+ player.pos[1] = tonumber(x)
+ player.pos[2] = tonumber(y)
+ print(player.id,"-->",player.pos[1],player.pos[2])
+ for i,otherplayer in ipairs(playerlist) do
+ if otherplayer ~= player then
+ otherplayer.peer:send(player_move_packet(player,x,y))
+ end
+ end
+ end
+
+ end
+ -- for k,v in pairs(ev) do io.write(tostring(k),":",tostring(v)," ") end
+ -- print()
+ end
+end