improvement: optimise chunk system

Diminishe the number of chunks and floor generated. Level loading will 
be a bit slower, but we basically double fps on test level
This commit is contained in:
Kazhnuz 2020-02-01 14:24:23 +01:00
parent 759d0d24e0
commit 89c5940116
6 changed files with 108 additions and 11 deletions

View file

@ -164,7 +164,7 @@ function VirtualPad:checkKey(key)
self.keys[key].isReleased = false self.keys[key].isReleased = false
else else
if (self.keys[key].isPressed) then if (self.keys[key].isPressed) then
core.debug:print("virtualpad", "key " .. key .. " is Down") --core.debug:print("virtualpad", "key " .. key .. " is Down")
self.keys[key].isPressed = false self.keys[key].isPressed = false
end end
end end

View file

@ -45,7 +45,7 @@ function OptionsManager:reset()
self.data.video.crtfilter = false self.data.video.crtfilter = false
self.data.video.resolution = 2 self.data.video.resolution = 2
self.data.video.border = true self.data.video.border = true
self.data.video.vsync = true self.data.video.vsync = false
self.data.video.fullscreen = false self.data.video.fullscreen = false
-- We load the default files -- We load the default files

View file

@ -11,6 +11,7 @@ function Frame:draw()
utils.graphics.resetColor() utils.graphics.resetColor()
love.graphics.draw(self.guiborder, 424, 20, 0, -1, -1) love.graphics.draw(self.guiborder, 424, 20, 0, -1, -1)
love.graphics.draw(self.guiborder2, 424, 220, 0, 1, 1, 424, 0) love.graphics.draw(self.guiborder2, 424, 220, 0, 1, 1, 424, 0)
love.graphics.print(love.timer.getFPS(), 200, 8)
end end
return Frame return Frame

View file

@ -15,6 +15,7 @@ function ShootMap:new(world, maptype, mapname)
self:getLevelData(mapname) self:getLevelData(mapname)
self:generateTextures(self.datas.tiles, self.datas.background) self:generateTextures(self.datas.tiles, self.datas.background)
self.layout = {} self.layout = {}
self.chunklist = {}
self.width = 0 self.width = 0
end end
@ -50,9 +51,10 @@ function ShootMap:loadCollisions()
self:loadLayout(); self:loadLayout();
local w, h = self:getDimensions() local w, h = self:getDimensions()
--self.world:newCollision("floor", 0, 0, -16, w, h, 16) --self.world:newCollision("floor", 0, 0, -16, w, h, 16)
for i, chunk in ipairs(self.layout) do for i, chunkname in ipairs(self.layout) do
chunk:spawnGrounds((i-1)*31*8)
chunk:spawnObjects((i-1)*31*8) self.chunklist[chunkname]:spawnGrounds((i-1)*31*8)
self.chunklist[chunkname]:spawnObjects((i-1)*31*8)
end end
end end
@ -115,11 +117,18 @@ function ShootMap:addChunk(source, filename, chunkid)
local chunkfile = require("datas.gamedata.maps.shoot.chunks." .. filename) local chunkfile = require("datas.gamedata.maps.shoot.chunks." .. filename)
local chunkdata = chunkfile.chunks local chunkdata = chunkfile.chunks
local chunkpos = #self.layout local chunkpos = #self.layout
local chunk = Chunk(self, chunkdata[chunkid]) local chunkname = filename .. chunkid
table.insert(self.layout, chunk) if self.chunklist[chunkname] == nil then
self.chunklist[chunkname] = Chunk(self, chunkdata[chunkid])
end
table.insert(self.layout, chunkname)
self:updateWidth() self:updateWidth()
end end
function ShootMap:getChunk(id)
return self.chunklist[self.layout[id]]
end
function ShootMap:addBlock(x, y, w, h, top, bottom) function ShootMap:addBlock(x, y, w, h, top, bottom)
-- Empty Placeholder function -- Empty Placeholder function
end end
@ -245,8 +254,9 @@ function ShootMap:drawChunks(x)
for i=1, 6 do for i=1, 6 do
local chunkID = firstChunk + i local chunkID = firstChunk + i
if (self.layout[chunkID] ~= nil) then local chunk = self:getChunk(chunkID)
self.layout[chunkID]:draw((chunkID-1) * (8*31)) if (chunk ~= nil) then
chunk:draw((chunkID-1) * (8*31))
end end
end end
end end

View file

@ -1,8 +1,12 @@
local Chunk = Object:extend() local Chunk = Object:extend()
local ChunkTerrain = require "game.modules.world.maps.tools.chunkterrain"
function Chunk:new(map, data) function Chunk:new(map, data)
self.map = map self.map = map
self.data = data self.data = data
self.grounds = {}
self.areGroundsPrepared = false
end end
function Chunk:getFakeData() function Chunk:getFakeData()
@ -20,13 +24,81 @@ function Chunk:update(dt)
end end
function Chunk:spawnGrounds(x) function Chunk:spawnGrounds(x)
if (self.areGroundsPrepared == false) then
self:prepareGround()
end
self:generateGround(x)
end
function Chunk:prepareGround()
for i=1, 5 do for i=1, 5 do
for j=1, 8 do for j=1, 8 do
if (self.data.terrain[i][j] ~= 3) then if (self.data.terrain[i][j] ~= 3) and (self:haveNoGround(j, i)) then
self.map.world:newCollision("floor", x+(j-1)*31, (i-1)*20, -48, 31, 20, 48) self:calculateGround(j, i)
--self.map.world:newCollision("floor", x+(j-1)*31, (i-1)*20, -48, 31, 20, 48)
end end
end end
end end
self.areGroundsPrepared = true
end
function Chunk:generateGround(basex)
for i, ground in ipairs(self.grounds) do
local x, y = ground.x, ground.y
local w, h = ground.w, ground.h
self.map.world:newCollision("floor", basex+(x-1)*31, (y-1)*20, -48, 31*w, 20*h, 48)
end
end
function Chunk:haveNoGround(x, y)
for i, ground in ipairs(self.grounds) do
if ground:isInside(x, y) then
return false
end
end
return true
end
function Chunk:addGround(x, y, w, h)
table.insert(self.grounds,ChunkTerrain(x, y, w, h))
end
function Chunk:calculateGround(x, y)
local groundHeight = 1
local groundWidth = 1
local maxHeight = 5-y
local maxWidth = 8-x
-- Creation de la première ligne
local lineEmpty = true
for i=0, maxWidth do
if self:testTerrain(x + i, y) and (lineEmpty) then
groundWidth = i + 1
else
lineEmpty = false
end
end
-- Pour optimiser, on commence à la seconde ligne cette boucle
for i=1, maxHeight do
lineEmpty = true
for j=0, (groundWidth-1) do
if self:testTerrain(x + j, y + i) == false then
lineEmpty = false
end
end
if (lineEmpty) then
groundHeight = i + 1
else
break
end
end
self:addGround(x, y, groundWidth, groundHeight)
end
function Chunk:testTerrain(x, y)
return (self.data.terrain[y][x] ~= 3) and (self:haveNoGround(x, y))
end end
function Chunk:spawnObjects(x) function Chunk:spawnObjects(x)

View file

@ -0,0 +1,14 @@
local ChunkTerrain = Object:extend()
function ChunkTerrain:new(x, y, w, h)
self.x = x
self.y = y
self.w = w
self.h = h
end
function ChunkTerrain:isInside(x, y)
return ((x >= self.x) and (x < self.x+self.w) and (y >= self.y) and (y < self.y+self.h))
end
return ChunkTerrain