• FEATURED
• FEATURED
• FEATURED
• FEATURED
• FEATURED

View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# 2D scrolling game

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

16 replies to this topic

### #1Johnell  Members

Posted 10 March 2013 - 06:23 PM

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?

### #2willpowered  Members

Posted 10 March 2013 - 07:37 PM

Move the player, and then move the camera to the same position. Then when you draw, draw everything at an offset based on the camera's position.

### #3mdias  Members

Posted 10 March 2013 - 10:12 PM

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...

### #4Servant of the Lord  Members

Posted 10 March 2013 - 11:11 PM

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, 10 March 2013 - 11:12 PM.

It's perfectly fine to abbreviate my username to 'Servant' or 'SotL' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames -

### #5Johnell  Members

Posted 14 March 2013 - 06:59 PM

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, 14 March 2013 - 08:42 PM.

### #6Khatharr  Members

Posted 14 March 2013 - 09:10 PM

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.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

### #7Johnell  Members

Posted 15 March 2013 - 05:43 AM

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, 15 March 2013 - 05:44 AM.

### #8stannic  Members

Posted 15 March 2013 - 08:54 AM

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, 15 March 2013 - 08:59 AM.

### #9Johnell  Members

Posted 15 March 2013 - 09:51 AM

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

### #10stannic  Members

Posted 15 March 2013 - 11:42 AM

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

### #11Johnell  Members

Posted 15 March 2013 - 07:30 PM

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?

### #12Servant of the Lord  Members

Posted 15 March 2013 - 08:18 PM

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).

It's perfectly fine to abbreviate my username to 'Servant' or 'SotL' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames -

### #13stannic  Members

Posted 15 March 2013 - 09:40 PM

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.

### #14Johnell  Members

Posted 16 March 2013 - 05:30 AM

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?

### #15Servant of the Lord  Members

Posted 16 March 2013 - 11:36 AM

"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?

APIs usually have their drawing code takes positions relative to the screen (well, relative to the screen's 'view', which is then stretched to fit the screen). So A.draw(50,50) always means (50,50) within the screen (i.e. in 'screen space'). A.draw(-50,-50) will always draw (-50, -50) outside of the screen (still in 'screen space' coordinates).

Positions in space are always relative to some known point. Putting a position in 'screen space' is making it relative to the screen/camera/view.

'world space' or 'world positions' or 'absolute positions' (Whatever you want to call it, the terms aren't standardized) mean that the positions are relative to the center of your 'world', whatever you define the 'world' as. (It could be the current level you have loaded, or the entire game world, or only the current fraction of the area that's actually loaded around the player).

Your camera position is always in 'world space' coordinates.
So if your camera is at (100, 100), then it really means 'world space origin' + (100,100), but 'world space origin' is (0,0) and so not mentioned.

When drawing, you want to convert to screen space. Screen space's origin is cameraPos.

Since you should keep your entities in world space (since the entities are within the world, unlike your GUI):

EntityAPos = (500, 500) //This is actually (0,0) + (500,500), since the entity's position is in world space.
CameraPos = (400, 400) //This is actually (0,0) + (400, 400), since the camera's position is in world space.

positionOfEntityAInScreenSpace = EntityAPos - CameraPos


This is now (100, 100)... it's but converted to screen space, because 'cameraPos' is the origin of screenspace.
Since your drawing functions take screenspace coordinates, this is what you pass to those functions.

Some APIs, like SFML, handle these conversions for you. Others don't.

Have you ever generated a random number using (rand() % 50) + 25 ?
It generates a number from 25 to 74.
First you generate a number from 0 to 49. This is in the 'domain' (or as I've been calling it above, the 'space') of 0 - 49.
Then, you shift it over to a new 'domain', making '25' be the origin instead of 0. So the new domain is from '25 to 74'.
The range (50) stayed the same, the origin just shifted. We shifted it from one "space" or "domain" to a new "space" or "domain".

When we convert the entity's position from world-space to screen-space, everything stays the same, but the origin shifts to be relative to the camera, instead of relative to the world.

If you aren't understanding, this isn't because it's a difficult subject, it's simply because I'm doing a butchered job of explaining it!

Maybe graphs will help me illustrate:

It's perfectly fine to abbreviate my username to 'Servant' or 'SotL' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames -

### #16taten3n  Members

Posted 16 March 2013 - 04:24 PM

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, 16 March 2013 - 04:37 PM.

### #17Servant of the Lord  Members

Posted 16 March 2013 - 08:26 PM

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)

It's perfectly fine to abbreviate my username to 'Servant' or 'SotL' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames -

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.