summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2025-06-08 22:02:44 +0100
committerubq323 <ubq323@ubq323.website>2025-06-08 22:02:44 +0100
commit5189d8102fe68529d463a99a0dc7e0ec5cae22d9 (patch)
tree3c35b03299d5c3160c577d7318bf1af6989a8443
parent22d767b3e10959cd1545b5b1986bfbc44ff41491 (diff)
many client changes
-rw-r--r--client/conf.lua2
-rw-r--r--client/logo.pngbin0 -> 278 bytes
-rw-r--r--client/main.lua130
-rw-r--r--client/main_1.lua85
4 files changed, 143 insertions, 74 deletions
diff --git a/client/conf.lua b/client/conf.lua
index faccea9..dca36d1 100644
--- a/client/conf.lua
+++ b/client/conf.lua
@@ -1 +1 @@
-function love.conf(t) t.window.msaa=8 end
+function love.conf(t) t.window.msaa=8 t.window.title='duet' end
diff --git a/client/logo.png b/client/logo.png
new file mode 100644
index 0000000..0146043
--- /dev/null
+++ b/client/logo.png
Binary files differ
diff --git a/client/main.lua b/client/main.lua
index 2a30aa2..262d849 100644
--- a/client/main.lua
+++ b/client/main.lua
@@ -1,81 +1,65 @@
-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 G = love.graphics
+local utf8 = require'utf8'
+
+local logo = G.newImage"logo.png" logo:setFilter'nearest'
+
+local function c(...) return {love.math.colorFromBytes(...)} end
+-- taken from breadquest
+local colors = { c(255,64,64), c(255,128,0), c(192,192,64), c(0,192,0),
+ c(0,192,192), c(64,64,255), c(192,0,192), c(128,128,128)}
+
+local state = {color=1,focused=nil,name='Susan'}
+
+local LogoImage = {}
+function LogoImage.draw() G.setColor(1,1,1) G.draw(logo, 120, 50, 0, 12) end
-local SPEED = 8 -- tiles per second
-local colors = {[true]={141/255,128/255,22/255}, [false]={71/255,50/255,122/255}}
+local ColorButton = class()
+function ColorButton.make(cls, idx)
+ local size, gap = 40, 10
+ local tl = Pos(100,240) + (idx-1)*Pos(size+gap,0)
+ local bb = Rect:from_pos(tl,tl+Pos(size,size))
+ return setmetatable({bb=bb,idx=idx},cls) end
+function ColorButton.draw(self)
+ G.setColor(colors[self.idx]) self.bb:draw'fill'
+ if self.idx == state.color then G.setColor(0,0,0) local d=5
+ G.line(self.bb.x0+d,self.bb.y0+d,self.bb.x1-d,self.bb.y1-d)
+ G.line(self.bb.x0+d,self.bb.y1-d,self.bb.x1-d,self.bb.y0+d) end end
+function ColorButton.click(self) state.color = self.idx end
-local host = enet.host_create()
-local conn = host:connect('localhost:19683')
+local font = G.newFont(24)
+local NameField = class()
+function NameField.make(cls,org)
+ local self = setmetatable({org=org},cls) self:setbb() return self end
+function NameField.setbb(self) local width = 12+math.max(200,font:getWidth(state.name))
+ self.bb=Rect:from_xywh(self.org.x,self.org.y,width,font:getHeight()) end
+function NameField.draw(self) G.setColor(0,0,0) self.bb:draw'line' local d=3
+ G.setFont(font) G.print(state.name,self.bb.x0+d,self.bb.y0)
+ if self == state.focused then local w = 2*d+self.bb.x0+font:getWidth(state.name)
+ G.line(w,self.bb.y0+d,w,self.bb.y1-d) end end
+function NameField.input(self,text) state.name = state.name .. text self:setbb() end
+function NameField.key(self,key) if key == 'backspace' and #state.name > 0 then
+ state.name = state.name:sub(1,utf8.offset(state.name,-1)-1) self:setbb() end end
-local players = {}
-local chunks = common.ChunkMap()
-local lp = { pos=Pos(0,0), movetimer=0, dir=nil } -- local player
-local cam = Camera(nil, 20)
+local things = { NameField(Pos(100,400)), LogoImage }
+for i=1,#colors do table.insert(things, ColorButton(i)) end
-local directions = {w=Pos(0,-1),a=Pos(-1,0),s=Pos(0,1),d=Pos(1,0)}
-function love.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(p, c) G.setColor(c) G.circle('fill',p.x,p.y,0.3) end
-function lp.draw() draw_player(lp.pos, {0,1,0}) end
+local function draw_ui() for _,thing in ipairs(things) do
+ if thing.draw then thing:draw() end
+ if thing.bb and thing.bb:has(Pos(love.mouse.getPosition())) then
+ G.setColor(0,0,0) thing.bb:draw'line' end end end
-function love.update(dt)
- lp.update(dt)
- local ev = 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}
- 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:service()
- end
-end
-function love.draw()
- G.clear(1,1,1); G.origin()
- cam.pos = lp.pos; cam:apply_trans()
+local function which(p) for _,thing in ipairs(things) do
+ if thing.bb and thing.bb:has(p) then return thing end end end
+function love.draw() G.clear(1,1,1) draw_ui() end
+function love.mousepressed(x,y,button)
+ local thing = which(Pos(x,y)) if thing then state.focused = thing
+ if thing.click then thing:click() end end end
+love.keyboard.setKeyRepeat(true)
+function love.textinput(text) if state.focused and state.focused.input then
+ state.focused:input(text) end end
+function love.keypressed(key) if state.focused and state.focused.key then
+ state.focused:key(key) end end
- 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.pos,{0,1,1}) 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
diff --git a/client/main_1.lua b/client/main_1.lua
new file mode 100644
index 0000000..f5ee5a9
--- /dev/null
+++ b/client/main_1.lua
@@ -0,0 +1,85 @@
+local G = love.graphics
+local common = require 'common'
+local Camera = require'r.camera'
+local Pos = require'r.pos'
+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 host = enet.host_create()
+local conn = host:connect('localhost:19683')
+
+local players = {}
+local chunks = common.ChunkMap()
+local lp = { pos=Pos(0,0), movetimer=0, dir=nil } -- local player
+local cam = Camera(nil, 20)
+
+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(p, c) G.setColor(c) G.circle('fill',p.x,p.y,0.3) end
+function lp.draw() draw_player(lp.pos, {0,1,0}) end
+
+function M.update(dt)
+ lp.update(dt)
+ local ev = 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}
+ 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: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.pos,{0,1,1}) 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