## Problem with drawing only the cubes on screen.

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

### Problem with drawing only the cubes on screen.

So I decided to optimize my game by only drawing cubes that are visible ( already been doing that, and by that I will explain in a bit ) and those that are on screen. Problem is, there are only so many cubes on the screen at a time, yet it tells me it draws around 900+ of them.
love 2018-08-08 21-34-01-166.jpg (543.14 KiB) Viewed 440 times
When I'm zoomed in at 100% ( default zoom and above ) it's around 900+. At 200% or when I'm at the edge, around 700+. At some point, the number of drawn cubes caps at 1200+ when I zoom out enough.
Now by visible I mean cubes that should theoretically be visible from the isometric point of view. Cubes that have a neighbor to the top, left and right are "not visible". If any of those three conditions is not met, then it "is visible".
After that I use two functions I made, normalToIsoX and normalToIsoY to find out the x,y coordinates of the cube, based on its x,y,z coordinate on the grid. After that I use cam:cameraCoords() on isoX and isoY to find the cubes x,y on the screen ( I use hump.camera )
Now here is the code :

Code: Select all

t.cubeIsVisible = function(x,y,z)
local xE = false
local yE = false
local zE = false
if (x + 1) > #grid then xE = true end
if (y + 1) > #grid[x] then yE = true end
if (z + 1) > #grid[x][y] then zE = true end
if xE or yE or zE then return true end
local n = 0
if grid[x + 1][y][z] ~= 0 then n = n + 1 end
if grid[x][(y + 1)][z] ~= 0 then n = n + 1 end
if grid[x][y][(z + 1)] ~= 0 then n = n + 1 end
local screenX, screenY = cam:cameraCoords(gridFuncs.normalToIsoX(x,y),gridFuncs.normalToIsoY(x,y,z,3))
if n == 3 then
return false
elseif not (((screenX < -100*zoom) or (screenX > wW + 100*zoom)) and ((screenY < -100*zoom) or (screenY > wH + 100*zoom))) then
return true
end
end
I have no idea what is causing this problem. Could anyone help me please? Thank you.
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source so anyone can continue my ( messy ) work

Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

### Re: Problem with drawing only the cubes on screen.

I realized that the edge xE,yE and zE might be making the game draw cubes on the border of the map so I decided to scrap and change the function. Now it still draws around 800+ at 100%, but only 400+ at 200%. One significant change though ( for the worse ), is that the game runs way slower now. Here is the new code :

Code: Select all

t.cubeIsVisible = function(x,y,z) -- checks if a cube is visible ( in this case covered up by other cubes )
local screenX, screenY = cam:cameraCoords(gridFuncs.normalToIsoX(x,y),gridFuncs.normalToIsoY(x,y,z,3))
if not (((screenX < -150) or (screenX > wW + 150)) and ((screenY < -150) or (screenY > wH + 150))) then
local n = 0
if gridFuncs.gridCheck(x+1,y,z,0,false) then n = n + 1 end
if gridFuncs.gridCheck(x,y+1,z,0,false) then n = n + 1 end
if gridFuncs.gridCheck(x,y,z+1,0,false) then n = n + 1 end
if n == 3 then return false else return true end
else return false end
end
And here is gridCheck()

Code: Select all

t.gridCheck = function(x,y,z,v,t) -- checks the grid for something, if search is outside the grid then it produces an error
return pcall(function()
if t then
if grid[x][y][z] == v then else print(haha + ahah) end
elseif not t then
if grid[x][y][z] ~= v then else print(haha + ahah) end
end end)
end
These two functions get called in another function that loops through the grid called gridDraw(), and gridDraw() in term gets called in love.draw. Also, in love.update I have this :

Code: Select all

