Skip to content

Commit 6e6e268

Browse files
committed
Merge branch 'dev'
2 parents 5109d8a + 64d065f commit 6e6e268

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1178
-217
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
.*
44
!.git*
55
/lua51*
6+
/profiling
67
savedir
78
/log*
89
import

game/assets/texture/Keyboard_A.png

5.82 KB
Loading

game/assets/texture/Keyboard_D.png

5.57 KB
Loading

game/assets/texture/Keyboard_S.png

6.2 KB
Loading
6 KB
Loading
6.4 KB
Loading

game/assets/texture/Keyboard_W.png

6.04 KB
Loading

game/common/camera.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11

2+
-- luacheck: globals love
3+
24
local math = require 'common.math'
5+
local vec2 = require 'cpml' .vec2
36
local Camera = require "steaming.extra_libs.hump.camera"
47
local VIEWDEFS = require 'view.definitions'
58

@@ -41,6 +44,14 @@ function CAM:isTileInFrame(i, j)
4144
and i <= cy + _HALF_H
4245
end
4346

47+
function CAM:relativeTileToScreen(i, j) -- luacheck: no self
48+
j = _HALF_W + j - 1
49+
i = _HALF_H + i - 1
50+
local x = (j - 0.5) * _TILE_W
51+
local y = (i - 0.5) * _TILE_H
52+
return vec2(x, y)
53+
end
54+
4455
function CAM:tilesInRange()
4556
local cx, cy = self:position() -- start point
4657
local rx, ry

