From 89c5940116b7c7254cd2aa67eddcf2c216f4f68b Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Sat, 1 Feb 2020 14:24:23 +0100 Subject: [PATCH] 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 --- sonic-bluestreak.love/core/input.lua | 2 +- sonic-bluestreak.love/core/options.lua | 2 +- .../game/modules/gui/frame.lua | 1 + .../game/modules/world/maps/shoot.lua | 24 ++++-- .../game/modules/world/maps/tools/chunk.lua | 76 ++++++++++++++++++- .../modules/world/maps/tools/chunkterrain.lua | 14 ++++ 6 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 sonic-bluestreak.love/game/modules/world/maps/tools/chunkterrain.lua diff --git a/sonic-bluestreak.love/core/input.lua b/sonic-bluestreak.love/core/input.lua index 4653aa1..2db94da 100644 --- a/sonic-bluestreak.love/core/input.lua +++ b/sonic-bluestreak.love/core/input.lua @@ -164,7 +164,7 @@ function VirtualPad:checkKey(key) self.keys[key].isReleased = false else 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 end end diff --git a/sonic-bluestreak.love/core/options.lua b/sonic-bluestreak.love/core/options.lua index 1c0252b..07b8bc3 100644 --- a/sonic-bluestreak.love/core/options.lua +++ b/sonic-bluestreak.love/core/options.lua @@ -45,7 +45,7 @@ function OptionsManager:reset() self.data.video.crtfilter = false self.data.video.resolution = 2 self.data.video.border = true - self.data.video.vsync = true + self.data.video.vsync = false self.data.video.fullscreen = false -- We load the default files diff --git a/sonic-bluestreak.love/game/modules/gui/frame.lua b/sonic-bluestreak.love/game/modules/gui/frame.lua index 5f40a15..2fd8a88 100644 --- a/sonic-bluestreak.love/game/modules/gui/frame.lua +++ b/sonic-bluestreak.love/game/modules/gui/frame.lua @@ -11,6 +11,7 @@ function Frame:draw() utils.graphics.resetColor() love.graphics.draw(self.guiborder, 424, 20, 0, -1, -1) love.graphics.draw(self.guiborder2, 424, 220, 0, 1, 1, 424, 0) + love.graphics.print(love.timer.getFPS(), 200, 8) end return Frame diff --git a/sonic-bluestreak.love/game/modules/world/maps/shoot.lua b/sonic-bluestreak.love/game/modules/world/maps/shoot.lua index 21f5d9d..47cace4 100644 --- a/sonic-bluestreak.love/game/modules/world/maps/shoot.lua +++ b/sonic-bluestreak.love/game/modules/world/maps/shoot.lua @@ -15,6 +15,7 @@ function ShootMap:new(world, maptype, mapname) self:getLevelData(mapname) self:generateTextures(self.datas.tiles, self.datas.background) self.layout = {} + self.chunklist = {} self.width = 0 end @@ -50,9 +51,10 @@ function ShootMap:loadCollisions() self:loadLayout(); local w, h = self:getDimensions() --self.world:newCollision("floor", 0, 0, -16, w, h, 16) - for i, chunk in ipairs(self.layout) do - chunk:spawnGrounds((i-1)*31*8) - chunk:spawnObjects((i-1)*31*8) + for i, chunkname in ipairs(self.layout) do + + self.chunklist[chunkname]:spawnGrounds((i-1)*31*8) + self.chunklist[chunkname]:spawnObjects((i-1)*31*8) end end @@ -115,11 +117,18 @@ function ShootMap:addChunk(source, filename, chunkid) local chunkfile = require("datas.gamedata.maps.shoot.chunks." .. filename) local chunkdata = chunkfile.chunks local chunkpos = #self.layout - local chunk = Chunk(self, chunkdata[chunkid]) - table.insert(self.layout, chunk) + local chunkname = filename .. chunkid + if self.chunklist[chunkname] == nil then + self.chunklist[chunkname] = Chunk(self, chunkdata[chunkid]) + end + table.insert(self.layout, chunkname) self:updateWidth() end +function ShootMap:getChunk(id) + return self.chunklist[self.layout[id]] +end + function ShootMap:addBlock(x, y, w, h, top, bottom) -- Empty Placeholder function end @@ -245,8 +254,9 @@ function ShootMap:drawChunks(x) for i=1, 6 do local chunkID = firstChunk + i - if (self.layout[chunkID] ~= nil) then - self.layout[chunkID]:draw((chunkID-1) * (8*31)) + local chunk = self:getChunk(chunkID) + if (chunk ~= nil) then + chunk:draw((chunkID-1) * (8*31)) end end end diff --git a/sonic-bluestreak.love/game/modules/world/maps/tools/chunk.lua b/sonic-bluestreak.love/game/modules/world/maps/tools/chunk.lua index ecb304e..076d1f8 100644 --- a/sonic-bluestreak.love/game/modules/world/maps/tools/chunk.lua +++ b/sonic-bluestreak.love/game/modules/world/maps/tools/chunk.lua @@ -1,8 +1,12 @@ local Chunk = Object:extend() +local ChunkTerrain = require "game.modules.world.maps.tools.chunkterrain" function Chunk:new(map, data) self.map = map self.data = data + + self.grounds = {} + self.areGroundsPrepared = false end function Chunk:getFakeData() @@ -20,13 +24,81 @@ function Chunk:update(dt) end 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 j=1, 8 do - if (self.data.terrain[i][j] ~= 3) then - self.map.world:newCollision("floor", x+(j-1)*31, (i-1)*20, -48, 31, 20, 48) + if (self.data.terrain[i][j] ~= 3) and (self:haveNoGround(j, i)) then + self:calculateGround(j, i) + --self.map.world:newCollision("floor", x+(j-1)*31, (i-1)*20, -48, 31, 20, 48) 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 function Chunk:spawnObjects(x) diff --git a/sonic-bluestreak.love/game/modules/world/maps/tools/chunkterrain.lua b/sonic-bluestreak.love/game/modules/world/maps/tools/chunkterrain.lua new file mode 100644 index 0000000..a6d0879 --- /dev/null +++ b/sonic-bluestreak.love/game/modules/world/maps/tools/chunkterrain.lua @@ -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