A Question of Draw performance

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: A Question of Draw performance

Post by micha »

Thanks, Robin.
User avatar
Pash
Prole
Posts: 43
Joined: Sun Dec 30, 2012 8:04 am

Re: A Question of Draw performance

Post by Pash »

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.
Sagan Interactive - Looking forward to a creative 2013.
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: A Question of Draw performance

Post by Roland_Yonaba »

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.
Hm.. Why not implement it as a conditional statement in love.update ?
Well, check for the displacement made so far, and if it gets more than the desired value, call the relevant update method, passing it dt, and then reset the displacement counter to zero again....
Unless I totally missed what the intent was.
User avatar
Pash
Prole
Posts: 43
Joined: Sun Dec 30, 2012 8:04 am

Re: A Question of Draw performance

Post by Pash »

Hey Roland,

Yeh, this is kind of my idea. The below doesnt seem to work.

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
This doesnt seem to work at all.

Its still a bit messy I know. But this is where im at. Im guessing there is a better way of doing this....Attached the love file.
Attachments
tbad.love
(7.36 KiB) Downloaded 83 times
Sagan Interactive - Looking forward to a creative 2013.
User avatar
Pash
Prole
Posts: 43
Joined: Sun Dec 30, 2012 8:04 am

Re: A Question of Draw performance

Post by Pash »

Excuse me. Im being stupidly silly. I see why that wouldnt work. I think my update sprite method is ok though, seems to draw whats visible on the screen.

Ok, ill try and fix that tonight then.
Sagan Interactive - Looking forward to a creative 2013.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: A Question of Draw performance

Post by micha »

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:

Code: Select all

screeni = math.floor(camera.x/tileWidth)
screenj = math.floor(camera.y/tileHeight)
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.

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:

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
If you have a "nil" in an if-condition, it is consideres as "false"
User avatar
Pash
Prole
Posts: 43
Joined: Sun Dec 30, 2012 8:04 am

Re: A Question of Draw performance

Post by Pash »

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:

Code: Select all

screeni = math.floor(camera.x/tileWidth)
screenj = math.floor(camera.y/tileHeight)
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.

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:

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
If you have a "nil" in an if-condition, it is consideres as "false"
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:-

Code: Select all

if self.x - self.displacementX > blockSize or self.x - self.displacementX < -blockSize then
		self.displacementX = self.x
		updateSpriteBatch()
end
Or like you said, i could use the functions that Im using to return the tile numbers and use that logic instead.

To be fair, I did have that worldblocks is "nil or exists" check previously but I had some issues with it. I cant remember what now, but ill revisit it and try again.
Sagan Interactive - Looking forward to a creative 2013.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 3 guests