Continuous flow of cars, but the flow is not smooth.

Hi guys, I’m pretty new to Corona and I’m starting to make some tests with it. My first exercise to get going with corona is/was to create a simple car games. Cars start showing up from the top of the screen and are moved to the bottom of the screen and the player has to change lines to avoid hitting the cars. It’s pretty simple. (this is pretty much what I’m trying to create https://itunes.apple.com/au/app/zigzag-racer-insanely-addictive!/id842010110?mt=8))

The problem is that I can’t understand why the cars movement is not fluent. It’s kind of laggy and I really don’t know why because I think that I’m doing it right. I’m adding here what I’m doing, because maybe my approach is not right.

Basically I have a “enterFrame” listener. For each frame I check if the latest car added is below a “y axis” coordinate, and if so I add a new car. The cars are stored in a table, so the first is always the latest added. Also inside the “enterFrame” listener I check if the car has left the screen and I remove it.   

To move the cars I have a function that iterates over all the cars in the “oponentCars” and with a constant speed I move them.

Is this approach ok? Why am I seeing some lag?

local oponentCars = { display.newImage( "oponentcar.png", randomSide(), -carHeight) } local runtime = 0 local function getDeltaTime() local temp = system.getTimer() local dt = (temp-runtime) / (1000/60) runtime = temp return dt end function addNewCar( ) local oponentcar = display.newImage( "oponentcar.png", randomSide(), -carHeight) physics.addBody( oponentcar, { density = 0.0} ) table.insert( oponentCars, 1, oponentcar ) end function moveCars( dt ) for index,oponentCar in ipairs(oponentCars) do oponentCar:translate( 0, speed\*dt ) end end local function frameUpdate() moveCars(getDeltaTime()) if oponentCars[1].y \> 280 then addNewCar() end if oponentCars[#oponentCars].y \> 1700 then oponentCars[#oponentCars]:removeSelf() table.remove( oponentCars, #oponentCars ) end end Runtime:addEventListener( "enterFrame", frameUpdate )

Thanks a lot!!

Hi @andresyo990,

Welcome to Corona. For this type of project, you should consider using transitions and/or physics (if you need collision handling). This will likely make this concept easier to manage. For example, you could start the cars on a basic transition and then use an “onComplete” event to put them back up top and start moving down again.

Here’s the documentation on transitions:

http://docs.coronalabs.com/api/library/transition/index.html

Take care,

Brent

Thank a lot for the answer!!

btw: just reformated the code… it lost the indentation! 

Bye

Brent, 

I couldn’t accomplish what I wanted using transitions, so this is the code I ended up with, the things I tried to optimize are:

  • use “local mRand = math.random” instead of calling math.random every time I needed it.
  • I reuse the cars, to avoid calling “display.newImage( “oponentcar.png”)” every time I needed a new car.
  • removed the adds from the gameplay and i’m going to only show admob ads on menu.

But I still see some lag. It’s not 100% smoth. Do you think that calling a loop inside the moveCars listener for enterFrame can be lagging my game? That loop only iterates over 4 elements. What do you think? 

Any clue to help me?

Thanks a lot!

local oponentCars = { display.newImage( "oponentcar.png", randomSide(), -carHeight) } function resetCar( car ) if car == nil then car = display.newImage( "oponentcar.png") end table.insert( oponentCars, 1, car) car.x = randomSide() car.y = -carHeight/2 end local removedCar = nil local function moveCars() for index,oponentCar in ipairs(oponentCars) do oponentCar.y = oponentCar.y + 20 end if oponentCars[1].y \> 470 then resetCar(removedCar) end if oponentCars[#oponentCars].y \> 1700 then removedCar = oponentCars[#oponentCars] table.remove( oponentCars, #oponentCars ) end end Runtime:addEventListener( "enterFrame", moveCars )

Given that you’re if/then statements are checking for things like 470 or 1700 separate cars (display objects) on the screen at once, I would wonder if it is somehow a performance issue.  Maybe someone with a better understanding of texture memory, corona’s image re-use/caching, etc. could chime in.

A quick test might be to not use “enterFrame”, but do a timer.performWithDelay( 200, moveCars, 0) – essentially slow down your update loop and see if things go smoother.  If you slow it down to 5 frames per sec and it’s still choppy, you’ve got bigger problems.d

Simple answer: you don’t need transitions at all. Creating an enterFrame function that moves your cars up or down a given amount of pixels should work perfectly.

The problems is in having 1700 cars. You need to write code that intelligently re-use a limited maximum set of cars on screen - i.e. use 20 same cars, but make them look like 1700 different cars.

I’m not sure if is a performance issue or if the image is getting blurred for the movement, I mean the image is not sharp, it’s like blurred…

any idea?

Hi @andresyo990,

Welcome to Corona. For this type of project, you should consider using transitions and/or physics (if you need collision handling). This will likely make this concept easier to manage. For example, you could start the cars on a basic transition and then use an “onComplete” event to put them back up top and start moving down again.

Here’s the documentation on transitions:

http://docs.coronalabs.com/api/library/transition/index.html

Take care,

Brent

Thank a lot for the answer!!

btw: just reformated the code… it lost the indentation! 

Bye

Brent, 

I couldn’t accomplish what I wanted using transitions, so this is the code I ended up with, the things I tried to optimize are:

  • use “local mRand = math.random” instead of calling math.random every time I needed it.
  • I reuse the cars, to avoid calling “display.newImage( “oponentcar.png”)” every time I needed a new car.
  • removed the adds from the gameplay and i’m going to only show admob ads on menu.

But I still see some lag. It’s not 100% smoth. Do you think that calling a loop inside the moveCars listener for enterFrame can be lagging my game? That loop only iterates over 4 elements. What do you think? 

Any clue to help me?

Thanks a lot!

local oponentCars = { display.newImage( "oponentcar.png", randomSide(), -carHeight) } function resetCar( car ) if car == nil then car = display.newImage( "oponentcar.png") end table.insert( oponentCars, 1, car) car.x = randomSide() car.y = -carHeight/2 end local removedCar = nil local function moveCars() for index,oponentCar in ipairs(oponentCars) do oponentCar.y = oponentCar.y + 20 end if oponentCars[1].y \> 470 then resetCar(removedCar) end if oponentCars[#oponentCars].y \> 1700 then removedCar = oponentCars[#oponentCars] table.remove( oponentCars, #oponentCars ) end end Runtime:addEventListener( "enterFrame", moveCars )

Given that you’re if/then statements are checking for things like 470 or 1700 separate cars (display objects) on the screen at once, I would wonder if it is somehow a performance issue.  Maybe someone with a better understanding of texture memory, corona’s image re-use/caching, etc. could chime in.

A quick test might be to not use “enterFrame”, but do a timer.performWithDelay( 200, moveCars, 0) – essentially slow down your update loop and see if things go smoother.  If you slow it down to 5 frames per sec and it’s still choppy, you’ve got bigger problems.d

Simple answer: you don’t need transitions at all. Creating an enterFrame function that moves your cars up or down a given amount of pixels should work perfectly.

The problems is in having 1700 cars. You need to write code that intelligently re-use a limited maximum set of cars on screen - i.e. use 20 same cars, but make them look like 1700 different cars.

I’m not sure if is a performance issue or if the image is getting blurred for the movement, I mean the image is not sharp, it’s like blurred…

any idea?