[HELP] Side Scrolling 2D game in SFML

Started by
6 comments, last by BrianJensen 12 years, 8 months ago
I am trying to make a side scrolling game (like mario) using SFML in c++. I have already implemented the side scrolling mechanism and now the screen's background gets scrolled perfectly. I also have made my character(move along the screen). Now the problem is : How do I get other sprites (such as the walls in mario) which are not currently visible; to scroll along with the background while player presses a key???
Advertisement
Ok, you don't.

When doing the scrolling, you should be only actively moving the items that are visible to your player. So, you don't scroll your background to match your player, you move your background in to the screen as it becomes visible.

I know that didn't come across as clearly as I wanted, but think about it this way. Picture you level as one giant 10000x10000 pixel jpg, and your screen as a 640x480 viewport of that picture. You dont modify the underlying picture itself, you instead move around your viewport of that picture. Or in other words, your world doesn't get translated, your perspective of it does.

Ok, you don't.

When doing the scrolling, you should be only actively moving the items that are visible to your player. So, you don't scroll your background to match your player, you move your background in to the screen as it becomes visible.

I know that didn't come across as clearly as I wanted, but think about it this way. Picture you level as one giant 10000x10000 pixel jpg, and your screen as a 640x480 viewport of that picture. You dont modify the underlying picture itself, you instead move around your viewport of that picture. Or in other words, your world doesn't get translated, your perspective of it does.



Thank you for your reply... I will try getting an entire level in an image just as you said... but I have a question: do I move my player along with the viewport or I just keep my player static in just one place no matter where the viewport is???

Again, thankyou for your response

I can't give a thorough answer, I'm on my phone, but I wanted you to know the big image comment was just an analogy.

Google tile engine scrolling. That is what you want.
Say map is 10000x10000 like previous person stated lets assume that you want to scroll left and right. The "MAP" will have a fixed position, we will say 1 to 10000, and the viewport(or section that is viewable to player) is 640x480. If you wanted to scroll right:

Record the locations, X and Y or Both (both for top/bottom left/right scrolling). Then you need an Offset variable, I usually use OffsetX and OffsetY. Every time the player pushed the arrow(or whatever) that would move the character you change the Offset variable.

When drawing the map you need to make the starting position(X or Y) of your map that you are drawing increased by the Offset variable and then the ending position increased by the Offset + Screen(Width or Height depending on which you want to scroll)

Here is a coding example. Written in Java, but gives you a basic example. Ripped right out of my Scrolling RPG example. Ignore the collision code. Will supply entire source that I ripped this out but the code examples below should have good readability as I use decent variable names.


