Author Topic: Falling sprite jitters like mad  (Read 2600 times)

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Falling sprite jitters like mad
« on: Mon, Jan 25, 2010 »
I've got a Tilemap that scrolls vertically. The FlxSprite player starts at the top and drops down.

It's working fine but for some reason the sprite is being drawn quite strangely - very often (but not all the time) it's as if the sprite is drawn 1 pixel lower than it should, and then a split second later is drawn 1 pixel higher again. The end result is that it looks like it's jiggling up and down (by 1 pixel) every time it updates.

It makes the sprite very flickering. I'm actually at a loss how to fix it. When the sprite collides and lands on a tile the flicker stops. If the sprite lands and moves left/right it doesn't flicker at all. It's just when falling.

I have tried various Y values for velocity, max velocity and accleration with no success. My guess is it could be a "rounding" issue - i.e. the Y value is a Number but of course with a bitmap engine it has to round to whole pixels, and sometimes it draws one line too far down. But I don't know how to fix it - it gives the visual effect of being "interlaced".

Has anyone seen this before / have any clues? The game is going perfectly other than this part! (the tilemap doesn't flicker at all)

Cheers,

Rich
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius

zuperxtreme

  • Contributor
  • ****
  • Posts: 254
  • Karma: +0/-0
    • View Profile
    • Buddah
Re: Falling sprite jitters like mad
« Reply #1 on: Mon, Jan 25, 2010 »
I'm having the same problem: http://flixel.org/forums/index.php?topic=866.0   :'(

..."without order nothing exists, without chaos nothing evolves"... 
Zoklet.net

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Re: Falling sprite jitters like mad
« Reply #2 on: Mon, Jan 25, 2010 »
Yeah I saw your post - it's certainly a similar issue. I've spent hours on it this evening trying to resolve it, and haven't got anywhere yet. I'm pretty sure it's a rounding issue. Time to download some sample games and see if they have the same issue.
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius

fefranca

  • Guest
Re: Falling sprite jitters like mad
« Reply #3 on: Mon, Jan 25, 2010 »
Hi Richard, like you said it is most likely an issue with rounding, done when your FlxSprite gets drawn to the screen. I am pretty sure the idea behind this is to avoid aliasing. Try extending FlxSprite and overriding this method:

Code: [Select]
//FlxSprite.as
override public function getScreenXY(P:Point=null):Point
{
if(P == null) P = new Point();
P.x = Math.floor(x-offset.x)+Math.floor(FlxG.scroll.x*scrollFactor.x);
P.y = Math.floor(y-offset.y)+Math.floor(FlxG.scroll.y*scrollFactor.y);
return P;
}

Let me know if that works out for you.

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Re: Falling sprite jitters like mad
« Reply #4 on: Mon, Jan 25, 2010 »
Thanks - that seemed to help sometimes! ... it's weird, as if there is a 1 in 3 chance of it getting into a "smooth" drop, and when it does it looks great, but the other 2 times it still jitters lots.

I notice that if I enable collision on the tilemap it has a much higher chance of jittering. If I disable that then your code above nearly always causes a smooth drop.
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius

fefranca

  • Guest
Re: Falling sprite jitters like mad
« Reply #5 on: Tue, Jan 26, 2010 »
Actually, that was just a copy/paste from the original FlxSprite class, sorry I didn't make it clear. The idea was be to adapt the code, I tested it on my own project and it seems this might work:

//FlxSprite.as
      override public function getScreenXY(P:Point=null):Point
      {
         if(P == null) P = new Point();
         P.x = x-offset.x+Math.round(FlxG.scroll.x*scrollFactor.x);
         P.y = y-offset.y+Math.round(FlxG.scroll.y*scrollFactor.y);
         return P;
      }

//FlxCore.as (used by FlxTilemap!)
      virtual public function getScreenXY(P:Point=null):Point
      {
         if(P == null) P = new Point();
         P.x = x+Math.round(FlxG.scroll.x*scrollFactor.x);
         P.y = y+Math.round(FlxG.scroll.y*scrollFactor.y);
         return P;
      }

Note the scrolling is not important as long as the same calculation is used for all your game objects.

cai

  • Contributor
  • ****
  • Posts: 465
  • Karma: +0/-0
  • the illest of villains
    • View Profile
    • Brandon Cash
Re: Falling sprite jitters like mad
« Reply #6 on: Tue, Jan 26, 2010 »
fefranca brought this up in IRC, and immediately my thought is that it's just the camera.

Try updating the lerp of the camera, either by adjusting FlxG.followLerp or setting it to a different amount in FlxG.follow().  Try a larger number, like 10 (default is 1).  Play around with different numbers, see what looks best for you.

If that doesn't help, I might have missed the mark entirely! :)
Follow me on Twitter | Come join us at #flixel on irc.freenode.net!

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Re: Falling sprite jitters like mad
« Reply #7 on: Tue, Jan 26, 2010 »
Hi guys,

Thanks for both of your suggestions. Sadly neither work - modifying the getScreenXY is a nice idea, but the camera methods use the FlxCore x/y values directly (bypassing that), the render stage used getScreen but the problem has already been cause by that point :(

I have tried loads of lerp/adjust settings cai! You're right though, the issue is camera related for sure, in relation to the x/y coords of the FlxSprite it is tracking.

So far I have tried:

1) Totally disabling the double-buffer, so it writes to one bitmap only. No dice.

2) Replaced the "doFollow()" method with my own, that cast the coords to ints before rendering. This helped, but the sprite still flickers as it gains acceleration - but once it hits maxVelocity it is stable.

3) In the FlxSprite update() method these two lines sit at the bottom:

