From 0dc1276df57aa16b4f0eaecf54fb5cd8f00115c6 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Sat, 4 Feb 2023 23:03:19 +0000 Subject: many many optimizations and refactorings; introduction of Map to support multiple chunks, modify worldgen and client drawing to support multiple chunks --- client/drawing.lua | 44 ++++++++++++++++++------------ client/main.lua | 53 +++++++++++++++++++++++------------- common/chunk.lua | 23 +++++++++------- common/class.lua | 7 +++++ common/constants.lua | 4 +++ common/coords.lua | 77 ++++++++++++++++++++++++++++++++++++++++++++-------- common/map.lua | 51 ++++++++++++++++++++++++++++++++++ server/server.lua | 55 +++++++++++++------------------------ server/worldgen.lua | 49 +++++++++++++++++++++++++++++++++ 9 files changed, 269 insertions(+), 94 deletions(-) create mode 100644 common/constants.lua create mode 100644 server/worldgen.lua diff --git a/client/drawing.lua b/client/drawing.lua index bbcf03a..5334a93 100644 --- a/client/drawing.lua +++ b/client/drawing.lua @@ -1,6 +1,7 @@ local coords=require"common.coords" local Pos = coords.Pos local chunk = require"common.chunk" +local CHUNK_SIZE = require"common.constants".CHUNK_SIZE local tau=math.pi*2 @@ -38,20 +39,24 @@ local colors = { c(192,0,192), -- purple c(128,128,128), -- grey } - - +-- precompute sins and cosines +local _coss,_sins = {},{} +for i=0,5 do + local angle = tau*(i+0.5)/6 + _coss[i+1] = math.cos(angle) + _sins[i+1] = math.sin(angle) +end -local zthr0 = 2 -local zthr1 = 5 +local zthr0 = 2.7 +local zthr1 = 6 local _corners = {} local function draw_hex(cpos,color,zoom) local cx,cy = cpos.x,cpos.y - for i=0,5 do - local angle = tau*(i+0.5)/6 - local x = cx + math.cos(angle) - local y = cy + math.sin(angle) - _corners[2*i+1] = x - _corners[2*i+2] = y + for i=1,6 do + local x = cx + _coss[i] + local y = cy + _sins[i] + _corners[2*i-1] = x + _corners[2*i ] = y end -- love.graphics.setColor(love.math.colorFromBytes(0xe7,0x9e,0)) love.graphics.setColor(color or {0.91,0.62,0}) @@ -63,22 +68,27 @@ local function draw_hex(cpos,color,zoom) end end -local function draw_chunk(camera,the_chunk) +local function draw_map(camera,map) local tl,br = camera:extents() local tlh,brh = tl:to_hex():round(), br:to_hex():round() local trh = coords.Pos:make(br.x,tl.y):to_hex():round() + local _h = coords.Hex:new() + local _p = coords.Pos:new() + for r = tlh.r-1,brh.r+1 do local rowidx = r-tlh.r local minq = tlh.q - math.floor((rowidx+1)/2) local maxq = minq+(trh.q-tlh.q)+1 for q = minq,maxq do - local h = coords.Hex:make(q,r) - local t = the_chunk:at(h) + -- local h = coords.Hex:make(q,r) + _h:init(q,r) + _h:to_pos(_p) + local t = map:at(_h) if type(t) == "number" then - draw_hex(h:to_pos(),colors[t],camera.zoom) + draw_hex(_p,colors[t],camera.zoom) elseif t then - draw_hex(h:to_pos(),nil,camera.zoom) + draw_hex(_p,nil,camera.zoom) end end end @@ -87,7 +97,7 @@ local function draw_chunk(camera,the_chunk) love.graphics.setColor(0,1,0) local function p(q,r) return coords.Hex:make(q,r):to_pos() end - local h = chunk.SIZE-0.5 + local h = CHUNK_SIZE-0.5 local c00 = p(-0.5,-0.5) local c01 = p(-0.5,h) local c10 = p(h,-0.5) @@ -100,4 +110,4 @@ local function draw_chunk(camera,the_chunk) end -return {draw_hex=draw_hex,draw_chunk=draw_chunk} +return {draw_hex=draw_hex,draw_map=draw_map} diff --git a/client/main.lua b/client/main.lua index 7af1bd4..da1b91d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -13,6 +13,7 @@ local Pos = coords.Pos local camera = require"camera".Camera:make() local Chunk = require"common.chunk".Chunk local util = require"util" +local Map = require"common.map".Map -- local pprint=require"common.pprint" -- pprint.setup{show_all=true} @@ -20,9 +21,9 @@ local util = require"util" math.randomseed(os.time()) -local host,peer +local map = Map:make() -local chunk +local host,peer _G.debugmode = false @@ -70,7 +71,7 @@ local function update_local_player(pl,dt) end -local function sync_local_player(pl,peer) +local function sync_local_player(pl) -- send updated info about local player to server if pl.pos_dirty then peer:send(json.encode{t="ppos",x=pl.pos.x,y=pl.pos.y}) @@ -81,26 +82,39 @@ local function send_settile(hpos,tile) peer:send(json.encode{t="settile",q=hpos.q,r=hpos.r,tile=tile}) end + +-- hack +local time_since_last_chunkreq = 100 function love.update(dt) + time_since_last_chunkreq = time_since_last_chunkreq + dt if local_player then update_local_player(local_player,dt) if love.keyboard.isScancodeDown"q" then camera.zoom = camera.zoom*1.05 end if love.keyboard.isScancodeDown"e" then camera.zoom = camera.zoom/1.05 end camera.zoom = math.max(2.25,math.min(50,camera.zoom)) - sync_local_player(local_player,peer) + sync_local_player(local_player) + end + + local mh = camera:screen_to_world(Pos:make(love.mouse.getPosition())):to_hex():round() + if false== map:at(mh) and love.mouse.isDown(1) then + print("place at",mh) + map:set_at(mh,true) + -- print(mh,true) + send_settile(mh,true) + elseif map:at(mh) and love.mouse.isDown(2) then + map:set_at(mh,false) + -- print(mh,false) + send_settile(mh,false) end - if chunk then - local mh = camera:screen_to_world(Pos:make(love.mouse.getPosition())):to_hex():round() - if false== chunk:at(mh) and love.mouse.isDown(1) then - chunk:set_at(mh,true) - -- print(mh,true) - send_settile(mh,true) - elseif chunk:at(mh) and love.mouse.isDown(2) then - chunk:set_at(mh,false) - -- print(mh,false) - send_settile(mh,false) + + if local_player then + local player_cp = local_player.pos:to_hex():containing_chunk() + if map:chunk(player_cp) == nil and time_since_last_chunkreq > 1 then + time_since_last_chunkreq = 0 + peer:send(json.encode{t="reqchunk",u=player_cp.u,v=player_cp.v}) end end + repeat local ev = host:service() @@ -123,10 +137,11 @@ function love.update(dt) local pl = j.pl local_player = {pos=coords.Pos:make(pl.x,pl.y),color=pl.color,id=pl.id} elseif op == "chunk" then - chunk = Chunk.from_packet_data(j) + local ch = Chunk.from_packet_data(j) + map:add_chunk(ch.cp,ch) elseif op == "settile" then local h = coords.Hex:make(j.q,j.r) - chunk:set_at(h,j.tile) + map:set_at(h,j.tile) end end until not ev @@ -140,9 +155,7 @@ function love.draw() end camera:apply_trans() - if chunk then - drawing.draw_chunk(camera,chunk) - end + drawing.draw_map(camera,map) if local_player then draw_player(local_player,true) @@ -169,6 +182,8 @@ function love.draw() "ph "..tostring(local_player.pos:to_hex()).." "..tostring(local_player.pos:to_hex():round()), "-", "voob "..tostring(camera.zoom), + "-", + "fps "..tostring(love.timer.getFPS()), },10,10) end end diff --git a/common/chunk.lua b/common/chunk.lua index 1d3faa6..affdab8 100644 --- a/common/chunk.lua +++ b/common/chunk.lua @@ -1,9 +1,8 @@ local json = require"common.dkjson" local class = require"common.class" +local coords = require"common.coords" -local CHUNK_SIZE = 64 - --- for now tiles shall be booleans +local CHUNK_SIZE = require"common.constants".CHUNK_SIZE local function index_ok(offq,offr) return 0<=offq and 0<=offr and offq