summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/camera.lua16
-rw-r--r--client/drawing.lua19
-rw-r--r--client/main.lua22
-rw-r--r--common/.map.lua.kak.Xd2mKc5
-rw-r--r--common/chunk.lua15
-rw-r--r--common/class.lua23
-rw-r--r--common/coords.lua34
-rw-r--r--common/map.lua6
-rw-r--r--server/noise.lua34
-rw-r--r--server/server.lua41
10 files changed, 140 insertions, 75 deletions
diff --git a/client/camera.lua b/client/camera.lua
index 6309e38..528b45b 100644
--- a/client/camera.lua
+++ b/client/camera.lua
@@ -1,15 +1,15 @@
local coords = require"common.coords"
+local class = require"common.class"
-- in screen units
local screen_width, screen_height = love.graphics.getDimensions()
-- zoom is screen pixels per world unit
-local Camera = {}
-Camera.__index = Camera
-function Camera.make(pos,zoom)
- pos = pos or coords.Pos.make(0,0)
+local Camera = class()
+function Camera.make(cls,pos,zoom)
+ pos = pos or coords.Pos:make(0,0)
zoom = zoom or 30
- return setmetatable({pos=pos,zoom=zoom},Camera)
+ return setmetatable({pos=pos,zoom=zoom},cls)
end
function Camera.apply_trans(self)
love.graphics.origin()
@@ -21,7 +21,7 @@ function Camera.apply_trans(self)
love.graphics.translate(-self.pos.x,-self.pos.y)
end
-local screen_offset = coords.Pos.make(screen_width/2,screen_height/2)
+local screen_offset = coords.Pos:make(screen_width/2,screen_height/2)
function Camera.screen_to_world(self,pos)
return (pos-screen_offset)/self.zoom + self.pos
end
@@ -31,8 +31,8 @@ end
function Camera.extents(self)
-- returns top left and bottom right pos's in world coords
- return self:screen_to_world(coords.Pos.make(0,0)),
- self:screen_to_world(coords.Pos.make(screen_width,screen_height))
+ return self:screen_to_world(coords.Pos:make(0,0)),
+ self:screen_to_world(coords.Pos:make(screen_width,screen_height))
end
diff --git a/client/drawing.lua b/client/drawing.lua
index 111b2e2..bbcf03a 100644
--- a/client/drawing.lua
+++ b/client/drawing.lua
@@ -33,7 +33,6 @@ local colors = {
c(255,128,0), -- orange
c(192,192,64), -- yellow
c(0,192,0), -- green
-
c(0,192,192), -- teal
c(64,64,255), -- blue
c(192,0,192), -- purple
@@ -67,14 +66,14 @@ end
local function draw_chunk(camera,the_chunk)
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 trh = coords.Pos:make(br.x,tl.y):to_hex():round()
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 h = coords.Hex:make(q,r)
local t = the_chunk:at(h)
if type(t) == "number" then
draw_hex(h:to_pos(),colors[t],camera.zoom)
@@ -84,6 +83,20 @@ local function draw_chunk(camera,the_chunk)
end
end
+ if _G.debugmode then
+ 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 c00 = p(-0.5,-0.5)
+ local c01 = p(-0.5,h)
+ local c10 = p(h,-0.5)
+ local c11 = p(h,h)
+
+ love.graphics.polygon("line",
+ c00.x,c00.y, c01.x,c01.y, c11.x,c11.y, c10.x, c10.y)
+ end
+
end
diff --git a/client/main.lua b/client/main.lua
index 2fad49e..7af1bd4 100644
--- a/client/main.lua
+++ b/client/main.lua
@@ -10,7 +10,7 @@ local local_player = nil
local drawing = require"drawing"
local coords = require"common.coords"
local Pos = coords.Pos
-local camera = require"camera".Camera.make()
+local camera = require"camera".Camera:make()
local Chunk = require"common.chunk".Chunk
local util = require"util"
@@ -24,10 +24,10 @@ local host,peer
local chunk
-local f3mode = false
+_G.debugmode = false
function love.keypressed(key,scancode,isrepeat)
- if scancode == "f3" then f3mode = not f3mode end
+ if scancode == "f3" then _G.debugmode = not _G.debugmode end
end
local function draw_player(pl,islocal)
@@ -45,7 +45,8 @@ end
local remote_players = {}
local function update_local_player(pl,dt)
- local SPEED = 10 -- pixels/sec
+ local SPEED = 10 -- units/sec
+ if love.keyboard.isScancodeDown("lshift") then SPEED = 100 end
local function kd(code)
if love.keyboard.isScancodeDown(code) then return 1 else return 0 end
end
@@ -85,10 +86,11 @@ function love.update(dt)
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)
end
if chunk then
- local mh = camera:screen_to_world(Pos.make(love.mouse.getPosition())):to_hex():round()
+ 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)
@@ -108,7 +110,7 @@ function love.update(dt)
local op = j.t
if op == "join" then
local pl = j.pl
- remote_players[pl.id] = {pos=coords.Pos.make(pl.x,pl.y),color=pl.color,id=pl.id}
+ remote_players[pl.id] = {pos=coords.Pos:make(pl.x,pl.y),color=pl.color,id=pl.id}
elseif op == "leave" then
local id = j.id
remote_players[id]=nil
@@ -119,11 +121,11 @@ function love.update(dt)
remote_players[id].pos.y = y
elseif op == "you" then
local pl = j.pl
- local_player = {pos=coords.Pos.make(pl.x,pl.y),color=pl.color,id=pl.id}
+ 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)
elseif op == "settile" then
- local h = coords.Hex.make(j.q,j.r)
+ local h = coords.Hex:make(j.q,j.r)
chunk:set_at(h,j.tile)
end
end
@@ -152,12 +154,12 @@ function love.draw()
love.graphics.setColor(1,0,0)
love.graphics.rectangle("fill",0,0,1,1)
- local sm = Pos.make(love.mouse.getPosition())
+ local sm = Pos:make(love.mouse.getPosition())
local wm = camera:screen_to_world(sm)
local hm = wm:to_hex()
love.graphics.origin()
- if f3mode and local_player then
+ if _G.debugmode and local_player then
util.print_good({
"ms "..tostring(sm),
"mw "..tostring(wm),
diff --git a/common/.map.lua.kak.Xd2mKc b/common/.map.lua.kak.Xd2mKc
new file mode 100644
index 0000000..aa2bfb0
--- /dev/null
+++ b/common/.map.lua.kak.Xd2mKc
@@ -0,0 +1,5 @@
+-- a Map is a 2d array of chunks
+-- it handles loading and unloading of chunks
+-- the specifics of which are then implemented separately for client and server
+-- it will probably also do things relating to entities and multiblock things
+
diff --git a/common/chunk.lua b/common/chunk.lua
index 8e2ec40..1d3faa6 100644
--- a/common/chunk.lua
+++ b/common/chunk.lua
@@ -1,6 +1,7 @@
local json = require"common.dkjson"
+local class = require"common.class"
-local CHUNK_SIZE = 128
+local CHUNK_SIZE = 64
-- for now tiles shall be booleans
@@ -15,10 +16,9 @@ local function index(offq,offr)
return CHUNK_SIZE*offq + offr + 1
end
-local Chunk = {}
-Chunk.__index = Chunk
-function Chunk.make(tiles)
- return setmetatable({tiles=tiles},Chunk)
+local Chunk = class()
+function Chunk.make(cls,tiles)
+ return setmetatable({tiles=tiles},cls)
end
function Chunk.at(self,hoffs)
if not index_ok(hoffs.q,hoffs.r) then return nil end
@@ -35,11 +35,12 @@ end
function Chunk.from_packet_data(packet)
-- assuming packet has already been json.decoded
-- since otherwise how would we know it's a chunk packet
- return Chunk.make(packet.tiles)
+ return Chunk:make(packet.tiles)
end
return {
Chunk=Chunk,
SIZE=CHUNK_SIZE,
- index=index
+ index=index,
+ index_ok=index_ok,
}
diff --git a/common/class.lua b/common/class.lua
new file mode 100644
index 0000000..37cf7bd
--- /dev/null
+++ b/common/class.lua
@@ -0,0 +1,23 @@
+local function class()
+ local T = {}
+ T.__index = T
+ return T
+end
+
+local function extend(Base)
+ local T = {}
+ T.__index = T
+ for k,v in pairs(Base) do
+ if k:sub(1,2) == "__" and k~="__index" then
+ T[k]=v
+ end
+ end
+ setmetatable(T,{__index=Base})
+end
+
+return setmetatable({
+ class=class,
+ extend=extend
+},{__call=class})
+
+
diff --git a/common/coords.lua b/common/coords.lua
index 2399e43..351aa53 100644
--- a/common/coords.lua
+++ b/common/coords.lua
@@ -1,3 +1,5 @@
+local class = require"common.class"
+
-- Hex: q,r,s. invariant that q+r+s=0
-- add, subtract
-- constructor takes 3 positions and rounds to closest hex centre.
@@ -15,12 +17,11 @@ local Pos, Hex
local SR3 = math.sqrt(3)
-Hex={}
-Hex.__index = Hex
-function Hex.make(q,r,s)
+local Hex = class()
+function Hex.make(cls,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)
+ return setmetatable({q=q,r=r,s=s},cls)
end
function Hex.round(self)
-- return a new Hex rounded to integer coordinates
@@ -40,32 +41,31 @@ function Hex.round(self)
rs = -rq-rr
end
- return Hex.make(rq,rr,rs)
+ 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)
+ 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.__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)
+Pos = class()
+function Pos.make(cls,x,y)
+ return setmetatable({x=x,y=y},cls)
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.__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)
+ return Pos:make(a*b.x,a*b.y)
elseif type(b) == "number" then
- return Pos.make(a.x*b,a.y*b)
+ return Pos:make(a.x*b,a.y*b)
else
error("can only multiply Pos by scalar")
end
@@ -81,7 +81,7 @@ function Pos.dot(self,other) return self.x*other.x + self.y*other.y 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)
+ return Hex:make(q,r,-q-r)
end
function Pos.__tostring(self) return string.format("(%.2f,%.2f)",self.x,self.y) end
diff --git a/common/map.lua b/common/map.lua
new file mode 100644
index 0000000..fe4b9e0
--- /dev/null
+++ b/common/map.lua
@@ -0,0 +1,6 @@
+-- a Map is a 2d array of chunks
+-- it handles loading and unloading of chunks
+-- the specifics of which are then implemented separately for client and server
+-- it will probably also do things relating to entities and multiblock things
+
+
diff --git a/server/noise.lua b/server/noise.lua
index 1480448..8a83b60 100644
--- a/server/noise.lua
+++ b/server/noise.lua
@@ -1,11 +1,12 @@
local Pos = require"common.coords".Pos
+local class = require"common.class"
local tau = 2*math.pi
math.randomseed(os.time())
local function random_unit_vec()
local theta = math.random()*tau
- return Pos.make(math.cos(theta),math.sin(theta))
+ return Pos:make(math.cos(theta),math.sin(theta))
end
local function lerp(a,b,t) return (1-t)*a + t*b end
local function smoothstep(x)
@@ -15,14 +16,13 @@ local function smoothstep(x)
end
local function slerp(a,b,t) return lerp(a,b,smoothstep(t)) end
-local NoiseGen = {}
-NoiseGen.__index = NoiseGen
-function NoiseGen.make()
+local PerlinNoise = class()
+function PerlinNoise.make(cls)
local grid = {}
setmetatable(grid,{__index=function(t,k) t[k] = {} return t[k] end})
- return setmetatable({grid=grid},NoiseGen)
+ return setmetatable({grid=grid},cls)
end
-function NoiseGen.vertex(self,ix,iy)
+function PerlinNoise.vertex(self,ix,iy)
local v = self.grid[ix][iy]
if v then return v end
vv = random_unit_vec()
@@ -30,7 +30,7 @@ function NoiseGen.vertex(self,ix,iy)
return vv
end
-function NoiseGen.at(self,x,y)
+function PerlinNoise.at(self,x,y)
local x0 = math.floor(x)
local y0 = math.floor(y)
local x1 = x0 + 1
@@ -41,7 +41,7 @@ function NoiseGen.at(self,x,y)
local v10 = self:vertex(x1,y0)
local v11 = self:vertex(x1,y1)
- local p = Pos.make
+ local p = function(...) return Pos:make(...) end
local d00 = v00:dot(p(x-x0,y-y0))
local d01 = v01:dot(p(x-x0,y-y1))
local d10 = v10:dot(p(x-x1,y-y0))
@@ -53,17 +53,9 @@ function NoiseGen.at(self,x,y)
return z
end
-local NoiseAgg = {}
-NoiseAgg.__index = NoiseAgg
-function NoiseAgg.make(things)
- return setmetatable({things=things or {}},NoiseAgg)
-end
-function NoiseAgg.make_perlin_octaves(nocts)
- local things = {}
- for i=1,nocts do
- table.insert(things,{amp=2^i,scale=2^(nocts-i),gen=NoiseGen.make()})
- end
- return NoiseAgg.make(things)
+local NoiseAgg = class()
+function NoiseAgg.make(cls,things)
+ return setmetatable({things=things or {}},cls)
end
function NoiseAgg.at(self,x,y)
local n = 0
@@ -72,7 +64,7 @@ function NoiseAgg.at(self,x,y)
for _,thing in ipairs(self.things) do
local gen,scale,amp = thing.gen,thing.scale,thing.amp
n = n + amp
- t = t + gen:at(x*scale,y*scale)*amp
+ t = t + gen:at(x/scale,y/scale)*amp
end
return t/n
end
@@ -93,4 +85,4 @@ end
-- io.write("\n")
-- end
-return {NoiseGen=NoiseGen,NoiseAgg=NoiseAgg}
+return {PerlinNoise=PerlinNoise,NoiseAgg=NoiseAgg}
diff --git a/server/server.lua b/server/server.lua
index 67860ea..08f75c0 100644
--- a/server/server.lua
+++ b/server/server.lua
@@ -60,19 +60,42 @@ local function player_move_packet(player,x,y)
return json.encode{t="move",id=player.id,x=x,y=y}
end
+
+-- worldgen
local the_tiles = {}
-local ng = noise.NoiseAgg.make_perlin_octaves(4)
-for q = 1,chunk.SIZE-1 do
- for r = 1,chunk.SIZE-1 do
- local p = coords.Hex.make(q,r):to_pos()
- local nv = ng:at(p.x/20,p.y/20)
- assert(nv ~= 1,"oopsy")
- the_tiles[chunk.index(q,r)] = nv > 0 and 1+math.floor(math.sqrt(nv)*8) or false
+local function p(amp,scale) return {scale=scale,amp=amp,gen=noise.PerlinNoise:make()} end
+local ng = noise.NoiseAgg:make{
+ p(1,20),
+ -- p(0.7,2),
+ p(0.5,15),
+ --p(2,200),
+}
+local ng2 = noise.NoiseAgg:make{p(1,20),p(0.5,15)}
+
+for q = 0,chunk.SIZE-1 do
+ for r = 0,chunk.SIZE-1 do
+ local p = coords.Hex:make(q,r):to_pos()
+ local ix = chunk.index(q,r)
+ local nv = ng:at(p.x,p.y)
+ if nv <= 0 then
+ the_tiles[ix] = false
+ else
+ local nv2 = ng2:at(p.x,p.y)
+ nv2 = math.max(-0.9999999,math.min(0.9999999,nv2*2.5))
+ nv2 = (nv2+1)/2
+ print(nv2)
+
+ local tv = 1+math.floor(nv2*8)
+ assert(1<=tv and tv<=8,"oopsy woopsy")
+ the_tiles[ix] = tv
+ end
end
end
-local the_chunk = Chunk.make(the_tiles)
+local the_chunk = Chunk:make(the_tiles)
print"generated chunk"
+
+
while true do
local ev = host:service(100)
if ev then
@@ -115,7 +138,7 @@ while true do
end
end
elseif op == "settile" then
- local h = coords.Hex.make(j.q,j.r)
+ local h = coords.Hex:make(j.q,j.r)
the_chunk:set_at(h,j.tile)
-- print(player.id,"settile",h,j.tile)
for i,otherplayer in ipairs(playerlist) do