Code: [Select]
x += (velocity.x = FlxG.computeVelocity(velocity.x, acceleration.x + thrustComponents.x, drag.x, maxVelocity.x)) * FlxG.elapsed;
y += (velocity.y = FlxG.computeVelocity(velocity.y, acceleration.y + thrustComponents.y, drag.y, maxVelocity.y)) * FlxG.elapsed;

This is what causes the jitter. If I add this:

Code: [Select]
x = Math.round(x);
y = Math.round(y);

After them, then I get pixel perfect smooth scrolling sprites, every time. However now all the tile collision tests are screwed (landing on something often causes it to get stuck there). Also all of the nice smoothing (acceleration / deceleration) has of course gone because this value needs to progress smoothly.

I'm at a bit of a loss as to what to try next to be honest.
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Re: Falling sprite jitters like mad
« Reply #8 on: Tue, Jan 26, 2010 »
I ripped out everything I had added / changed, rolled back to a default Flixel version fresh from Github, and then put the exact same values for the sprite / camera as used in Mode.

And it works ok - the scrolling is smooth (way too fast, but smooth) and the sprite doesn't flicker on bit. Those values must be "just right" to fit into the timing / rounding threshold needed. Which is a shame because in this game I need the player to "float" down, like a bubble.. not sink like a lead bomb ala Mode.

It's a start ... let's see what can be tweaked.
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius

fefranca

  • Guest
Re: Falling sprite jitters like mad
« Reply #9 on: Tue, Jan 26, 2010 »

This is what causes the jitter. If I add this:

Code: [Select]
x = Math.round(x);
y = Math.round(y);

After them, then I get pixel perfect smooth scrolling sprites, every time. However now all the tile collision tests are screwed (landing on something often causes it to get stuck there). Also all of the nice smoothing (acceleration / deceleration) has of course gone because this value needs to progress smoothly.

I'm at a bit of a loss as to what to try next to be honest.

If that fixed the problem, why not change only getScreenXY to round (x,y) instead of flooring it on FlxSprite.as?
Code: [Select]
override public function getScreenXY(P:Point=null):Point
{
if(P == null) P = new Point();
P.x = Math.round(x-offset.x)+Math.floor(FlxG.scroll.x*scrollFactor.x);
P.y = Math.round(y-offset.y)+Math.floor(FlxG.scroll.y*scrollFactor.y);
return P;
}

This won't interfere with collisions, only rendering.

EDIT:
What might might help you close down on the problem is to set FlxGame.MAX_ELAPSED to a large number, like 1.0 (seconds), that way you will know if this is a framerate drop issue (very unlikely on desktop Flash Player though).
« Last Edit: Tue, Jan 26, 2010 by fefranca »

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Re: Falling sprite jitters like mad
« Reply #10 on: Tue, Jan 26, 2010 »
I did try your revised getScreenXY, believe me I did! I've spent hours trying to solve this and just work out how it all operates under the hood :)

I've actually got a set of values now which I feel work pretty well together, so I'm getting close. I'm finding the way it handles "physics" very limiting at the moment, but that's a project for another day. Right now I need to get this game finished pronto! :)
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius