Followers 0

# 2D scrolling game

## 16 posts in this topic

I am gonna make a 2D scrolling game, kinda like Mario. What is the best way to move the screen? Move the player and update the camera accordingly or move the entire screen and let the player stay still?

0

##### Share on other sites

I would go for a move the player and refresh camera position too, instead of moving the world. Otherwise:

• it will be difficult to setup "effects" such as smooth camera following and so on...
• it will be harder to accomplish scrolling since you'll have to update every object's position instead of just the player+camera
• if you use a physics engine, it will be even harder to keep sprites and internal physics state in sync

I can't really think of an upside to moving the world instead...

2

##### Share on other sites

As Willpowerd said, draw your objects at "absoluteObjectPosition - absoluteCameraPosition", and trim out objects not in view. absoluteCameraPosition = absolutePlayerPosition, most of the time. This is fairly simple and easy to implement, but works very well for most 2D situations.

Edited by Servant of the Lord
2

##### Share on other sites

I understand how to render objects relative to the camera. I'm not sure how I get the camera to follow the player, while keeping him centered.

Edited by Johnell
0

##### Share on other sites

I think you're going to need to explain what it is that you're not getting more precisely. Maybe if you start by explaining to us your process so far and then stop at the point where you're stuck and explain why you don't know what to do.

0

##### Share on other sites

I think you're going to need to explain what it is that you're not getting more precisely. Maybe if you start by explaining to us your process so far and then stop at the point where you're stuck and explain why you don't know what to do.

I wanna know how I can keep the player centered on the screen while moving him. I need the camera to "follow" the player so the camera's position is updated, but I dont know how I can accomplish this.

Edited by Johnell
0

##### Share on other sites

As state above

but you also need to center 0,0 to the middle of the screen in 2d so addhalf your screen dimension

camerapos = playerpos

for all objs

draw obj at objpos-camerapos+(screenDimension/2)

Edited by stannic
0

##### Share on other sites

So instead of moving the player I should move the camera and just center the player in the camera?

0

##### Share on other sites

You move the player normally then center the camera onto the player (camerapos = playerpos)

0

##### Share on other sites

I am currently centering the player this way:

player.draw(playerX - cameraX + (screen.width/2), playerY - cameraY + 240);


This do indeed work, although i'm confused as to why it does. Since playerX = cameraX I am just drawing it at screen.width/2. Say screen.width/2 is 400px. If cameraX is at 800 the player will still be drawn at 400px, yet still be centered in the screen. Why is that?

0

##### Share on other sites

Because your cameraX is the top-right (or bottom-right) of the camera, and not the center of the camera.

You're mixing two different formulas into a single location:

A) You're calculating the center of the camera from the camera's position and the screen size.

B) You're calculating the player's on-screen position from his absolute (or 'world') position and the (now centered) camera.

I suggest you keep your camera position as the center point of the camera, I just find it easier that way. Then your function would just look like:

player.draw(playerX - cameraX, playerY - cameraY);

Further, holding a 2D 'position' is a very very common game task. It adds extra visual code clutter and extra opportunities for mistakes if for every 'position' you have two variables (one for x and one for y).

Instead, a position is a prime candidate for its own struct or class.

A 'Point' class, that contains an 'x' and 'y', and has built-in addition and subtraction functions. Instead of every function taking an 'x' and a 'y', now you just take a 'point'.

This further reduces and simplifies your code to:

player.draw(playerPos - cameraPos);

It has the extra same code costs, but alot less visual clutter, and alot less potential for bugs, and alot easier maintenance, and alot easier readability.

Here's the interface for my point class: http://ideone.com/lH9X3B

Here's the source file: http://ideone.com/G5aAst

Many people (and different libraries) have their own custom point class. It's a very useful thing to have.

I suggest you make yourself a Point, a Size, and a Rect (which contains a Point and a Size).

0

##### Share on other sites

if playerpos = (400,0) and camerapos = (800,0) and the player is still centered on the screen, then something is wrong.

It should be drawing the player at (-400,0) relative to the center of the screen, which should be on the left side of the screen.

As to why it works, since playerpos = camerapos, playerpos-camerapos = (0,0). So then when you add half your screenDimension, which is the center of the screen, it will center the player onto the screen.

0

##### Share on other sites

Because your cameraX is the top-right (or bottom-right) of the camera, and not the center of the camera.

You're mixing two different formulas into a single location:

A) You're calculating the center of the camera from the camera's position and the screen size.