private void DrawMap(Graphics g, int[][][] map)
{
for (y = MapOffsetY / BlockHeight; y < MapOffsetY / BlockHeight + ScreenHeight / BlockHeight + 2; y++)
{
for (x = MapOffsetX / BlockWidth; x < MapOffsetX / BlockWidth + ScreenWidth / BlockWidth + 2; x++)
{
if (y < MapMaxY && y >= 0 && x < MapMaxX && x >= 0)
{
Block.setFrame(map[MAPNumber][y][x]);
draw_sprite(g, Block, x * BlockHeight - MapOffsetX, y * BlockWidth - MapOffsetY);
}
}
}
}
...
private void MoveMap(int[][][] map, int[][]BlockStruct)
{
int keystate = getKeyStates();
if (MoveMap)
{
if ((keystate & RIGHT_PRESSED) != 0 && ScrollRight
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX + (charBlob.getWidth() / 2) + STEP * 2, myBlob.y + MapOffsetY - (charBlob.getHeight() / 2) - STEP) == 0)
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX + (charBlob.getWidth() / 2) + STEP * 2, myBlob.y + MapOffsetY + (charBlob.getHeight() / 2) + STEP) == 0)
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX + (charBlob.getWidth() / 2) + STEP * 2, myBlob.y + MapOffsetY) == 0))
{
MapOffsetX += STEP;
if (MapOffsetX > (MapMaxX * BlockWidth) - ScreenWidth)
{
MapOffsetX = (MapMaxX * BlockWidth) - ScreenWidth;
ScrollRight = false;
MoveRight = true;
}
blobMove = true;
}
if ((keystate & LEFT_PRESSED) != 0 && ScrollLeft
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX - (charBlob.getWidth() / 2) - STEP * 2, myBlob.y + MapOffsetY - (charBlob.getHeight() / 2) - STEP) == 0)
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX - (charBlob.getWidth() / 2) - STEP * 2, myBlob.y + MapOffsetY + (charBlob.getHeight() / 2) + STEP) == 0)
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX - (charBlob.getWidth() / 2) - STEP * 2, myBlob.y + MapOffsetY) == 0))
{
MapOffsetX -= STEP;
if (MapOffsetX < 0)
{
MapOffsetX = 0;
ScrollLeft = false;
MoveLeft = true;
}
blobMove = true;
}
if ((keystate & UP_PRESSED) != 0 && ScrollUp
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX - (charBlob.getWidth() / 2) - STEP, myBlob.y + MapOffsetY - (charBlob.getHeight() / 2) - STEP * 2) == 0)
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX + (charBlob.getWidth() / 2) + STEP, myBlob.y + MapOffsetY - (charBlob.getHeight() / 2) - STEP * 2) == 0)
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX, myBlob.y + MapOffsetY - (charBlob.getHeight() / 2) - STEP * 2) == 0))
{
MapOffsetY -= STEP;
if (MapOffsetY < 0)
{
MapOffsetY = 0;
ScrollUp = false;
MoveUp = true;
}
blobMove = true;
}
if ((keystate & DOWN_PRESSED) != 0 && ScrollDown
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX - (charBlob.getWidth() / 2) - STEP, myBlob.y + MapOffsetY + (charBlob.getHeight() / 2) + STEP * 2) == 0)
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX + (charBlob.getWidth() / 2) + STEP, myBlob.y + MapOffsetY + (charBlob.getHeight() / 2) + STEP * 2) == 0)
&& (Collided(map, BlockStruct, myBlob.x + MapOffsetX, myBlob.y + MapOffsetY + (charBlob.getHeight() / 2) + STEP * 2) == 0))
{
MapOffsetY += STEP;
if (MapOffsetY > (MapMaxY * BlockHeight) - ScreenHeight)
{
MapOffsetY = (MapMaxY * BlockHeight) - ScreenHeight;
ScrollDown = false;
MoveDown = true;
}
blobMove = true;
}
}
}



Pastebin of entire code: Canvas Java Sorry that you'll have to look through 655 lines of code, but this is a working example.

Hope that helps. This is Java for Mobile devices, should give example. There is A* implementation in code and a lot of collision code you can ignore, but no time to edit it all down to the basics.

If you need the basics I could write a simpler example tomorrow that does just the scrolling.

Sprite Creator 3 VX & XP

WARNING: I edit my posts constantly.

As the other posters stated you want to move your character not your background. I'll use a different example to try and explain it.

So you are filming a movie which consists of a person walking down a dirt path with many trees. Do you move all the trees and have the person walk in place? Or do you move the camera along with the person as you walk further and further down?

In your game you should allow the player to move however they want and instead of changing the background make it so the part of the world you are seeing is the part around the character if that makes sense.
Thank you guys... so now I will try moving the player and not the background...
Actually what bloodisblue is trying to say that may not be coming off that well, is you want to keep the player at a fixed position on the screen(viewport) and instead of moving the entire map drawn completely every time you instead draw what only you can see relative to the players position based on the screen size and as the player moves you treat it much like a camera in a movie and you follow them and just like a movie, you cannot see what is outside the frame so therefore technically you can refer to it as it doesn't exist and you don't need to draw it.

For a computer you may have to draw a little ahead if using tiles to avoid the map edge jumping around.

Sprite Creator 3 VX & XP

WARNING: I edit my posts constantly.

This topic is closed to new replies.

Advertisement