game/common/profiler.lua

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
2+
-- luacheck: globals love
3+
4+
local SWITCHER = require 'infra.switcher'
5+
local Class = require 'steaming.extra_libs.hump.class'
6+
7+
local Profiler = Class{}
8+
9+
local SAMPLES = 10
10+
11+
function Profiler:init()
12+
self.profiling = {}
13+
self.last_state = nil
14+
self.output = io.open("profiling", "w")
15+
end
16+
17+
function Profiler:update(dt)
18+
local GS = require 'gamestates'
19+
local state = self.last_state
20+
self.last_state = SWITCHER.current()
21+
if state then
22+
local name = "???"
23+
for k,v in pairs(GS) do
24+
if v == state then
25+
name = k
26+
break
27+
end
28+
end
29+
if dt > 0.2 then
30+
local warning = ("%.2f lag on state %s at frame %d\n"):format(
31+
dt, name, GS[name].frame or -1
32+
)
33+
self.output:write(warning)
34+
print(warning)
35+
for mark, slice in pairs(self.slices) do
36+
self.output:write(("%16s: %.3f\n"):format(mark, 1000*slice))
37+
end
38+
end
39+
local sample = self.profiling[name] or { times = {} , n = 1 }
40+
sample.times[sample.n] = dt
41+
sample.n = (sample.n % SAMPLES) + 1
42+
self.profiling[name] = sample
43+
end
44+
self:start()
45+
end
46+
47+
function Profiler:start()
48+
self.started_at = love.timer.getTime()
49+
self.slices = {}
50+
end
51+
52+
function Profiler:mark(name)
53+
if not self.slices then return end
54+
local t = love.timer.getTime()
55+
local dt = t - self.started_at
56+
self.started_at = t
57+
self.slices[name] = (self.slices[name] or 0) + dt
58+
end
59+
60+
local function average(sample)
61+
local sum = 0
62+
for _,time in ipairs(sample.times) do
63+
sum = sum + time
64+
end
65+
return sum / math.max(#sample.times, SAMPLES)
66+
end
67+
68+
function Profiler:draw()
69+
local g = love.graphics
70+
g.push()
71+
g.origin()
72+
g.setColor(1,1,1)
73+
local i = 0
74+
for name,sample in pairs(self.profiling) do
75+
g.print(("%s: %.2f"):format(name, 1 / average(sample)), 32, 32+i*32)
76+
i = i + 1
77+
end
78+
g.pop()
79+
end
80+
81+
return Profiler()
82+

game/common/visibility.lua

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ local SCHEMATICS = require 'domain.definitions.schematics'
44

55
local TILE = require 'common.tile'
66

7+
local _cache
8+
79
--LOCAL FUNCTIONS DECLARATIONS--
810

911
local updateOctant
@@ -15,7 +17,6 @@ local visibilityOfShadow
1517
local addProjection
1618
local transformOctant
1719
local projectTile
18-
local fullShadow
1920
local isInRange
2021

2122
local VISIBILITY = {}
@@ -47,11 +48,31 @@ function VISIBILITY.resetFov(fov, sector)
4748

4849
end
4950

51+
function VISIBILITY.isCached(actor, sector)
52+
if not _cache then
53+
_cache = {}
54+
end
55+
local key = ("%s/%s"):format(sector:getId(), actor:getId())
56+
local cached = _cache[key] or {}
57+
local i, j = actor:getPos()
58+
local range = actor:getFovRange()
59+
if cached.i ~= i or cached.j ~= j or cached.range ~= range then
60+
cached.i = i
61+
cached.j = j
62+
cached.range = range
63+
return false
64+
else
65+
return true
66+
end
67+
end
68+
5069
--Update actors field of view based on his position in a given sector
5170
function VISIBILITY.updateFov(actor, sector)
52-
VISIBILITY.resetFov(actor:getFov(sector), sector)
53-
for octant = 1, 8 do
54-
updateOctant(actor, sector, octant)
71+
if not VISIBILITY.isCached(actor, sector) then
72+
VISIBILITY.resetFov(actor:getFov(sector), sector)
73+
for octant = 1, 8 do
74+
updateOctant(actor, sector, octant)
75+
end
5576
end
5677
end
5778

@@ -61,55 +82,49 @@ end
6182

6283
function updateOctant(actor, sector, octant)
6384
local line = newShadowLine()
64-
local full_shadow = false
6585

6686
--Actor current position
6787
local actor_i, actor_j = actor:getPos()
6888
local fov = actor:getFov(sector)
6989

70-
local row = 0
71-
while true do
72-
90+
for row = 0, actor:getFovRange() do
7391
do
7492
local d_i, d_j = transformOctant(row, 0, octant)
7593
local pos = {actor_i + d_i, actor_j + d_j}
7694

77-
--Check if tile is inside sector
95+
-- Check if tile is inside sector
7896
if not sector:isInside(pos[1],pos[2]) then break end
79-
if row > actor:getFovRange() then
80-
full_shadow = true
81-
end
8297
end
8398

99+
local full_shadow = false
100+
84101
for col = 0, row do
85102
local d_i, d_j = transformOctant(row, col, octant)
86103
local pos = {actor_i + d_i, actor_j + d_j}
87104

88105
--Check if tile is inside sector
89106
if not sector:isInside(pos[1],pos[2]) then break end
90107

91-
if full_shadow then
92-
if fov[pos[1]][pos[2]] then --Was seen once
93-
fov[pos[1]][pos[2]] = 0 --Make it invisible
94-
end
95-
else
96-
--Set visibility of tile
97-
local projection = projectTile(row, col)
98-
local visible = 1 - visibilityOfShadow(line, projection)
99-
if isInRange(pos[1], pos[2], actor) and (fov[pos[1]][pos[2]] or visible == 1) then
100-
fov[pos[1]][pos[2]] = visible
101-
end
102-
103-
--Add any wall tiles to the shadow line
104-
if visible == 1 and
105-
sector.tiles[pos[1]][pos[2]] and
106-
sector.tiles[pos[1]][pos[2]].type == SCHEMATICS.WALL then
107-
addProjection(line, projection)
108-
fullShadow = fullShadow or isShadowLineFull(line)
109-
end
108+
--Set visibility of tile
109+
local projection = projectTile(row, col)
110+
local visible = 1 - visibilityOfShadow(line, projection)
111+
if isInRange(pos[1], pos[2], actor) and (fov[pos[1]][pos[2]] or visible == 1) then
112+
fov[pos[1]][pos[2]] = visible
110113
end
114+
115+
--Add any wall tiles to the shadow line
116+
if visible == 1 and
117+
sector.tiles[pos[1]][pos[2]] and
118+
sector.tiles[pos[1]][pos[2]].type == SCHEMATICS.WALL then
119+
addProjection(line, projection)
120+
full_shadow = full_shadow or isShadowLineFull(line)
121+
end
122+
end
123+
124+
-- Check if shadow is full and no other tiles behind it will be visible
125+
if full_shadow then
126+
break
111127
end
112-
row = row + 1
113128
end
114129
end
115130

@@ -163,9 +178,10 @@ end
163178
function addProjection(line, projection)
164179
local list = line.shadow_list
165180
local index = 1;
181+
local n = #list
166182

167183
--Figure out where to slot the new shadow in the list
168-
while index <= #list do
184+
while index <= n do
169185
--Stop when we hit the insertion point.
170186
if list[index].start >= projection.start then break end
171187
index = index + 1

0 commit comments

Comments
 (0)