Choppy performance when moving image across screen

Hi @atkinson.b,

The code looks fine, generally, although I’d localize the move function. Are you sure there’s not another process that is slowing down the game in general? Is this the only thing you’re doing at this point, on a blank screen with no other processes?

Best regards,

Brent

Yes, I suppose I should note that I am using the physics engine on an object (character) using physics.addBody, a Runtime event handler for screen touch/release uses physics:setGravity(0, 20) or physics:setGravity(0, -20) to control the character to go up and down when you press or release.  I also have a Runtime listener on enterFrame that is checking for some collisions.

Sounds like a “Flappy” game! :wink:

The touch handling routine may be the culprit. Or, something is being continually set/changed during your Runtime handler that doesn’t need to be constantly (every frame) set/changed. If you can minimize and isolate your code for posting here, that should help.

Brent

I doubt it’s the touch handling routine very much (unless there’s some performance issue with constantly changing the gravity of the physics engine)…

Runtime:addEventListener(“touch”, touchFunction)

function touchFunction(event)

    if event.phase == “began” then

        physics:setGravity(0, -20)

    else if event.phase == “ended” then

        physics:setGravity(0, 20)

    end

end

And in the enterFrame, it’s checking every frame if any of the objects on the screen have collided (there are between 3 and 10 moving objects on screen at any given time) using the non-physics hasCollided function I found in one of the Corona demos.  I’m not sure it HAS to check for collisions EVERY frame, but I’d like the collisions to be as responsive as possible.  I was reading something about possibly moving all of my object movement management code (currently using transition.to’s) into the enterFrame method and using Delta Time, is putting the logic for moving the objects across the screen into enterFrame likely to be smoother than using transitions? Or would it matter?

Hi again,

The non-physics collision function is most likely the issue in regards to performance. In almost every case, if you use physics for something, I recommend that you use it for everything that makes sense (and within reason). In other words, if you’re using physics already, use the physics engine to detect collisions, not a separate function. If you were not using physics for anything, then the non-physics method would make sense, but in this case, it’s logical to have the physics engine handle your collisions for you.

Brent

Hey, thanks for your continued attention… I have tried the following, very simple program and it still seems to be chopping:

local _H = display.contentHeight

local _W = display.contentWidth

local _buildingObject1 = display.newImage(“building.png”)

_buildingObject1:translate(_W, 0)

_buildingObject1.anchorX = 0

_buildingObject1.anchorY = 0

local function enterFrameListener(event)

    _buildingObject1:translate(-5, 0)

    if _buildingObject1.x <= 0 - _buildingObject1.width then

        _buildingObject1.x = _W

    end

end

Runtime:addEventListener(“enterFrame”, enterFrameListener)

=========

Is it possible that it’s the image that I’m using? It’s a quite tall rectangle shape, but it just seems to not be smooth… it jumps forward and “tears” occasionally.  I’ve attached the image for reference.

It appears that the building is 795 pixels tall? This isn’t excessively large, so it’s not a texture memory issue.

In this latest experiment, your sole code is what you show? Nothing else going on? And the performance is still bad on the device you mention? What is this device, may I ask?

Of course, in the “translate” function, you’re moving it by 5 pixels each time, if that’s what you mean by “choppy”.

Brent

The phone I’m using is an S4, so it’s pretty up-to-date hardware wise.  I’ve played with the number of pixels it moves, that just makes it slower/faster, it’s still just seems to “jump” like it will be moving along at a certain rate, then just skip a few pixels and jump forward.

Hi @atkinson.b,

Just to confirm once more… this is your entire project? As in, you basically have these 10-15 lines of code in “main.lua”, one image file (the building), and maybe a very basic “config.lua” and “build.settings” file? And you’re getting choppy performance on the S4?

Yes, this is my entire project.  I think the problem is not fixable, it’s a very slight jitter when “pulling” images across the screen.  I’ve taken a look at some of the “top” games developed using Corona, and it appears to be present in all of them.  Thief Job, for example… the demo video on the web site shows a side scrolling chase scene, and if you watch the buildings you can see them sort of non-smoothly “jump” every now and then, which is exactly what I’m experiencing.

It’s hard for me to determine how you’re interpreting “choppy”, as it’s somewhat prone to personal judgment. I suppose the Galaxy S4 could be considered in the same range as the iPhone5 in regards to hardware speed/performance? I have a game in development that I haven’t tested on an S4, but i’ve tested it on an iPhone5 and the performance is incredibly smooth. It does a considerable amount of processing too, under the hood… dozens of physics objects moving independently, sprites animating, sounds/music playing, etc. etc. I haven’t noticed any choppy performance on the iPhone5.