B) You're calculating the player's on-screen position from his absolute (or 'world') position and the (now centered) camera.

I suggest you keep your camera position as the center point of the camera, I just find it easier that way. Then your function would just look like:

player.draw(playerX - cameraX, playerY - cameraY);

Further, holding a 2D 'position' is a very very common game task. It adds extra visual code clutter and extra opportunities for mistakes if for every 'position' you have two variables (one for x and one for y).

Instead, a position is a prime candidate for its own struct or class.

A 'Point' class, that contains an 'x' and 'y', and has built-in addition and subtraction functions. Instead of every function taking an 'x' and a 'y', now you just take a 'point'.

This further reduces and simplifies your code to:

player.draw(playerPos - cameraPos);

It has the extra same code costs, but alot less visual clutter, and alot less potential for bugs, and alot easier maintenance, and alot easier readability.

Here's the interface for my point class: http://ideone.com/lH9X3B

Here's the source file: http://ideone.com/G5aAst

Many people (and different libraries) have their own custom point class. It's a very useful thing to have.

I suggest you make yourself a Point, a Size, and a Rect (which contains a Point and a Size).

"I suggest you keep your camera position as the center point of the camera." Hmm, not sure I follow. Isn't the camera view camera.x + camera.width and camera.y + camera.height? Also I'm not sure I entirely understand the difference between world position and screen position.

Say object A and B is at (50, 50)

If I draw them like this:

A.draw(50, 50);
B.draw(50 - camera.x, 50 - camera.y);


A will be at (50, 50) within the screen all the time. B will be drawn at (50, 50) world position. Is the coordinates within the screen always the same?

0

##### Share on other sites

Servant of the Lord it's not a bad way to explain it, but it's not that clear either. I'm not saying this because I could explain it better, but because i was trying to learn from your example but..I feel that I got a little closer to understanding it , but ...

About the screen/ camera space it says infinite in every direction, is this mistake or am I not undestanting something here. As screen space is definetly finite?

Edited by taten3n
0

##### Share on other sites

My forte` isn't explanations. Someone else could (and hopefully will) explain it in less words and clearer.

Just because the screen isn't infinite (let's say it's 800 x 600), the screen space is a Cartesian grid with x, y, axes that can go negative or positive.

Even if your screen is from (0,0) to (800, 600), the position (-100, -700) is outside of the screen's rectangle, but still in 'screen space' coordinates, because it's still relative to the same origin as the screen.

Everything in space is relative to some other position. There's no such thing as a 'position' except as a measurement relative to another point (the origin of your measurement).

A 'position' of an object is the distance between the object and the origin of the 'space' it is being measured in.

Where is the Earth located? You can give me the distance of the Earth from the Sun. That would make the Sun the origin, and you measuring the Earth's position in what we'll arbitrarily decide to call 'Sun-space'. Or you can give me the location of the Earth relative to the center of our Galaxy, making the center of the galaxy the origin.

Or you can give me the distance relative to the center of the universe, making the center of the universe the origin.

None of these are incorrect answers - they all refer to the same location (the location of the earth) but are in different coordinate spaces.

To convert between these spaces:

earthPosInGalaxySpace = earthPosInSolarSystemSpace + originOfSolarSystemInGalaxySpace

earthPosInUniverseSpace = earthPosInGalaxySpace + originOfGalaxyInUniverseSpace

Any 'space' is something that we make up. They only exist, because we can't measure anything (not position, not size) without measuring it relative to something else.

With 2D sprites, we measure 'size' at the pixel scale. We measure 'position' in a variety of ways, and we frequently convert between them as the need requires:

origin of the entire game world

origin of the area within the game world ("Green Forest")

origin of the subportion of the area that happens to be loaded around us

origin of the camera

These are just several possible coordinate spaces. At the very least, in almost every 2D game, you have 'world space' (what you keep your entity locations in) and 'camera space' (what is visible onscreen). Different people have different names for these - the names don't matter, the concept does.

If you say something is at position (0,0), you probably mean either relative to the game world, or relative to the camera - but it's important to understand which you want. Likely, all your API draw functions take screen-space coordinates. Likely, you'll want to keep all the objects in world-space coordinates. So knowing how to convert between spaces is important.

Thankfully, the formula is very simple:

originInNewSpace = (positionInCurrentSpace + originOfCurrentSpace)

In Johnell's case:

posInWorldSpace = (positionInCameraSpace + originOfCameraSpace)

posInCameraSpace = (positionInWorldSpace - originOfCameraSpace)

1

## Create an account

Register a new account