0 Favourites

Retro Style Platformer Issues (Jitters And Shaking BG Sprite

  • Hi everyone,

    I recently switch from cocoonJS to XDK and im having alot of the issues that i tackled arise again on me for some odd reason.

    Im having some issues with a Jittery Platformer Movement and some Jittery Background images that are set to Parallax scroll on the horizontal axis.

    Im making a game using TileMaps and yes i have Pixelated retro style sprites.

    I just posted on the XDK thread because of an issue that involved blackbars appearing on my mobile device,Once i fixed that i started to see that my platformer character is Jittering so much that it is just an eyesore and in my OP its unplayable like that!

    What i tried to do was use True Pixel Rounding and set the players position to Round(Player.X) Round(Player.Y) But still was able to see jittering plus i seen a 1-2 pixel wide gap underneath my player mask(Which i thought was fixed)

    Im really at my wits end with the jittering player,What is the definite fix for this.Only thing i came up with was True Pixel Rounding. Thanks guys,Im sorry for being frustrated i didnt want my mood to alter how i talk on the site.

  • Anyone Know how to fix the jittering? I cant export a game in this condition.

  • Did yountried with pixel rounding on Off?

    Last time I tried to do a pixellated game, point sampling was enough to do what I wanted (but that was a long time ago though, so that may not be the ideal solution)

  • Aphrodite That was my first guess,I messed around with all of the settings and when using Tilemaps it forces you to use specific settings if anyone forgot about that.

    Ive toggled most of them on and off and still seem to see a bit of jitters,I ended up lerping my camera for smoother movement and it has worked somewhat but some jitters are still visible in the character mask and background sprites.

  • I did not though about tilemaps, and some people seems to not have great results with the seamless mode ofthe tilemap either, if it is a retro style project using point sampling, the low quality setting may do the trick for the tilemap, but I cannot guarantee it.

  • Jittering can be caused by a number of things.

    -Game resolution

    -Player movement speed

    -Camera Code

    -Parallax Settings

    -Project Settings

    Only way to get perfectly smooth scrolling in low-res games is to move the player the same speed as the refresh rate..but uh..yeah..y'know. Or you can disable pixel rounding and use high quality fullscreen scaling..but then your graphics move on "sub-pixels" and you risk seams as well.

  • Yeah, the most sure way to get smooth updates for pixel-graphics is to move your player by whole integer increments for every update. Whether or not that's a good solution for you depends on pixel fidelity I guess? You could try moving by 0.5 and round() as well. In theory that means the player moves 1 pixel every second update. Other than that, best way to go is like Tokinsom said and use high-quality scaling/no pixel-rounding. It'll get you non-square pixels but if the screen resolution vs game resolution is high enough it may not be noticable.

  • Thank you guys,I really wish i would of known this before i started my retro style game,It seems like anyone that wants to create pixel games is in for a rough time using construct 2 and there are plenty of post complaining about Seams,Jittering....ect.

    I think alot of these issues need to be addressed Ashley because this is something a new person would not know unless they dug deep within the forums before they bought the product.

    Any possible way to make it easier on people that use retro style graphics would be a plus,There should be no possible way that someone should have issues with something like the Movement,In my OP shaking and jittering is really unprofessional looking,I played tons of games on mobile that are pixel games but run so smooth you couldnt tell.

    GROWTOPIA for ANDROID and IOS is a free to play platformer and is a great example,Im trying to mimic the smooth movement and can not.

    Thank you all for posting here ErekT Tokinsom Aphrodite i will try my luck with your logic.

  • As always share a .capx or all we can do is wildly speculate. If I were to wildly speculate I'd guess you used an animated platform object and the animations are causing the jitter.

  • Some of the issues with seams have already been solved. If you turn off pixel rounding, set sampling to point, and fullscreen to letterbox integer scale, you can play with the fullscreen options at runtime (browser: request fullscreen, for example) to get good results.

  • How are you doing your camera positioning? I've set up a system that works pretty well for me. The camera, or CamFocus object, will scroll smoothly to a position ahead of the Player object (Character). When it's moved within a certain range of the destination (between 39 and 41) I just snap it into the integer position "round( Character.X + 40 )". The player sprite itself is separate from the Character object and is always drawn at round(Character.X/Y) positions.

    For a camera that's fixed to the player's position at all times, it should be enough to just set camera.x/y to round(player.x/y) and set sprite.x/y to round(player.x/y). If you need a catch-up camera like I do, there's an extra trick you can do that I'll describe below.

    Couple of cave-ats with this tho'.

    One:

    I'm modifying C2's layout.js to make it render to a point-sampled texture. This way I get sharp pixels on integer positions, and interpolated pixels on float positions, even though I've got sampling set to linear in project settings. Only use if you don't mind modifying layout.js every time you update C2. As far as hacking into the official code goes, it's discouraged by Ashley for obvious reasons but this change is entirely cosmetic so I'm pretty much 100% sure it's not gonna break anything.

    Two:

    For a pixel-art game it's not perfect. Like I said, if you just fix the camera position to the player's movement you shouldn't even need to use it. But with a catch-up camera both the player sprite and other moving graphics will get blurred by interpolation until the camera has moved into position. I found that this doesn't look so bad; it's a temporary blur and everything's moving pretty fast so it's not all that noticable.

    Three:

    You need to use low-quality scaling with layout scale = 1 (default) for it to work. But since you're doing a pixel-art game that shouldn't be a problem.

    If you want to try it out, back up layout.js in exporters/html5 and replace these lines:

    Line 540 (inside Layout.prototype.draw = function (ctx)):

    [quote:jiim5lbr]

    if (ctx_changed)

    {

    layout_ctx["webkitImageSmoothingEnabled"] = this.runtime.linearSampling;

    layout_ctx["mozImageSmoothingEnabled"] = this.runtime.linearSampling;

    layout_ctx["msImageSmoothingEnabled"] = this.runtime.linearSampling;

    layout_ctx["imageSmoothingEnabled"] = this.runtime.linearSampling;

    }

    ... with these:

    [quote:jiim5lbr]

    if (ctx_changed)

    {

    // ErekT mod:

    layout_ctx["webkitImageSmoothingEnabled"] = this.runtime.pointSampling;

    layout_ctx["mozImageSmoothingEnabled"] = this.runtime.pointSampling;

    layout_ctx["msImageSmoothingEnabled"] = this.runtime.pointSampling;

    layout_ctx["imageSmoothingEnabled"] = this.runtime.pointSampling;

    }

    And these lines:

    Line 584 (inside Layout.prototype.drawGL = function (glw))

    [quote:jiim5lbr]

    if (render_to_texture)

    {

    // Need another canvas to render to. Ensure it is created.

    if (!this.runtime.layout_tex)

    {

    this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);

    }

    // Window size has changed (browser fullscreen mode)

    if (this.runtime.layout_tex.c2width !== this.runtime.draw_width || this.runtime.layout_tex.c2height !== this.runtime.draw_height)

    {

    glw.deleteTexture(this.runtime.layout_tex);

    this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);

    }

    ... with these:

    [quote:jiim5lbr]

    if (render_to_texture)

    {

    // Need another canvas to render to. Ensure it is created.

    if (!this.runtime.layout_tex)

    {

    // ErekT mod

    this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.pointSampling);

    }

    // Window size has changed (browser fullscreen mode)

    if (this.runtime.layout_tex.c2width !== this.runtime.draw_width || this.runtime.layout_tex.c2height !== this.runtime.draw_height)

    {

    glw.deleteTexture(this.runtime.layout_tex);

    // ErekT mod

    this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.pointSampling);

    }

    Then restart C2. Good to go.

    A bonus you get with this is the ability to turn point-sampling on/off during runtime. Just increase layout scale or turn on high-quality scaling to enable linear sampling. It looks exactly the same as with vanilla C2 as far as I can tell.

  • I've actually seen these problems in other creation software. It seems to be a common problem when making pixel-accurate games with engines that are designed with higher resolutions in mind. Erek's potential solution is sophisticated sure, but most people probably shouldn't need to go to those lengths to eliminate all of the movement stutters. Risk seams or other undesirable side-effects by leaving pixel rounding off, or set it to on and constantly wrestle with every movable object in your game to ensure that every number is being rounded to an integer.

    Ashley Is it possible for behaviors like MoveTo or Sine to account for whether pixel rounding is set to on or off? Are they supposed to already do that? On my end, they seem to operate in fractions regardless of what project properties are set. If we can force these behaviors to always use integers with round(), surely it's possible to implement some kind of option that will just make them default to that?

  • Construct 3

    Buy Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Buy Now Construct 3 users don't see these ads
  • I actually did not encounter those problems, but maybe that was because of the interger letterbox scaling combined with low quality and not using the pixel rounding nor the round() of any sort.

    Amanita : unless I am unaware, the moveto behavior is not maintained at all by scirra so this is not a question to ask to ashley, but I agree that the pixel rounding seems pretty much useless.

  • My mistake, I meant ScrollTo. MoveTo is one of Rex's add-ons.

    I haven't been using pixel rounding since having these issues crop up. Despite that, aside from the overt smoothness of everything I haven't really seen any seams or related problems pop up. I guess it's a plausible solution to just ignore that option nowadays? I'd like to say that conclusively, but I'm not as versed in Construct as other similar programs.

  • ErekT - your code modifications make no sense, referring to property names that don't exist. It looks like it will have identical effect to set 'Sampling' to 'Point' in project properties, which sets linearSampling to false and turns it off, as opposed to accessing the non-existent pointSampling property which returns undefined which is probably also interpreted as false.

    I still have no idea what people are talking about when they say things are jittery, and still nobody has provided a .capx to demonstrate. Everything has always worked perfectly from C2's side as far as I've ever seen. My best theory is that everything is working correctly and the perceived "jitter' is simply the difference between point and linear sampling. Linear sampling can look very smooth and elegant, especially when scrolling slowly, because it can render smoothly along sub-pixel positions. When you switch to point sampling, what you are telling Construct 2 to do is to turn off that lovely smooth linear sampling and revert to a nearest-neighbour filter. This can sometimes look comparitively "jumpy", since it will not render any sub-pixel positions - it will pick a side, and go with that. So scrolling slowly goes from a lovely smooth sub-pixel transition to occasional pixel-size jumps. I would agree this does not look so good, but by choosing point sampling you are literally asking for that to happen.

    So in other words this is the normal, expected result in computer graphics. It's more to do with how digital rendering works than Construct 2 itself. That would also explain why Amanita has observed it in other tools.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)