[SOLVED] Troubles Implementing Map Scrolling

Hey,

I’m currently attempting to add in map scrolling to a basic platformer I’m working on. I worked out a good idea of how it works, but every time I try to implement map scrolling it never works properly.

The player is 32 pixels wide and 64 pixels tall.

///////// WIP - Screen scrolling code.
		double playerX = ((Player)ENTITIES.get(0)).getX();
		double halfScreenWidth = (SCREEN_DIMENSIONS.getWidth()/2);

		if(playerX > halfScreenWidth) {
			double distanceFromHalfScreenWidth = playerX - halfScreenWidth;
			offsetX -= distanceFromHalfScreenWidth;
			((Player)ENTITIES.get(0)).setX(halfScreenWidth - distanceFromHalfScreenWidth); // Rest works, no idea what to set X to atm.
		} else {
			offsetOldX = offsetX;
		}
		/////// End of WIP

This is what I’m currently using. It does scroll the map to the left, but it does this:

I’ve modified the code above in many ways, but only the current code has resulted in anything close to working properly. The screen seems to scroll too far and the player is often thrown inside of a tile where it’s not allowed to move. If anyone has an idea of what I may have messed up on in the code that would help a lot.

I hope this might help you…

If a player is thrown into a tile, because of how you’re rendering things, you must be doing something wrong.

It has nothing to do with the rendering.

You just said in your post that player gets thrown into tiles and cannot move. I assume you said it, because that didn’t happen before you implemented map scrolling. That means your map scroll affects how player moves.

Yes, and that has nothing to do with rendering. The problem is in the map scrolling code in the OP which is part of the updating and not the rendering. If you look at the code it simply moves the player backwards, or at least it should, so that it lines up to it’s position from before the scroll.

Could you explain why you would even want to alter player coordinates to determine map scroll? Shouldn’t map scroll be just raw player coordinates, which would mean that map is centered around the player?

Before setting map scroll coordinates you could check if players position is smaller than half of the screen of larger than half of the screen. If it is, don’t change map scroll. I mean, why would you change player coordinates to determine map scroll?

I don’t.

Whenever the player’s x position is greater than half of the screen it does (playerX - halfScreenWidth) to find the difference. Then subtracts that from the xOffset. Next, the player’s position is set back to halfScreenWidth so that it lines up with where it was before the map was moved back by the xOffset.

Why do you “set back” player position, if you didn’t change it in the first place?

Because it just updates the player’s position after figuring out how much to scroll the map so that the player’s position won’t change on the map when it scrolls to show the next bit of the map. The user controls the player’s movement.

It appears that you are defining the players position based on its position in the screen. Everything will be easier to keep track of if you define everything in world or map coordinates instead of in screen coordinates.

Define the player with a position in the world.
Define a camera or screen with a position in the world.

Every frame before rendering set the cameras position to track the players position.

It has been a while… :wink:

Anyway, I see you are having problems with scrolling. I wrote a small mario game that has basic scrolling, collision detection, and so on. However, it is in a very rough coding style. However, if you cut and paste it in your IDE, it should work…

http://pastebin.java-gaming.org/43823368d83

For scrolling, the best and simplest method is to separate the camera from the player movements. If you look in my code, you will see that a have a variable called “scrollx”. This is solely used to control the camera. The player movements and the world are stationary and the camera is just an “offset”.


g.setColor(Color.BLACK);
g.fillRect(px[i]+scrollx, py[i], psx[i], psy[i]);
//See how scrollx^^ is by itself, that is the only call back to the camera in this code
//The rest of the variables have to do with the object movement...

I hope that you can pick through the mess and see the code for how it is, but the basic idea is that I graphically pin everything to the camera and just move the camera. All camera movements are calculated separately from everything else in order to give the camera freedom of movement around the world.

I hope it helps, but the code is rather a mess. I’ll see if I can write a better example, but I’ll only do so upon request… :point:

I like to keep a cameraX and cameraY variable.

At the beginning of each game loop I set:
cameraX = playerX - halfScreenWidth;
cameraY = playerY - halfScreenHeight;

Now in pseudo code, any time any object/tile/particle/etc is drawn to the screen:
drawSprite(spriteImage, spriteX - cameraX, spriteY - cameraY);

This also allows the camera to be moved around to show other parts of the level, or to give the player a better view of the direction they are facing, etc, just by altering the camera position variables.

=O

I was just messing around with the code while writing a reply about it almost working and it worked. I just combined the ideas in ctomni’s code and what Liquid said in his comment and now it works perfectly!