I think you should try to move the object using physics (setLinearVelocity) and also via a transition, as in your initial test. Also, try increasing the FPS to 60, if you haven’t already done so.

Brent

P.S. - is your actual phone nearly overloaded with other apps? As in, almost out of physical memory?

have you tried optimizing the image file

No, how would I go about optimizing the image file?

I have increased the FPS to 60, and my phone is not overloaded.  The “chop” I’m referring to also shows up in the demo video for Thief Job when I watch it on a PC, so I’m not entirely convinced there’s anything that can be done about it. For example, if you watch: https://www.youtube.com/watch?v=t_ZGBnmtem0 and watch the parts where he’s running along the rooftops and focus on the buildings he’s running on, you can notice them not moving completely smoothly.

on Mac I use imageoptim. not sure bout windows but they should have something sim.

Wow, good lookin product (the video). Anyways, about the stuttering…

One factor could be that it looks like you’re using enterFrame and (based on your sample) the timing appears to be based on enterFrame being called 30 (or 60) times per second.

However, I believe this is NOT guaranteed ( can CoronaLabs weigh in on this?) If you’re app is set for 30 fps, it might only get called 26 times (if your app/sdk does a lot of processing on 3-4 of the loops, and runs over through the next frame - it will be skipped).

This will affect your rate of movement across those 3-4 frames, and appear as a “stutter”. It’s of course most noticeable in your case on long vertical lines (building sides) since your side scrolling (horizontal lines if vertical scrolling).

The transition library tries to smooth these out by averaging the movement out across frames, but still - if there is a lot of processing going on in a frame (during enterFrame especially) it can completely cancel an entire screen update - it just gets skipped (again, can coronaLabs verify that setting to 30 fps does NOT guarantee 30 enterframe events per second / 30 screen updates? It can be defeated by coding issues?)

Anyways, I tried this on your test case, and with both the enterFrame method and the transition method, both looked the same. BUT… I don’t think this test case really represents your app… If it’s like the Thief Job, there’s at least 4 layers of depth with a lot going on during the enterFrame I would think, and perhaps during just a few of them (per second), it runs over into the next frame

[lua]

– replace above demo code from the enterFrame onward…

–Runtime:addEventListener(“enterFrame”, enterFrameListener)

local function resetBuilding()
    _buildingObject1.x = _W
    transition.to( _buildingObject1, { x=-_buildingObject1.width, time = 5000, onComplete = resetBuilding } )
end

resetBuilding()

[/lua]

This code does about the same thing. You might notice some interesting artifacts if you change the time period (5000). As it sits right now, it doesn’t look like the stuttering to me.

The test case looks more like the left edge pixel “crawls” back and forth, just a little, as the building moves. I don’t think it’s the stutter - but a mathematical artifact in this case – of the screen width (640) which is the movement distance, divided by the number of frames (5 seconds * 30 frames) = 4.266

This means for each enterFrame, for the movement to look perfectly smooth, the image should move exactly 4.266 pixels. But there aren’t fractions of pixels of course. So one obvious solution for the sdk is to average the xcoordinate out (which leaves it shifting 1 pixel every few calculations – the onscreen wiggle of the left edge we see). There’s only certain things you can do to battle the math at this level… Fuzzy edges can hide it for example, or using scroll rates that factor well…

Anyways, take it all with a grain of salt of course, but there may be an idea in there that provides a lead for you… Based on the video, you’re kickin some butt!

NOTE: There is a little weirdness in the sim with my changed code… If you set it to(30*640), 30*320), etc… You might be able to pin something down  etc… But it could just be a sim/mac issue, don’t have time to test on a device…

First, thanks everyone for taking the time to reply.  Second, I think you misunderstood, Thief Job is not my game, I was using it as a reference point because it’s listed in the “hall of fame”, showing that even the “top level” games seem to have this stuttering effect.  I’ve tried the transition method, re-calling with the onComplete, with the same results.  It’s not a terrible stuttering, just enough to be noticable and really bug me.  It appears there might not be a solution to the problem.  I’ve tested on numerous devices, a brand new S4 (my wife just got one) and in the emulator it’s still quite noticable no matter what I try.  Not sure if it’s even a Corona issue (perhaps Android in general has this problem), although I’ve seen other games that are seamless.

what if you tracked the previous position and compared it to the new position and if it’s more then expected back it up before image position is updated

If you have an enterframe event then you could track the fps delta (dt) and multiply it by your translation e.g. 

buildingObject:translate(speed \* dt, 0)

There is a good tutorial somewhere on using getTimer and delta fps.

This should compensate for fluctuations in frame rate and hopefully smooth out the movement, worth a try.

Edit: found the tutorial - https://coronalabs.com/blog/2013/06/18/guest-tutorial-delta-time-in-corona/