0
\$\begingroup\$

I'm working on a 2D space shooter type of game in typescript using Phaser 3 and am trying to get a parallax background with different depths going. But I'm having trouble getting the math right.

You can see my work in progress here: https://www.youtube.com/watch?v=Pea9yVbTD64

As stated in the video everything works if the players x and y are positive, but breaks when they are negative, and I can't figure out what I am doing wrong. Any help would be greatly appreciated. Or perhaps there is a better way to accomplish this?

What I'm doing is randomly generating out a bunch of the Sprites, storing them in an Array, and then updating their position with this code.

  • _Nebulas: is an Array<NebulaParticle>.
  • p.distance: is a number between 1 and 5 to signify how far away the sprite is and is used to make them move slower when they are furher away.
  • _Width and _Height are both arbitrary numbers to signify how big the area is that the parallax should cover, in the video they are both set to 80.
  • OriginalOffsetX/Y is the original random position the Sprite was given.

(this line is here because the below code formatting wont work otherwise.)

public update(delta: number, playerx: number, playery: number) {
 console.log(playerx + ", " + playery );
 for (let i = 0; i < this._Nebulas.length; i++) {
 let p = this._Nebulas[i]; 
 p._Sprite.x = (playerx + (this._Width / 2)) - (((playerx / p.distance) + p.OriginalOffsetX) % this._Width);
 p._Sprite.y = (playery + (this._Width / 2)) - (((playery / p.distance) + p.OriginalOffsetY) % this._Height);
 }
}
class NebulaParticle {
 public _Sprite: Phaser.GameObjects.Sprite;
 public OriginalOffsetX: number;
 public OriginalOffsetY: number;
 public distance: number;
}
asked Dec 4, 2018 at 20:29
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

The reason you're having trouble is the behaviour of the modulo operator % in JavaScript. (And therefore in TypeScript.) If the dividend is negative then the remainder will also be negative:

console.log((-729) % 100); // -29

and your code is assuming that the result of a division modulo d will always fall into the range 0 to d, when in fact it falls into the range -d to d.

My usual workaround is to add another copy of the modulo at the end, to force the result to be positive, and then take the modulus again. So add this line:

p._Sprite.x = (playerx + (this._Width / 2)) - (((playerx / p.distance) + p.OriginalOffsetX) % this._Width);
p._Sprite.x = (p._Sprite.x + this._Width) % this._Width;

and the same for the y-coordinate.

answered 2 days ago
\$\endgroup\$
1
  • \$\begingroup\$ I know this question is nearly 7 years old, but it got bumped to the front page and I figured I might as well answer it while it's there. \$\endgroup\$ Commented 2 days ago
0
\$\begingroup\$

Just use a camera with the gameobject method setScrollFactor. Setting 0 makes it fixed to the camera; setting a number between 0-1 will make it scroll at varying rates, which you can use to set up parallax scrolling layers.

See an example here

answered Dec 5, 2018 at 5:44
\$\endgroup\$
2
  • \$\begingroup\$ Thank you, but I can get this to work, the problem comes in when I want to loop around an object so that when it leaves the trailing edge it comes in on the leading one. That is I want the parallax background to be infinite and self looping in all directions forever. \$\endgroup\$ Commented Dec 5, 2018 at 8:03
  • \$\begingroup\$ In the example you linked the hotdog should come back in on the leading edge when it goes out of the screen view from being left behind, it's that part which I can't get right. \$\endgroup\$ Commented Dec 5, 2018 at 8:04

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.