diff options
| author | ubq323 <ubq323@ubq323.website> | 2025-06-08 22:02:44 +0100 | 
|---|---|---|
| committer | ubq323 <ubq323@ubq323.website> | 2025-06-08 22:02:44 +0100 | 
| commit | 5189d8102fe68529d463a99a0dc7e0ec5cae22d9 (patch) | |
| tree | 3c35b03299d5c3160c577d7318bf1af6989a8443 | |
| parent | 22d767b3e10959cd1545b5b1986bfbc44ff41491 (diff) | |
many client changes
| -rw-r--r-- | client/conf.lua | 2 | ||||
| -rw-r--r-- | client/logo.png | bin | 0 -> 278 bytes | |||
| -rw-r--r-- | client/main.lua | 130 | ||||
| -rw-r--r-- | client/main_1.lua | 85 | 
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 Binary files differnew file mode 100644 index 0000000..0146043 --- /dev/null +++ b/client/logo.png 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  | 
