diff options
author | ubq323 <ubq323@ubq323.website> | 2023-01-27 13:43:49 +0000 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2023-01-27 13:46:41 +0000 |
commit | d0916d568a00f5171b96fbc3bfc19ff263affc27 (patch) | |
tree | ef007be582d2b872ff2ac407def9d0ad64e3bc86 | |
parent | 0eab09311f6634aefe0e79ecafd975ab68b2812c (diff) |
coords, hexagons, drawing, chunks
-rw-r--r-- | client/conf.lua | 2 | ||||
-rw-r--r-- | client/drawing.lua | 40 | ||||
-rw-r--r-- | client/main.lua | 11 | ||||
-rw-r--r-- | common/chunk.lua | 30 | ||||
-rw-r--r-- | common/coords.lua | 90 |
5 files changed, 172 insertions, 1 deletions
diff --git a/client/conf.lua b/client/conf.lua index 5c58cb3..e207e09 100644 --- a/client/conf.lua +++ b/client/conf.lua @@ -1,3 +1,3 @@ function love.conf(t) - t.window.title = "rectangle emulator" + t.window.title = "hexagon emulator" end diff --git a/client/drawing.lua b/client/drawing.lua new file mode 100644 index 0000000..e65e716 --- /dev/null +++ b/client/drawing.lua @@ -0,0 +1,40 @@ +local coords=require"common.coords" +local Pos = coords.Pos +local chunk = require"common.chunk" + +local tau=math.pi*2 + +local corners = {} +for i=0,5 do + local angle = tau*(i+0.5)/6 + local x = math.cos(angle) + local y = math.sin(angle) + table.insert(corners,x) + table.insert(corners,y) +end + +local function draw_hex(cpos,size) + love.graphics.push() + love.graphics.setLineWidth(0.1) + love.graphics.translate(cpos.x,cpos.y) + love.graphics.scale(size) + love.graphics.setColor(love.math.colorFromBytes(0xe7,0x9e,0)) + love.graphics.polygon("fill",corners) + love.graphics.setColor(0,0,0) + love.graphics.polygon("line",corners) + love.graphics.pop() +end + +local function draw_chunk(the_chunk) + for q = 0,chunk.SIZE-1 do + for r = 0,chunk.SIZE-1 do + local t = the_chunk.tiles[chunk.index(q,r)] + if t then + local p = coords.Hex.make(q,r):to_pos() + draw_hex(p*10,10) + end + end + end +end + +return {draw_hex=draw_hex,draw_chunk=draw_chunk} diff --git a/client/main.lua b/client/main.lua index 5884186..b5d322e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -6,6 +6,9 @@ local PLAYER_SIZE = 30 local local_player = nil + +math.randomseed(os.time()) + -- { -- pos={100,100}, -- color={love.math.colorFromBytes(0xdf,0x73,0xff)}, @@ -13,6 +16,9 @@ local local_player = nil local host,peer + +local chunk = require"common.chunk".Chunk.make() + local function draw_player(pl,me) local hplsz = PLAYER_SIZE/2 love.graphics.setColor(pl.color) @@ -103,12 +109,17 @@ function love.update(dt) end function love.draw() + love.graphics.clear(1,1,1) if local_player then draw_player(local_player,true) end for _,pl in pairs(remote_players) do draw_player(pl) end + + -- require"drawing".drawhex({x=200,y=200},40) + require"drawing".draw_chunk(chunk) + end function love.load() diff --git a/common/chunk.lua b/common/chunk.lua new file mode 100644 index 0000000..38cdaf0 --- /dev/null +++ b/common/chunk.lua @@ -0,0 +1,30 @@ +local CHUNK_SIZE = 128 + +-- for now tiles shall be booleans + +local function index(offq,offr) + -- indexes start at 0 + -- and go up to (CHUNK_SIZE^2)-1 + assert(0<=offq and 0<=offr and offq<CHUNK_SIZE and offr<CHUNK_SIZE, "chunk hex offset out of bounds") + return CHUNK_SIZE*offq + offr +end + +local Chunk = {} +Chunk.__index = Chunk +function Chunk.make() + -- todo actual worldgen + local tiles = {} + for i=0,CHUNK_SIZE-1 do + for j=0,CHUNK_SIZE-1 do + tiles[index(i,j)] = (math.random()<0.5) + end + end + + return setmetatable({tiles=tiles},Chunk) +end + +return { + Chunk=Chunk, + SIZE=CHUNK_SIZE, + index=index +} diff --git a/common/coords.lua b/common/coords.lua new file mode 100644 index 0000000..1bb9154 --- /dev/null +++ b/common/coords.lua @@ -0,0 +1,90 @@ +-- Hex: q,r,s. invariant that q+r+s=0 +-- add, subtract +-- constructor takes 3 positions and rounds to closest hex centre. + +-- round to nearest int, rounding .5 away from 0. +local function round(x) + if x<0 then + return math.ceil(x-0.5) + else + return math.floor(x+0.5) + end +end + +local Pos, Hex + +local SR3 = math.sqrt(3) + +Hex={} +Hex.__index = Hex +function Hex.make(q,r,s) + s=s or -q-r + assert(q+r+s==0,"hex coord doesn't meet invariant") + return setmetatable({q=q,r=r,s=s},Hex) +end +function Hex.round(self) + -- return a new Hex rounded to integer coordinates + local fq,fr,fs = self.q,self.r,self.s + -- round all to nearest integer + -- find which was changed the most, reset that one to be coherent with the other two. + local abs = math.abs + + local rq,rr,rs = round(fq),round(fr),round(fs) + local dq,dr,ds = abs(fq-rq), abs(fr-rr), abs(fs-rs) + + if dq>dr and dq>ds then + rq = -rr-rs + elseif dr>ds then + rr = -rq-rs + else + rs = -rq-rr + end + + return Hex.make(rq,rr,rs) +end + +function Hex.to_pos(self) + local x = self.q*SR3 + self.r*(SR3/2) + local y = self.r*(3/2) + return Pos.make(x,y) +end + +function Hex.__add(self,other) return Hex.make(self.q+other.q, self.r+other.r, self.s+other.s) end +function Hex.__sub(self,other) return Hex.make(self.q-other.q, self.r-other.r, self.s-other.s) end +function Hex.__tostring(self) return string.format("H(%.2f,%.2f)",self.q,self.r) end + + +Pos = {} +Pos.__index=Pos +function Pos.make(x,y) + return setmetatable({x=x,y=y},Pos) +end +function Pos.__add(self,other) return Pos.make(self.x+other.x,self.y+other.y) end +function Pos.__sub(self,other) return Pos.make(self.x-other.x,self.y-other.y) end +function Pos.__mul(a,b) + if type(a) == "number" then + return Pos.make(a*b.x,a*b.y) + elseif type(b) == "number" then + return Pos.make(a.x*b,a.y*b) + else + error("can only multiply Pos by scalar") + end +end +function Pos.__div(a,b) + assert(type(b) == "number","can only divide Pos by scalar, and can't divide scalar by Pos") + return a*(1/b) +end +function Pos.lensq(self) return self.x^2 + self.y^2 end +function Pos.len(self) return math.sqrt(self:lensq()) end +function Pos.to_hex(self) + local q = self.x*(SR3/3) - self.y*(1/3) + local r = (2/3)*self.y + return Hex.make(q,r,-q-r) +end +function Pos.__tostring(self) return string.format("(%.2f,%.2f)",self.x,self.y) end + + + +return {Hex=Hex,Pos=Pos} + + |