Best way of defining game/screen coordinates?

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
ammianus
Very interested
Posts: 124
Joined: Sun Jan 29, 2012 2:10 pm
Location: North America
Contact:

Best way of defining game/screen coordinates?

Post by ammianus »

So this more of a general question, I am developing for 32X but think it could be asked here as well. Please move if needed.
Disclaimer: I've never made a side-scroller game before.

I am trying to develop some logic in my game, which is a 2d side-scroller. I am having trouble because I have two ways to define "positions" in the game level/world/map. One is what I call "screen" coordinates, which is how I can actually draw and place things on the screen as my character walks around. That is mapped to the actual pixels on the screen or in the Framebuffer. This makes things simple if the screen never moves.

But in my game, I want to have to have the character walk around the level, as you might expect, the player should stay somewhere on the screen and other things should appear on the screen when you get close to them, and then move relative to the character's motion when they are on screen. To define objects and enemies on my level (as well as the boundaries of where the character can walk) I have a larger coordinate system that I call "map or tile coordinates". Basically this is mapped to the 16 x 16 px tiles that make up the background of this level.

Hopefully this image illustrates my point
Image

So I am finding it cumbersome to work in both systems simultaneously, and I thought maybe I am just doing something more difficult than it should be. I.e. do I define the game "physics" in terms of the pixel coords? and then recalculate the "world coordinate" from where they end up. When things are way off screen, how best to have them move? Or alternatively, make everything in terms of world coordinates, but since characters don't move and interact in 16 pixel increments, I somehow need to adjust things by offsets of pixels while they are on screen?

Maybe I scrap the "world coordinates" and just have everything be in terms of pixels? And then keep track of where the screen position is, within that world. The "world coordinates" based on tiles, would make it easier for me to define my levels with all objects being made up of 16 x 16 squares. But I could live without it I suppose.

What do you guys do? Since I work in 32X it's free in terms of how I want to do it, I don't know if the MD achieves this in a specific way.
slobu
Very interested
Posts: 85
Joined: Tue Apr 03, 2012 6:02 pm

Post by slobu »

I'm struggling with my first scrolling engine for the Genesis. The way I have it now is to basically not use the actual x/y coordinates for the player sprite since they do not move from their starting position on screen. I'm pretty lazy in that I just design the map itself so the player does not reach the screen/level edges.

I can't think of an easier system than viewport x/y and world x/y, really.

It may also depend on whether you want to keep track of objects off screen or just "Activate" them when they enter the viewport.
djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Post by djcouchycouch »

Maybe this will help:

On Goplanes, every game object is in world space.

There's a "camera" position. You can also see this as the current scrolling position of the entire level/map. It's also in world space. The camera can move with the player. The camera position is generally:

player_position.x - half_screen_width
player_position.y - half_screen_height

To place an object on the screen, I go: object_position - camera_position. If the position is within screen coordinates, it's visible. Then I make note of it so I can draw its sprite later.

In practice on Goplanes, there's some extra complexity because the x scrolling on genesis is backwards and my world coordinate system has 4x the points per pixel but that's the basic version of it.
ammianus
Very interested
Posts: 124
Joined: Sun Jan 29, 2012 2:10 pm
Location: North America
Contact:

Post by ammianus »

Thanks for the ideas, it's along the lines of what I was trying. Regarding, the camera window. What about the backgrounds or the level geometry? (again this may be a different animal on the MD which has the background planes that 32X doesn't have (without using the MD).

What I am doing is similarly to any other object, for any background tile calculating the relative pixel x,y each time.
djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Post by djcouchycouch »

I work on MD, so all the backgrounds are planes. So setting the correct background plane position is simply just the camera position but backwards. If the camera is 100 pixels towards the right, then scroll the background 100 pixels towards the left to simulate the effect.

Collisions, I transform object positions from world coordiates to "plane/tile" coordinates. Basically take the x and of the world position and divide by 8 pixels, the size of a tile. That'll give you the tile position on the level. From tile position you get the tile and then do your collision code you need to.

Even on the 32x, I think you still have access to the MD's background planes. You get them for free so I don't see why they couldn't be used.
ammianus
Very interested
Posts: 124
Joined: Sun Jan 29, 2012 2:10 pm
Location: North America
Contact:

Post by ammianus »

Just an update I am taking this "camera window" approach and it seems to be working really well.

I added some functions to simplify the behavior of drawing objects on the screen and converting world coordinates to pixels based on camera position

Code: Select all

/*
* Defines where the screen is positioned
*/
typedef struct {
 int16 left_x;
 int16 right_x;
 int16 top_y;
 int16 bottom_y;
 int16 screenPos;
} CAM_CameraView;

/*
* Sets the camera based on the position of the character
*/
int CAM_updateCamera(CAM_CameraView *camera, GameCharacter *player, const int worldWidth);

/*
* Set the Pixel X,Y in the pointers passed in as last two arguments at these coordinates based on relative location to the camera
*/
int CAM_calculateOnScreenPixels(CAM_CameraView *camera, const int16 world_x, const int16 world_y, const int16 xOffSet, int16 *newX,int16 *newY);

/*
* Set the Pixel X,Y on the GameCharacter based on relative location to the camera
*/
int CAM_calculateOnScreenPixelsCharacter(CAM_CameraView *camera, GameCharacter *player);


/*
* Test if the object at world_x, world_y is considered in the Camera's current view or not
* @return 1 for true, 0 for false
*/
int CAM_isInCameraView(const CAM_CameraView *camera, const int16 world_x, const int16 world_y, const int16 width);
It actually simplifies a lot of the AI and "physics" logic as I am free to do those based on world coordinates, while I let the camera and related functions take care of drawing them in the right place on the screen.
djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Post by djcouchycouch »

great!
Post Reply