Vertical parallax scrolling

Started by
0 comments, last by pulo 11 years, 3 months ago
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
Advertisement

Maybe someone could explain how he has done it? I am not sure how to approach this problem, so my "solution" could be very wrong.

This topic is closed to new replies.

Advertisement