Implementing better code design for a camera feature in a 2D game

Started by
26 comments, last by Nicholas Kong 10 years, 4 months ago

I'll try to disentangle this a bit for you.

- Suppose you have the microwave. You would typically have a file where the model is saved. There the origin--in object space--could be placed at the lower left front point for example (or the middle of the lower surface of its bounding box or just the weighted average of all points of it or whatever you like).

- Now you place the microwave onto a table, the table is inside the kitchen, the kitchen inside the house, the house someplace in the world. That would give a whole hierarchy of matrices to apply to convert the points of the microwave into world space (thats what people who make a scenegraph do). But you would more likely want to simplify this by combining all that into a single model matrix per object, that the gpu can use for the transform, or directly placing the microwave and all other objects at some place--in world space--with the origin in the middle or one corner of your map or whereever you like to.

- Now you want to watch the world and therefore you place a camera somewhere in world space. From that you calculate the view matrix that transforms world space into--view space--, where the camera is always at the origin.

- For further simplification the view matrix and the model matrix get often multiplied together on cpu once to get the modelview matrix and only this is given to the gpu.

- Then you generate the projection matrix that squeezes the world into a tiny cube and can give the illusion of further away objects being smaller by squeezing them more.

- Later you see one slice of that cube stretched onto the available screen space (thats what the viewport settings are for).

Advertisement

The camera might start at (0,0), but it shouldn't stay at (0,0).

If a tree is at (100,50) in the world, and the player is at (75,75) in the world, and you want the player in the center of the screen, then you do this:


//Snap the camera relative to the player.
cameraPos = playerPos - (cameraSize/2)

//Draw the player relative to the camera.
DrawPlayerAt(playerPos - cameraPos)

//Draw the tree relative to the camera.
DrawTreeAt(treePos - cameraPos)

//Draw everything relative to the camera.
for every object
{
    //But keep their 'positions' as relative to the origin of the world.
    DrawObjectAt(objectPos - cameraPos)
}
...but after drawing your objects and backgrounds and everything, then you reset the camera to (0,0) to draw the GUI.

So technically your camera can start at (-50,0) during its creation in the game if there is a good reason to? Once you say it should not stay at (0,0) does that mean the camera x and y will change?

Is cameraSize the width of the camera?

Is cameraPos the x and y coordinate of the camera that represents the upper left corner of the camera?

I'm still confused about the foreach loop, is this algorithm for objects that is not the player and the tree?

Wouldn't the GUI be drawn during the entire game? I feel the camera reset might cause the object position to be in their original position(original coordinates during the object's creation). I am not quite sure how that would look in the game.

Thanks for the psuedocode example. The camera feature is definitely more involved than I originally thought.

The camera moves in world space, of course its coordinates will change!

Everything drawn is relative to the camera. Try not to draw things that can't be seen by the camera ;)

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley


...but after drawing your objects and backgrounds and everything, then you reset the camera to (0,0) to draw the GUI.


Wouldn't the GUI be drawn during the entire game? I feel the camera reset might cause the object position to be in their original position(original coordinates during the object's creation). I am not quite sure how that would look in the game.

There's no need to reset the camera if you draw the GUI to the coordinates of the screen itself rather than relative to the camera.


The camera feature is definitely more involved than I originally thought.

And it will become even more involved once you start introducing features such as bounds checking, forward positioning based on character direction/speed, and even camera physics. But those aren't essential features, so don't worry about them until you really want to polish your game.

So technically your camera can start at (-50,0) during its creation in the game if there is a good reason to? Once you say it should not stay at (0,0) does that mean the camera x and y will change?

Yes definitely. Your "camera" should move through the world, to display different parts of the world.

Is cameraSize the width of the camera?

Yep, the width and height.

Is cameraPos the x and y coordinate of the camera that represents the upper left corner of the camera?

Usually, yes. Sometimes (depending on how you write your code or how your API works), it might be the center of the camera.

I'm still confused about the foreach loop, is this algorithm for objects that is not the player and the tree?

It's for everything, including the tree and including the player. You don't have to put them in a loop if you don't want to, my point was, for every game object, whenever you draw them, draw them relative to the camera but store their positions in world-space.

Wouldn't the GUI be drawn during the entire game? I feel the camera reset might cause the object position to be in their original position(original coordinates during the object's creation). I am not quite sure how that would look in the game.

Don't change your camera's stored position but just draw the GUI objects relative to the screen, not relative to the camera in the world.

A tree in the world located at (20,20) needs to be drawn at ((20,20) - cameraPosition).
A GUI object on the screen (screenspace) located at (20,20) needs to always be drawn at (20,20) regardless of where in the world the player is. So don't subtract the camera position from GUI objects, only from objects "in the world".


It's for everything, including the tree and including the player. You don't have to put them in a loop if you don't want to, my point was, for every game object, whenever you draw them, draw them relative to the camera but store their positions in world-space.

Am I suppose to store all the positions of the objects in world-space even though they are not drawn on-screen when the level boots up but at some point will need to be drawn?

Am I suppose to store all the positions of the objects in world-space even though they are not drawn on-screen when the level boots up but at some point will need to be drawn?


Mostly, yes. Whenever your game world is "loaded" (however that might happen in your code), from that point on, all objects "in the world" should have world-space positions. Regardless of whether they are visible or not.

GUI objects have screen-space positions.

Any object "in the world" that isn't created yet or is loaded at a later time, when it's time to load or create it, then until it is destroyed it should have a position in the world. Objects that are created later as the player moves around: As soon as they are "created" they should be set to their position in the world.

Basically, if an instance exists of a class that is a world object, it should probably have a valid position. That valid position should be in world-space, not screen-space, since the object is in the world.
This isn't an absolute rule, but it's a good guideline that any created and 'active' object should have a valid state.

Am I suppose to store all the positions of the objects in world-space even though they are not drawn on-screen when the level boots up but at some point will need to be drawn?


Mostly, yes. Whenever your game world is "loaded" (however that might happen in your code), from that point on, all objects "in the world" should have world-space positions. Regardless of whether they are visible or not.

GUI objects have screen-space positions.

Any object "in the world" that isn't created yet or is loaded at a later time, when it's time to load or create it, then until it is destroyed it should have a position in the world. Objects that are created later as the player moves around: As soon as they are "created" they should be set to their position in the world.

Basically, if an instance exists of a class that is a world object, it should probably have a valid position. That valid position should be in world-space, not screen-space, since the object is in the world.
This isn't an absolute rule, but it's a good guideline that any created and 'active' object should have a valid state.

Thanks.

This topic is closed to new replies.

Advertisement