Re: A Question of Draw performance
Posted: Tue Feb 12, 2013 10:39 am
Thanks, Robin.
Hm.. Why not implement it as a conditional statement in love.update ?Pash wrote:I implemented this multi dimensional array, its now much cleaner than before but the next consideration is how to check for when to update the screen. My next idea is to only update the screen when the camera x or y has moved more than 16 px, rather than now which is obviously a big tug on the resources. Ill post back if I get further luck. Some point in the next few weeks when this is working well and much cleaner ill put the complete source on github or something.
Just need more time on it first.
Code: Select all
function camera:follow(target)
local oldcamx = self.x
if target.x + target.width/2 > love.graphics.getWidth() / 2 then
self.x = math.floor(target.x + target.width/2 - love.graphics.getWidth() / 2)
else
self.x = 0
end
if target.y < love.graphics.getHeight() / 2 then
self.y = math.floor(target.y - love.graphics.getHeight() / 2)
else
self.y = 0
end
if self.x - oldcamx > 2 then
GameWorld:updateSpriteBatch()
end
end
Code: Select all
unction world:updateSpriteBatch()
local xdmin,xdmax = self:CheckBlockXMinMax()
local ydmin,ydmax = self:CheckBlockYMinMax()
blockSetBatch:bind()
blockSetBatch:clear()
for i=ydmin,ydmax do
for j=xdmin,xdmax do
if WorldBlocks[i][j].idno ~= 0 then
blockSetBatch:addq( WorldBlocks[i][j].id.img, j * self.blockSize - self.blockSize, i * self.blockSize - self.blockSize )
end
end
end
blockSetBatch:unbind()
end
Code: Select all
screeni = math.floor(camera.x/tileWidth)
screenj = math.floor(camera.y/tileHeight)
Code: Select all
for i=ydmin,ydmax do
if WoldBlocks[i] then
for j=xdmin,xdmax do
if WorldBlocks[i][j] then
blockSetBatch:addq( ... )
end
end
end
end
Thanks micha. Yeh that looks much better. My idea was to start moving the draw code over to the camera anyway. I dont really need to draw the world from that class blueprint - as the camera is the v in mvc (if I look at it like that). I thought of something like this in the camera update:-micha wrote:It is not enough to check if the x-difference between the current frame and the last frame is greater than 2. It might happen, that you move one pixel per frame, for many frames. Then after some time you need new tiles, but your codes believes everything is ok. The correct solution is as follows:
In each timestep you calculate the tile-coordinates (that is i and j) of the top left corner. This is done with the math.floor-function:Now in each timestep you compare screeni and screeny of the last time step with the current values. If there is a change, then the spritebatch needs to be updated, if not, not.Code: Select all
screeni = math.floor(camera.x/tileWidth) screenj = math.floor(camera.y/tileHeight)
And one short comment to your spritebatch update: It looks like you store empty tiles as 0 ("zero"). Instead of that I suggest you store them as nil. That way, this part of the memory is not even existing and you need less memory. However you then have to take care of nonexisting variables:If you have a "nil" in an if-condition, it is consideres as "false"Code: Select all
for i=ydmin,ydmax do if WoldBlocks[i] then for j=xdmin,xdmax do if WorldBlocks[i][j] then blockSetBatch:addq( ... ) end end end end
Code: Select all
if self.x - self.displacementX > blockSize or self.x - self.displacementX < -blockSize then
self.displacementX = self.x
updateSpriteBatch()
end