summaryrefslogtreecommitdiff
path: root/client/game.lua
blob: 59c5799ca765370a9bf4844d0ffff77274a80830 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
local G = love.graphics
local common = require 'common'
local Camera = require'r.camera'
local Pos = require'r.pos'
local Rect = require'r.rect'
local class = require'r.class'
local enet = require'enet'
local pprint = require'pprint'
local json = require'dkjson'
local rle = require'r.rle'

local M = {}

local SPEED = 8 -- tiles per second
local colors = {[true]={141/255,128/255,22/255}, [false]={71/255,50/255,122/255}}


local players = {}
local chunks = common.ChunkMap()
local lp = { pos=Pos(0,0), movetimer=0, dir=nil } -- local player
local cam = Camera(nil, 20)

local host, conn
function M.load(_host,_conn,j) host=_host  conn=_conn
	lp.pos=Pos(j.pos.x,j.pos.y)  lp.name=j.name  lp.color=j.color end

local directions = {w=Pos(0,-1),a=Pos(-1,0),s=Pos(0,1),d=Pos(1,0)}
function M.keypressed(k,s,r)
	if directions[s] then
		if not love.keyboard.isScancodeDown('lshift') then lp.dir = s
		else local tgt = lp.pos + directions[s]
			local val = not chunks:tile(tgt); chunks:set_tile(tgt,val)
			conn:send(json.encode{type='tile',pos=tgt,tile=val}) end
	elseif s=='space' then cam.zoom = cam.zoom == 10 and 20 or 10 end end
function love.keyreleased(k,s)  if s==lp.dir then lp.dir=nil end end
function lp.update(dt)
	lp.movetimer = lp.movetimer - dt
	if lp.movetimer <= 0 and lp.dir then
		local d = directions[lp.dir] local newpos = lp.pos+d
		if chunks:tile(newpos) == false then
			conn:send(json.encode{type='move',pos=newpos})
			lp.pos = newpos  lp.movetimer = 1 / SPEED  end end end
local function draw_player(player,no_label)
	G.setColor(player.color) G.circle('fill',player.pos.x,player.pos.y,0.3)
	if not no_label then local f = G.getFont()
		local txtw,h = f:getWidth(player.name), f:getHeight()
		local centre = cam:world_to_screen(player.pos-Pos(0,.4))-Pos(0,h/2)
		local bb = Rect:from_centre_dims(centre,txtw,h)
		G.push() G.origin() G.setColor(0,0,0,0.8) bb:draw'fill'
		G.setColor(1,1,1) G.print(player.name,bb.tl:vals()) G.pop() end end
function lp.draw() draw_player(lp,true) end

function M.update(dt)
	lp.update(dt)
	local ev = host and host:service()  while ev do
		-- pprint(ev)
		if ev.type == 'receive' then local j = json.decode(ev.data)
			local pos  if j.pos then pos = Pos(j.pos.x,j.pos.y) end
				if j.type == 'player' 	then players[j.name] = {name=j.name,pos=pos,color=j.color}
			elseif j.type == 'unplayer' then players[j.from] = nil
			elseif j.type == 'move' 	then players[j.from].pos = pos
			elseif j.type == 'chunk'	then chunks:add(pos,{d=rle.decode(j.d)})
			elseif j.type == 'unchunk'	then chunks:remove(pos)
			elseif j.type == 'tile'		then chunks:set_tile(pos,j.tile)
			end
		end
		ev = host and host:service()
	end
end
function M.draw()
	G.clear(1,1,1); G.origin()
	cam.pos = lp.pos; cam:apply_trans()

	local tl,br = cam:extents()
	tl = tl:floor()  br = br:ceil()
	for x=tl.x,br.x do for y=tl.y,br.y do
		local t = chunks:tile(Pos(x,y))
		if t ~= nil then G.setColor(colors[t~=(x<0)]) G.rectangle('fill',x-0.5,y-0.5,1,1) end end end
	lp.draw()
	for _,player in pairs(players) do draw_player(player) end
	-- G.origin() G.setColor(1,0,0)
	-- G.print(tostring(lp.pos),100,100)
	-- G.setColor(0,0,0,0.8)
	-- G.rectangle('fill',0,0,100,100)
	-- G.setColor(1,1,1)
	-- for cx=-7,7 do for cy=-7,7 do local p=Pos(cx,cy) if chunks:get(p) then
	-- 	p = (p + Pos(7,7))*10
	-- 	G.setColor(1,1,1) G.rectangle('fill',p.x,p.y,10,10)
	-- 	G.setColor(0,0,1) G.rectangle('line',p.x,p.y,10,10)
	-- 	end end end
	-- local p = (lp.pos/common.SIZE+Pos(7,7))*10
	-- G.setColor(1,0,0) G.rectangle('fill',p.x-1,p.y-1,2,2)
end

return M