summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--client/camera.lua2
-rw-r--r--client/main.lua149
-rw-r--r--client/msgbox.lua53
-rw-r--r--client/util.lua2
-rw-r--r--net.txt5
-rw-r--r--server/server.lua10
7 files changed, 196 insertions, 26 deletions
diff --git a/.gitignore b/.gitignore
index e4c3052..448f390 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+*.love
server/enet.so
server/world/*
flamegraph.pl
diff --git a/client/camera.lua b/client/camera.lua
index 528b45b..bb1d8a6 100644
--- a/client/camera.lua
+++ b/client/camera.lua
@@ -12,7 +12,7 @@ function Camera.make(cls,pos,zoom)
return setmetatable({pos=pos,zoom=zoom},cls)
end
function Camera.apply_trans(self)
- love.graphics.origin()
+ -- love.graphics.origin()
-- centre (0,0) in the middle of the screen
love.graphics.translate(screen_width/2,screen_height/2)
-- apply camera transformations
diff --git a/client/main.lua b/client/main.lua
index 27b93f9..9de4290 100644
--- a/client/main.lua
+++ b/client/main.lua
@@ -1,5 +1,6 @@
local enet = require"enet"
local json = require"common.dkjson"
+local utf8 = require"utf8"
local SERVER_HOSTNAME = "ubq323.website"
@@ -16,6 +17,7 @@ local Chunk = require"common.chunk".Chunk
local util = require"util"
local Map = require"common.map".Map
local movement = require"movement"
+local msgbox = require"msgbox"
-- local pprint=require"common.pprint"
-- pprint.setup{show_all=true}
@@ -23,11 +25,21 @@ local movement = require"movement"
local help_text = [[
controls:
-wasd: move left mouse: place
-q,e: zoom in/out right mouse: destroy
+wasd: move
shift: sprint
-F3: toggle debug
-F1: show/hide this help]]
+
+left mouse: place
+right mouse: destroy
+mousewheel: zoom in/out
+
+F1: show/hide this help
+F3: show/hide debug
+F11: toggle "big mode" (bad)
+
+enter: toggle chat]]
+
+
+
math.randomseed(os.time())
@@ -35,13 +47,62 @@ local map = Map:make()
local host,peer
+
+local selected_tile = 9
+
+-- normal: regular gameplay
+-- chat: chat box is open
+-- more modes may come
+local ui_mode = "normal"
+
_G.debugmode = false
-local show_controls = true
+local show_controls = false
+
+local this_chatmsg = ""
+local chatmsg_text = love.graphics.newText(love.graphics.getFont())
+
+local big_mode = false
+local orig_w,orig_h = love.graphics.getDimensions()
function love.keypressed(key,scancode,isrepeat)
- if scancode == "f3" then _G.debugmode = not _G.debugmode end
- if scancode == "f1" then show_controls = not show_controls end
+ if key == "f11" then
+ big_mode = not big_mode
+ if big_mode then
+ love.window.setMode(orig_w*2,orig_h*2)
+ else
+ love.window.setMode(orig_w,orig_h)
+ end
+ end
+ if ui_mode == "normal" then
+ if key == "f3" then _G.debugmode = not _G.debugmode end
+ if key == "f1" then show_controls = not show_controls end
+ for i = 1,9 do if key == tostring(i) then selected_tile = i end end
+ if key == "return" then
+ ui_mode = "chat"
+ this_chatmsg = ""
+ end
+ elseif ui_mode == "chat" then
+ if key == "return" then
+ ui_mode = "normal"
+ peer:send(json.encode{t="chat",msg=this_chatmsg})
+ -- msgbox.add("[me] "..this_chatmsg)
+ elseif key == "escape" then
+ ui_mode = "normal"
+ elseif key == "backspace" then
+ local boffs = utf8.offset(this_chatmsg,-1)
+ if boffs then
+ this_chatmsg = this_chatmsg:sub(1,boffs-1)
+ end
+
+ end
+ end
+end
+
+function love.textinput(text)
+ if ui_mode == "chat" then
+ this_chatmsg = this_chatmsg..text
+ end
end
local function draw_player(pl,islocal)
@@ -61,7 +122,7 @@ local remote_players = {}
local function update_local_player(pl,dt)
local SPEED = 8*math.sqrt(3) -- 8 hexagonheights per second
- if love.keyboard.isScancodeDown("lshift") then SPEED = SPEED*2 end
+ if love.keyboard.isDown("lshift") then SPEED = SPEED*2.5 end
local function kd(code)
if love.keyboard.isScancodeDown(code) then return 1 else return 0 end
end
@@ -96,25 +157,35 @@ local function send_settile(hpos,tile)
peer:send(json.encode{t="settile",q=hpos.q,r=hpos.r,tile=tile})
end
+function love.wheelmoved(dx,dy)
+ camera.zoom = camera.zoom * (1.15 ^ dy)
+ camera.zoom = math.max(2.5,math.min(50,camera.zoom))
+end
function love.update(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.5,math.min(50,camera.zoom))
- sync_local_player(local_player)
- end
+ msgbox.update(dt)
+ if ui_mode == "normal" then
+
+ -- movement and zoom in/out (keyboard input)
+ if local_player then
+ update_local_player(local_player,dt)
+ sync_local_player(local_player)
+ end
- local mh = camera:screen_to_world(Pos:make(love.mouse.getPosition())):to_hex():round()
- if map:at(mh) == 0 and love.mouse.isDown(1) then
- map:set_at(mh,9)
- send_settile(mh,9)
- elseif map:at(mh) ~= 0 and love.mouse.isDown(2) then
- map:set_at(mh,0)
- send_settile(mh,0)
+ -- mouse input
+ local msx,msy = love.mouse.getPosition()
+ if big_mode then msx,msy = msx/2,msy/2 end
+ local mh = camera:screen_to_world(Pos:make(msx,msy)):to_hex():round()
+ if map:at(mh) == 0 and love.mouse.isDown(1) then
+ map:set_at(mh,selected_tile)
+ send_settile(mh,selected_tile)
+ elseif map:at(mh) ~= 0 and love.mouse.isDown(2) then
+ map:set_at(mh,0)
+ send_settile(mh,0)
+ end
end
+ -- load and unload chunks
if local_player then
local player_cp = local_player.pos:to_hex():containing_chunk()
-- load chunks near to player (within 3x3 square)
@@ -140,6 +211,7 @@ function love.update(dt)
end
+ -- handle network packets
repeat
local ev = host:service()
if ev and ev.type == "receive" then
@@ -149,9 +221,11 @@ function love.update(dt)
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}
+ msgbox.add(pl.id.." joined")
elseif op == "leave" then
local id = j.id
remote_players[id]=nil
+ msgbox.add(id.." left")
elseif op == "move" then
local id,x,y = j.id,j.x,j.y
assert(remote_players[id],"wheeze "..id)
@@ -166,6 +240,9 @@ function love.update(dt)
elseif op == "settile" then
local h = coords.Hex:make(j.q,j.r)
map:set_at(h,j.tile)
+ elseif op == "chat" then
+ local msg,from = j.msg,j.from
+ msgbox.add("["..tostring(from).."] "..msg)
end
end
until not ev
@@ -174,6 +251,7 @@ end
function love.draw()
love.graphics.clear(1,1,1)
love.graphics.origin()
+ if big_mode then love.graphics.scale(2) end
if local_player then
camera.pos = local_player.pos
end
@@ -196,6 +274,8 @@ function love.draw()
local hm = wm:to_hex()
love.graphics.origin()
+ if big_mode then love.graphics.scale(2) end
+ util.print_good(tostring(selected_tile), 400,10)
if _G.debugmode and local_player then
util.print_good({
"ms "..tostring(sm),
@@ -208,19 +288,42 @@ function love.draw()
"voob "..tostring(camera.zoom),
"-",
"fps "..tostring(love.timer.getFPS()),
- "ping "..tostring(peer:round_trip_time())
+ "ping "..tostring(peer:round_trip_time()),
},10,10)
end
if show_controls then
util.print_good(help_text,300,200)
end
+
+ msgbox.draw()
+
+ if ui_mode ~= "normal" then
+ util.print_good(ui_mode, 700,10)
+ end
+
+ if ui_mode == "chat" then
+ local W,H = love.graphics.getDimensions()
+ chatmsg_text:set("- "..this_chatmsg)
+ local tw,th = chatmsg_text:getDimensions()
+ local y = H-th-30
+ love.graphics.setColor(0,0,0,0.8)
+ love.graphics.rectangle("fill",0,y,W,th)
+ love.graphics.setColor(1,1,1)
+ love.graphics.draw(chatmsg_text,0,y)
+ love.graphics.setColor(0.8,0.8,0.8)
+ love.graphics.line(tw,y,tw,y+th)
+ end
+
end
function love.load()
+ love.keyboard.setKeyRepeat(true)
-- require"profile".start(10,io.open("./trace","w"))
host = enet.host_create()
peer = host:connect(SERVER_HOSTNAME..":8473")
+ msgbox.add("connected to "..SERVER_HOSTNAME..":8473")
+ msgbox.add("press F1 for controls help")
end
function love.quit()
diff --git a/client/msgbox.lua b/client/msgbox.lua
new file mode 100644
index 0000000..720bfab
--- /dev/null
+++ b/client/msgbox.lua
@@ -0,0 +1,53 @@
+local font = love.graphics.getFont()
+
+
+local msgs = {}
+
+local function add(str)
+ table.insert(msgs, 1, {text=love.graphics.newText(font,str),time=10})
+end
+
+local margin_bottom = 70
+
+local function draw()
+ if #msgs == 0 then return end
+
+ local W,H = love.graphics.getDimensions()
+ local maxw = 0
+ local sumh = 0
+ for _,msg in ipairs(msgs) do
+ local text = msg.text
+ maxw = math.max(maxw,text:getWidth())
+ sumh = sumh + text:getHeight()
+ end
+ love.graphics.setColor(0,0,0,0.8)
+ love.graphics.rectangle("fill",0,H-sumh-margin_bottom,maxw,sumh)
+
+ love.graphics.setColor(1,1,1)
+ local cury = H
+ for _,msg in ipairs(msgs) do
+ local text = msg.text
+ local h = text:getHeight()
+ love.graphics.draw(text,0,cury-h-margin_bottom)
+ cury = cury - h
+ end
+end
+
+local function update(dt)
+ for ix = #msgs,1,-1 do
+ local m = msgs[ix]
+ m.time = m.time - dt
+ if m.time <= 0 then
+ msgs[ix] = nil
+ end
+ end
+end
+
+
+
+
+return {
+ draw=draw,
+ update=update,
+ add=add,
+}
diff --git a/client/util.lua b/client/util.lua
index f9ec088..8a18b96 100644
--- a/client/util.lua
+++ b/client/util.lua
@@ -6,7 +6,7 @@ local function print_good(lines,x,y)
for _,line in ipairs(lines) do
text:set(line)
local w,h = text:getDimensions()
- love.graphics.setColor(0,0,0,0.6)
+ love.graphics.setColor(0,0,0,0.8)
love.graphics.rectangle("fill",x,y,w,h)
love.graphics.setColor(1,1,1)
love.graphics.draw(text,x,y)
diff --git a/net.txt b/net.txt
index ced98ee..4a81d7d 100644
--- a/net.txt
+++ b/net.txt
@@ -8,6 +8,9 @@ settile {q,r,tile}
reqchunk {u,v}
request chunk data for chunk at chunkpos u,v
+chat {msg}
+ send chat message msg
+
s2c:
playerinfopart:: {id,x,y,color:[r,g,b]}
@@ -29,3 +32,5 @@ chunk {tiles=[array of 128*128 booleans],u,v}
settile {q,r,tile}
tile at H(q,r) was set to tile (currently boolean)
+chat {msg,from}
+ recieve chat message msg from player with name from.
diff --git a/server/server.lua b/server/server.lua
index 85112c9..f78bdd0 100644
--- a/server/server.lua
+++ b/server/server.lua
@@ -60,6 +60,9 @@ end
local function player_move_packet(player,x,y)
return json.encode{t="move",id=player.id,x=x,y=y}
end
+local function chat_packet(fromplayer,msg)
+ return json.encode{t="chat",from=fromplayer.id,msg=msg}
+end
local map = MapS:make()
@@ -121,6 +124,11 @@ local function handle_ev(ev)
local cp = coords.ChunkPos:make(j.u,j.v)
local ch = map:obtain(cp)
player.peer:send(ch:data_packet())
+ elseif op == "chat" then
+ print("chat ["..player.id.."] "..j.msg)
+ for i,otherplayer in ipairs(playerlist) do
+ otherplayer.peer:send(chat_packet(player,j.msg))
+ end
end
end
end
@@ -160,7 +168,7 @@ local ntick = 0
local function player_near_chunk(cp)
-- true: chunk at cp should stay loaded (because of a nearby player),
-- false: no players nearby, can be unloaded
- -- this is kind of inefficient at the moment
+ -- this is maybe not as efficient as it possibly could be
for _,player in ipairs(playerlist) do
local pcp = player.pos:to_hex():containing_chunk()
for _,neighb in ipairs(pcp:neighborhood()) do