1
\$\begingroup\$

I'm trying to implement parallax scrolling and have a partially working equation (from a book I've read) but it doesn't fully align to the screen. I also want to stick purely to integer maths. I've played around with it a lot and tried alternate approaches but can't get it right.

Unfortunately the book doesn't go into detail of how the maths is supposed to work it just glosses over it.

The calculation is:

x * (screenWidth - layerWidth) / (screenWidth - playfieldWidth)

Variables I'm inputting are the following values:

x = Player x Position within playfield width the others should be self explanatory

The book also calculates x as (screenWidth / 2 - playerX - tilewidth) which I've tried.

The only difference I can think of is that to the book the player X co-ordinate is left of the player where for my engine it's the centre, but I changed - tileWidth to account for that to no avail.

The way it should work is when the player is at 0 the left-most pixel of the layer should be at the left edge of the screen and when the player is at (playfieldWidth - 1) then the right most pixel of the layer should be touching the right of the screen.


I finally figured it out, after tracking down the fact that I had a small rendering bug that shifted things a few pixels (oversight from adding overscan)

The final algorithm is as follows and works as long as layer is equal to or lower than screen width which i derived from scroll bar maths

public static final int calculateScroll(final int scroll, final int minScroll, final int maxScroll, final int contentSize) {
    return (scroll - minScroll) * contentSize / (maxScroll - minScroll);
}

scrollX = calculateScroll(playerX, 0, playfieldWidth, screenWidth - layerWidth + 1);

I'm sure it will work for layers that are larger than the screen width just need to figure out the right input values


After further playing I realised the variable I was using for testing the larger than viewport layers was incorrect and throwing everything off, that's now been fixed and i've refined the final function

  public static final int calculateScroll(final int scroll, final int minScroll, final int maxScroll, final int contentSize, final int viewportSize) {
    return (minScroll / 2 - scroll) * (contentSize - viewportSize) / (maxScroll - minScroll);
  }
\$\endgroup\$
  • 1
    \$\begingroup\$ Most likely obvious but what exactly does layerWidth represent? \$\endgroup\$ – newton1212 Jun 14 '15 at 12:17
  • \$\begingroup\$ width of the layer within the playfield being rendered, which is assumed to be less or equal to playfield width \$\endgroup\$ – Cyber Axe Jun 14 '15 at 13:00
  • \$\begingroup\$ Using strictly integers with animations is like putting on concrete shoes and trying to run a marathon. Even if you do complete your method, the end result will not look very good. \$\endgroup\$ – StrongJoshua Jun 15 '15 at 16:29
  • \$\begingroup\$ If one requires extra precision one can always use fixed points without having to resort to real numbers, I've found them to work just as good in each situation I've used them in so far. Though in this situation I wanted to stick to maths similar to what would have been used in the early to mid 90s which seems smooth enough. \$\endgroup\$ – Cyber Axe Jun 15 '15 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.