enterFrame issues

Hey

I am having a few problems within the enterFrame (game loop) function that I have.  Unfortunately, I have a lot happening in there and I am struggling to find ways in which I can optimise this.

My actual problem is that I have a for loop that will constantly iterate over the group of display objects that are “alive” and will check the object’s x and y values within the screen to determine whether or not that object is within a certain grid threshold or not, if so, it assigns that thing to a grid coord.  So, imagine that a grid exists and each point in that grid contains the following:

x1 = coordinates of first x value in grid

x2 = coordinates of second x value in grid

y1 = coordinates of first y value in grid

y2 = coordinates of second y value in grid

The code:

[lua]

local function setGridCoords( thing )

    for x=1, noGridCellsX do

        – y Coord is set every down transition so there’s no need to iterate over the y coords in the grid

        local y = thing.yCoord

        local x1 = gridArr[x][y].x1

        local x2 = gridArr[x][y].x2

        local y1 = gridArr[x][y].y1

        local y2 = gridArr[x][y].y2

        if ( thing.isAlive == true and ( thing.x >= x1 ) and ( thing.x < x2 )

                    and ( thing.y >= y1 ) and ( thing.y < y2 ) ) then

           thing.xCoord = x

           thing.yCoord = y

           return

        end

    end

end

local function gameLoop( event )

    for i=thingGroup.numChildren,1,-1 do

        local thing = thingGroup[i]

        setGridCoords( thing )

    end

end

function scene:enterScene( event )

    

    Runtime:addEventListener(“enterFrame”, gameLoop)

end

[/lua]

I basically, want to know if there’s any simple ways that I can optimise this.  These “things” are constantly on the move - they transition across the screen from left to right, and down the screen if they collide with anything (each other, walls, objects, etc…).

I’ve thought about trying to restrict the number of times that the for loop and setGridCoords() are called within the game method - because they really don’t need to be called 30/60 times per second, but i didn’t want to introduce any modulus functions in there that might slow the game down further.  The frame rate really starts to take a hit once I start spawning a lot of these things.

Any suggestions on what to try would be very welcome.  Please also bare in mind that the above code has been drawn up from memory (as I am at work and my boss is right over my shoulder!), so if I miss anything then I can try my best to fill the gaps :slight_smile:

Cheers

Rich

Do the objects move in straight lines, i.e. always within the confines of the grid square boundaries?

Off the top of my head, would it be possible to put a physics sensor object within each grid square, and then just detect when an object passes through one of them and update the grid position?

Hey,

Yes, they just move in straight lines from left to right. The things do stray outside of the x boundaries of the grid but only very briefly.  When they hit an object they transition down the screen by little over the display object’s height and then move in the opposite direction - kinda like how Space Invaders move.  However, it’s a bit different to that though because the movement of each of the “things” is separate - whereas in Space Invaders they all move as a complete group.

With regards to your suggestion, that sounds like a very good idea! Will give this a try tonight.

Thanks a lot

Rich

It sounds like your app is doing a LOT of work during enterFrame, which can cause a lot of little rendering glitches (frames stuttering, frames skipped, etc) I would suggest re-evaluating your strategy for moving things about…

Here’s another approach to consider… Do not calculate grid snapping values during enterFrame, at least not by processing every scrap of object data.

Instead I’d recommend you employ an alternate, frame rendering friendly strategy (which executes outside enterFrame) such as

  • Having the objects themselves calculate correct final endpoints (which is what is passed to their transition.to() call)

  • Having the objects themselves call a snap function using transition.to() onComplete argument (which snaps them when they complete their initial movement) - only “alive things” would be calling in this case.

  • When the actual determination is made as to whether a “thing” is on a grid line, use modulo math to determine if it is on a grid coordinate as opposed to checking every grid element in an array (presuming the grid is homogeneously spaced)

There’s probably half a dozen ways to get the objects to snap themselves using a lot less CPU horsepower than cycling through a lot of data on enterFrame (which can really wreck the “smoothocity” of your app).

Anyways, just a couple thoughts on potential alternate strategies that might be applicable.

Thanks guys,

There is still some way to go to optimising this ting! @nick_sherman solution has gone some way to sorting that out though.  The grid of rectangles of x1 - x2 by y1 - y2 is now a collection of sensor squares that the objects can now pass over each able to detect where each is.

As I said though, there’s a lot more happening here that I need to sort out though in order to fully optimise this.

Thanks again

Rich

Do the objects move in straight lines, i.e. always within the confines of the grid square boundaries?

Off the top of my head, would it be possible to put a physics sensor object within each grid square, and then just detect when an object passes through one of them and update the grid position?

Hey,

Yes, they just move in straight lines from left to right. The things do stray outside of the x boundaries of the grid but only very briefly.  When they hit an object they transition down the screen by little over the display object’s height and then move in the opposite direction - kinda like how Space Invaders move.  However, it’s a bit different to that though because the movement of each of the “things” is separate - whereas in Space Invaders they all move as a complete group.

With regards to your suggestion, that sounds like a very good idea! Will give this a try tonight.

Thanks a lot

Rich

It sounds like your app is doing a LOT of work during enterFrame, which can cause a lot of little rendering glitches (frames stuttering, frames skipped, etc) I would suggest re-evaluating your strategy for moving things about…

Here’s another approach to consider… Do not calculate grid snapping values during enterFrame, at least not by processing every scrap of object data.

Instead I’d recommend you employ an alternate, frame rendering friendly strategy (which executes outside enterFrame) such as

  • Having the objects themselves calculate correct final endpoints (which is what is passed to their transition.to() call)

  • Having the objects themselves call a snap function using transition.to() onComplete argument (which snaps them when they complete their initial movement) - only “alive things” would be calling in this case.

  • When the actual determination is made as to whether a “thing” is on a grid line, use modulo math to determine if it is on a grid coordinate as opposed to checking every grid element in an array (presuming the grid is homogeneously spaced)

There’s probably half a dozen ways to get the objects to snap themselves using a lot less CPU horsepower than cycling through a lot of data on enterFrame (which can really wreck the “smoothocity” of your app).

Anyways, just a couple thoughts on potential alternate strategies that might be applicable.

Thanks guys,

There is still some way to go to optimising this ting! @nick_sherman solution has gone some way to sorting that out though.  The grid of rectangles of x1 - x2 by y1 - y2 is now a collection of sensor squares that the objects can now pass over each able to detect where each is.

As I said though, there’s a lot more happening here that I need to sort out though in order to fully optimise this.

Thanks again

Rich

Hi there!

I’m still kind of newbie in Corona, but following your original idea of restricting number of times the for loop is started I would suggest this rather naive check:

local count = 0 local function gameLoop( event ) if count\<5 then count = count + 1 else count = 0 for i=thingGroup.numChildren,1,-1 do local thing = thingGroup[i] setGridCoords( thing ) end end end

You get loop executed every fifth frame.

Cheers

Hi there!

I’m still kind of newbie in Corona, but following your original idea of restricting number of times the for loop is started I would suggest this rather naive check:

local count = 0 local function gameLoop( event ) if count\<5 then count = count + 1 else count = 0 for i=thingGroup.numChildren,1,-1 do local thing = thingGroup[i] setGridCoords( thing ) end end end

You get loop executed every fifth frame.

Cheers