Sign in to follow this  
pulo

Vertical parallax scrolling

Recommended Posts

i have set up a simple 2D game with the help of the Platformer Starter-Kit for XNA. I have reworked the CameraCode (to have it in a own class with a transformation matrix). Now i want to have vertical parallax scrolling (it works fine horizontally) but i cannot get it to work vertically.
Here is how it is set up:
 

 

 private void ScrollCamera(Viewport viewport)
            {
    
                const float ViewMargin = 0.35f;
    
                // Calculate the edges of the screen.
                float marginHeight = viewport.Height * ViewMargin;
                float marginTop = cameraPositionY + marginHeight;
                float marginBottom = cameraPositionY + viewport.Height - marginHeight;
    
                float marginWidth = viewport.Width * ViewMargin;
                float marginLeft = cameraPositionX + marginWidth;
                float marginRight = cameraPositionX + viewport.Width - marginWidth;
    
                // Calculate how far to scroll when the player is near the edges of the screen.
                float cameraMovementX = 0.0f;
                if (Player.Position.X < marginLeft)
                    cameraMovementX = Player.Position.X - marginLeft;
                else if (Player.Position.X > marginRight)
                    cameraMovementX = Player.Position.X - marginRight;
    
                float cameraMovementY = 0.0f;
                if (Player.Position.Y < marginTop)
                    cameraMovementY = Player.Position.Y - marginTop;
                else if (Player.Position.Y > marginBottom)
                    cameraMovementY = Player.Position.Y - marginBottom;
    
                // Update the camera position, but prevent scrolling off the ends of the level.
                float maxCameraPositionY = Tile.Height * Height - viewport.Height;
                float maxCameraPositionX = Tile.Width * Width - viewport.Width;
                cameraPositionX = MathHelper.Clamp(cameraPositionX + cameraMovementX, 0.0f, maxCameraPositionX);
                cameraPositionY = MathHelper.Clamp(cameraPositionY + cameraMovementY, 0.0f, maxCameraPositionY);
            }

 

 
This function calculates the current position of the camera. 
 
 - "Height" = tiles.GetLength(1) where "tiles" is a 2D Array and 
 - "Width" = tiles.GetLength(0). So my world is represented in this 2D array
 - Tile.Height and Tile.Width are the dimensions of my Tiles (i am currently working with tiles of the same size)
 
Now i am using this draw-call:
 
    

 

spriteBatch.Begin();
                for (int i = 0; i <= EntityLayer; ++i)
                    layers[i].Draw(spriteBatch, camera._pos, i);
                spriteBatch.End();
    
                ScrollCamera(spriteBatch.GraphicsDevice.Viewport);
                camera._pos = new Vector2(cameraPositionX, cameraPositionY);
    
                spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, camera.get_transformation(spriteBatch.GraphicsDevice));
    
                DrawTiles(spriteBatch);
    
                Player.Draw(gameTime, spriteBatch);
    
                spriteBatch.End();
    
    
                spriteBatch.Begin();
    
                for (int i = EntityLayer + 1; i < layers.Length; ++i)
                    layers[i].Draw(spriteBatch, camera._pos, i);
    
                spriteBatch.End();

 

 
I want to control the drawing process of the brackground layer seperately, like so:
 
 
 
   

 

 public void Draw(SpriteBatch spriteBatch, Vector2 cameraPosition, int index)
            {
                int segmentWidth = Textures[index].Width;
                int segmentHeight = Textures[index].Height;
    
                // Calculate which segments to draw and how much to offset them.
                float x = cameraPosition.X * ScrollRate;
                int leftSegment = (int)Math.Floor(x / segmentWidth);
                int rightSegment = leftSegment + 1;
                x = (x / segmentWidth - leftSegment) * -segmentWidth;
    
                float y = cameraPosition.Y * ScrollRate;
                int topSegment = (int)Math.Floor(y / segmentHeight);
                y = (y / segmentHeight - topSegment) * -segmentHeight;
    
                spriteBatch.Draw(Textures[leftSegment % Textures.Length], new Vector2(x, y + 136f), Color.White);
                spriteBatch.Draw(Textures[rightSegment % Textures.Length], new Vector2(x + segmentWidth, y + 136f), Color.White);
            }

 

 
Now i am pretty sure that there is problem with my calculation of my "y" but i cannot see it. Maybe someone can give me a hint or just a better way to approach this problem. Thanks a lot!
 
EDIT: Forgot to mention that it works fine for the tiles.
 
EDIT2: Sorry forgot to explain further: The Background Layers are scrolling nice horizontally but aren't aligned to the ground. They have an offset in the y-direction wich gets bigger and bigger depending on the total height of the level. I hope this clears some questions. If you still have some please let me know (i can also provide a screenshot if necessary) Thanks a lot

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this