1
\$\begingroup\$

I want to create a Windows Phone jump-and-run game with parallax scrolling. The character should always be in centered in the viewport.

I use the following camera so that the viewport looks on every resolution the same:

Vector2 vp, gameWorldSize = new Vector2(800, 480);
vp = new Vector2(GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
ScaleX = vp.X / gameWorldSize.X;
ScaleY = vp.Y / gameWorldSize.Y;
Scale = Math.Min(ScaleX, ScaleY);
Vector2 PlayerPosition;
Vector2 Viewport;
float Scale;

public Matrix GetMatrix(float scrollingspeed)
{
  return Matrix.CreateTranslation(new Vector3(-PlayerPosition.X, -PlayerPosition.Y, 0) * scrollingspeed)
   * Matrix.CreateScale(Scale, Scale, 1)
   * Matrix.CreateTranslation(Viewport.X / 2, Viewport.Y / 2, 0);
}

I draw the sprites like this:

spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, camera.GetMatrix(0.8f));  
  BackgroundLayer1.Render(spriteBatch);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, camera.GetMatrix(1.0f));
  Player.Render(spriteBatch);
spriteBatch.End();

//in the Player class:
batch.Draw(Playertex, new Rectangle(400, 240, Playertex.Width, Playertex.Height), null, Color.White, 0, new Vector2(Playertex.Width / 2, Playertex.Height / 2), SpriteEffects.None, 0f);
//in the BackgroundLayer1 class:
batch.Draw(Background1tex, new Rectangle(400, 240, Background1tex.Width, Background1tex.Height), null, Color.White, 0, new Vector2(Background1tex.Width / 2, Background1tex.Height / 2), SpriteEffects.None, 1.0f);

The camera is working fine and the player is always in the center of the viewport, but I don't know how to implement Parallax Scrolling. What is the best way to implement Parallax Scrolling?

How can I create a resizeable 2D viewport that follows the player and supports parallax scrolling?

UPDATE1: In addition, the background sprites shouldn't repeat in a loop, because I have ten 800x480 pixel sprites that are drawn one after another. For example, the first sprite is drawn at (0,0), the second at (800,0), the third at (1600,0), … The last sprite(number 10) is the end of the level. The player can move back but not further. I will create more than one layer of sprites, but every layer with a different speed factor to create the Parallax Scrolling.

How can I add the speed factor so that the background sprites move slower than the player sprite?

UPDATE2: If I draw "BackgroundLayer1" with a scrolling speed of 1.0f, the sprite is drawn on the correct position, but if I change the scrolling speed to another value(for example 0.8f), then the sprites of "BackgroundLayer1" aren't drawn on the correct position.

Why are the sprites of "BackgroundLayer1" not drawn on the same position if I change the scrolling speed? What is wrong? The sprites should be drawn on the same positions, even if I change the scrolling speed.

In these two pictures, you see the differences if I change the scrolling speed of BackgroundLayer1:

scrollingspeed = 1.0f

http://s1.directupload.net/images/140505/qdi6cqwz.jpg

scrollingspeed = 0.8f

http://s1.directupload.net/images/140505/56ferzuv.jpg

\$\endgroup\$
4
+50
\$\begingroup\$

The X position of the background have to be calculated with the X position of the player and a speed factor.

 Texture2D ParallaxTex;
 Rectangle ParallaxBounds = graphics.Viewport.Bounds;

 spriteBatch.Begin();  //With no camera view transform

 ParallaxBounds.X = (Player.X * Factor) % ParallaxBounds.Width;

 spriteBatch.Draw(ParallaxTex, ParallaxBounds, null, Color.White);

 ParallaxBounds.X -= ParallaxBounds.Width;

 spriteBatch.Draw(ParallaxTex, ParallaxBounds, null, Color.White, ..., SpriteFlips.Horizontally);

 spriteBatch.End();
\$\endgroup\$
  • \$\begingroup\$ Why is there no camera in the spriteBatch.Begin()? I need a camera in my side scrolling game. Secondly, why are you drawing the texture "ParallaxTex" two times? \$\endgroup\$ – Homer_Simpson May 3 '14 at 20:37
  • \$\begingroup\$ The background is drawed relative to the screen. Its position is not a world position, it is a screen position. If you draw the background at X=200 the area from X=0 to X=200 will be not drawn. So its needed to draw it two times. One at X=200px and other at X=200px-BackgroundWidth \$\endgroup\$ – Blau May 3 '14 at 20:40
  • \$\begingroup\$ It's not working for me. For example, the sprites are not getting scaled when I use a higher resolution than 800x480, because there is no camera parameter in the spriteBatch. Where(in which spriteBatch?) should I implement my camera as a parameter in spriteBatch if I use Parallax Scrolling? In addition, the background sprites shouldn't repeat in a loop, because I have ten 800x480 pixel sprites that are drawn one after another. For example, the first sprite is drawn at (0,0), the second at (800,0). How can I add the speed factor so that the background sprites move slower than the player sprite? \$\endgroup\$ – Homer_Simpson May 4 '14 at 11:10
  • \$\begingroup\$ It depends on how you want do it. I didn't know if you have more backgrounds, and usually a parallax is not supposed to get scaled with your sprites. If you want to do so, build some quads with your backgorunds and give them coordinates in world position, as you do with the platforms tiles \$\endgroup\$ – Blau May 5 '14 at 1:29
  • \$\begingroup\$ I tried to add a scrolling speed variable to change the speed of the different background layers, but the sprites aren't getting drawn on the correct positions if I change the scrolling speed to another value than 1.0f. What is wrong? Why are sprites drawn on a different position if I change the scrolling speed value? The sprites should be drawn on the same positions, even if I change the scrolling speed. \$\endgroup\$ – Homer_Simpson May 5 '14 at 20:56

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.