if camCycle >= 0.1 then
-- zoom
clientFuncs.camZoom()
cam:zoomTo(zoom)
-- get cam pos
local x,y = cam:position()
-- get the diff between the target pos and current pos
local xDiff,yDiff = math.abs(isoX - x), math.abs(isoY - y)
-- slow down if jumping or falling
local m = 1
if player.data.jumping or
gridFuncs.gridCheck(player.entity.pos.x,
player.entity.pos.y,
player.entity.pos.z - 1,0,true) then m = 0.3 end
if xDiff < 5 then xDiff = 0 else xDiff = xDiff / (20 / (settings.camSpeed/10*player.entity.stats.speed*m)) end
if yDiff < 5 then yDiff = 0 else yDiff = yDiff / (20 / (settings.camSpeed/10*player.entity.stats.speed*m)) end
camCycle = 0
-- move cam x pos
if isoX > x then
cam:lookAt(x + xDiff,y)
else
cam:lookAt(x - xDiff,y)
end
-- update cam pos
local x,y = cam:position()
-- move cam y pos
if isoY > y then
cam:lookAt(x,y + yDiff)
else
cam:lookAt(x,y - yDiff)
end
end
And this :

Code: Select all

camCycle = camCycle + 1*dt*settings.camSpeed
And I think I created some sort of feedback loop, and that in turn slows down the game.
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source so anyone can continue my ( messy ) work

Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

### Re: Problem with drawing only the cubes on screen.

Nevermind I managed to make the camera run smooth again, but it still says it renders 800+ cubes. Here is a .love file
ooga.love
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source so anyone can continue my ( messy ) work

Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

### Re: Problem with drawing only the cubes on screen.

I looked at my memory usage and it says love uses 60mb. Is that a lot or not much in terms of Love2D standards ?
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source so anyone can continue my ( messy ) work

0x72
Citizen
Posts: 51
Joined: Thu Jun 18, 2015 9:02 am

### Re: Problem with drawing only the cubes on screen.

Code: Select all

not (((screenX < -150) or (screenX > wW + 150)) and ((screenY < -150) or (screenY > wH + 150)))
renders 1,3,5,7,9:

Code: Select all

region #5 is your viewport and everything else is not visible:

1|2|3
-+-+-
4|5|6
-+-+-
7|8|9
You want to render only 5 (viewport) so try changing and keyword to an or.

Code: Select all

not ((screenX < -150) or (screenX > wW + 150)) or ((screenY < -150) or (screenY > wH + 150))
or express differently:

Code: Select all

((-150 < screenX) and (screenX < wW + 150)) and ((-150 < screenY) and (screenY < wH + 150)) -- "inside" instead "not outside"
Also: this solution you have iterates over all the cubes each frame. If it ever become a performance issue read about spatial hashing.
It depends on the size of your world, but I'm already not getting steady 60 with the map you have there - 20181 cubes. cubeIsVisible is responsible for more then 91% time in the gridDraw (after fixing the condition and actually rendering around 60 cubes).

Also: it looks like your coords are anchored to corners so 150 might not be perfect value: this one worked for me better:

Code: Select all

((-250 < screenX) and (screenX < wW)) and ((-250 < screenY) and (screenY < wH))

Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

### Re: Problem with drawing only the cubes on screen.

Thank you a lot
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source so anyone can continue my ( messy ) work

Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

### Re: Problem with drawing only the cubes on screen.

I will try your solution + spatial hashing + capping the framerate and see what the result is.
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source so anyone can continue my ( messy ) work

pedrosgali
Party member
Posts: 102
Joined: Wed Oct 15, 2014 5:00 pm
Location: Yorkshire, England

### Re: Problem with drawing only the cubes on screen.

I'd also suggest drawing your cubes to a canvas and checking each frame if you need to redraw it. So if the camera moves redraw but otherwise just draw the previous render to the screen. I posted an isometric map generation example on another thread on here, I'd leave a link here but I'm on my phone so you'll have to do a search if you want to download it for the code. But using the above method I got a consistent 60 fps regardless of how many tiles I needed on screen (Until I moved the camera at which point it could get a bit laggy if there were too many objects to render.) Since you have players moving you can just draw them after the canvas render.

Code: Select all

if not wearTheseGlasses() then
chewing_on_trashcan = true
end

### Who is online

Users browsing this forum: Bing [Bot], Exabot [Bot], ironsheikh and 4 guests