Jump to content
  • Advertisement
Sign in to follow this  
Avencherus

2.5D Movement Problem

This topic is 810 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm a newbie working on a 2.5D game, and I've run into a bit of a problem with the character movement when it comes to UP and DOWN controls that handle depth.

 

The objects in this game are in a 2D top down world space, and in rendering they are put into a walking area with a front to back perspective transformation.  Mainly I'd like to scale them appropriately as they walk towards or further from the screen/camera.  This is then all put over top a 2D background.  The issue is that the strictly up and down movement in the world coordinates is going to render showing them following along the imaginary perspective lines.  Meaning that at any point off the center of the screen, UP/DOWN becomes a diagonal movement that gets wider the further off center the player is.  This makes for some really wonky controls that are hard to navigate.

 

I've attached an image depicting the problem, and what I would prefer to achieve.

 

[attachment=32737:2.5D problem.png]

 

I'd like the movement to actually just go up and down, but maintain their world position accurately for collision detection.

 

There were a few thoughts that I had, and I was wondering if someone with more experience could tell me if I'm headed in the right direction.

 

My first idea, a not very ideal one, was to split the physics and rendering on the X axis.  The rendering would not scale the X into perspective, but the scaling amount would be captured in the physics and scale movement speeds and collision width.  Creating a strange distorted physics world, but rendering the way I'd like.  I've done this one part way and so far seems to work, but I worry about collision detection.

 

Now I'm wondering that maybe it's sensible to apply some sort of transformation to their movement force vectors, so they will orient to a path in world space that will create the desired results in rendering.

 

Last was that perhaps there is some other method of projection I'm not yet aware of that will get me the sprite scaling effects without the movement side effect.

Share this post


Link to post
Share on other sites
Advertisement

I'm a bit confused by what you mean for "2d top down world space" and then rendering "front to back transformation" and your usage of up and down. That being said -

 

Generally you don't store any type of perspective transformations directly in your object's world positions. Rather, when you render from some point (generally this point is called the camera) you use a matrix to represent the camera's perspective transformation (although many represent the projection method separate from the camera) and multiply each object's verts by a world position matrix created from the object's world position and then this transform to give the correct scaling for how far away they are from the camera.

 

Everything else in your game will use the world position - the scaled verts are only used to render - usually passed in to a shader in the form of a matrix. For 2d sprites - you would be transforming the verts of the quad that the sprite is drawn on. Something like (glsl):

layout (location = 0) in vec3 vert;
uniform mat4 proj_cam_tform;
uniform mat4 world_pos_tform;

int main()
{
    gl_Position = proj_cam_tform * world_pos_tform * vec4(vert, 1.0);
}

As for movement - I would argue that if you are rendering in perspective, your character's movement should follow those parellel lines. In fact - if everything is rendered in perspective and your characters don't move along the perspective lines, the player will think their character is moving diagonally instead of straight forward or back.

 

last edit: I would store your world position in 3d coords instead of 2d. If you were trying to say earlier that you want a character to be able to jump and have that follow up/down with the screen, then using 3d coords and the method I show above will work. The easiest thing to do would be to store your horizontal plane coords in x and z and your vertical coord in y. Your z will then act as the object's "depth".

Edited by EarthBanana

Share this post


Link to post
Share on other sites

I'm a bit confused by what you mean for "2d top down world space" and then rendering "front to back transformation" and your usage of up and down. That being said -

 

Generally you don't store any type of perspective transformations directly in your object's world positions. Rather, when you render from some point (generally this point is called the camera) you use a matrix to represent the camera's perspective transformation (although many represent the projection method separate from the camera) and multiply each object's verts by a world position matrix created from the object's world position and then this transform to give the correct scaling for how far away they are from the camera.

 

Everything else in your game will use the world position - the scaled verts are only used to render - usually passed in to a shader in the form of a matrix. For 2d sprites - you would be transforming the verts of the quad that the sprite is drawn on. Something like (glsl):

layout (location = 0) in vec3 vert;
uniform mat4 proj_cam_tform;
uniform mat4 world_pos_tform;

int main()
{
    gl_Position = proj_cam_tform * world_pos_tform * vec4(vert, 1.0);
}

As for movement - I would argue that if you are rendering in perspective, your character's movement should follow those parellel lines. In fact - if everything is rendered in perspective and your characters don't move along the perspective lines, the player will think their character is moving diagonally instead of straight forward or back.

 

last edit: I would store your world position in 3d coords instead of 2d. If you were trying to say earlier that you want a character to be able to jump and have that follow up/down with the screen, then using 3d coords and the method I show above will work. The easiest thing to do would be to store your horizontal plane coords in x and z and your vertical coord in y. Your z will then act as the object's "depth".

 

There won't be any jumping.  I would think of it like the movement of some of the old arcade street fighting games.  Like Double Dragon or something such as that.

 

To clarify the 2D to 2.5D rendering.  This is a screenshot of an experiment I was doing with it.  On the left is the actual world coordinates of shapes, and on the right is how they would be rendered with the perspective transformations.

[attachment=32738:mapping.png]

 

I'm familiar with transformation matrices.  This will mostly be a 2D game, all the art is flat.  I just am trying to achieve a walkable area that will scale the sizes based on the Y position.  I end up with some incoherent controls, since the camera is not always pointed at the player, like it would be in many 3D games.

 

I've made a prototype with sprites being positioned and scaled with this transformation you see on the right side, and it really does not play well at the edges.  It feels as if your controls are being continuously skewed as you head left and right, since everything looks like a classical 2D game.  When you wish to move directly up and press UP, and you start running diagonally in the direction of center screen, it doesn't feel right.  Even if these perspective lines get visually represented.  It gets especially unbearable in the back corners.

Share this post


Link to post
Share on other sites

Not much experience here, but perhaps you want to walk on the line from the player position to the current character position for up/down? (Or perpendicular to that, for left/right.)

It seems a bit weird to me, but the best test is to try it.

Share this post


Link to post
Share on other sites

Have you thought about doing an orthographic camera instead?  You lose the visual look, but it should fix the issues.

Share this post


Link to post
Share on other sites

I believe double dragon is done with orthographic - and most of those type of games - if you do perspective rendering i still think you should only persepctive tform for rendering meaning moving forward and back would go along the projection lines - otherwise it will seem like your moving diagonally

That being said - you could simply render your characters with an orthogonal projection and everything else with perspective - but i think its going to have a strange feel.

In any case i wouldnt involve the projection for EDIT*anything but* rendering in your world positions

Edited by EarthBanana

Share this post


Link to post
Share on other sites

The solution is very simple: divide the rendered X coordinate of the object by it's Z (or depth) coordinate, and offset to the center of the screen.

 

You may have to add a scaling and add a bias on there but it will work great. That's how 3D perspective is achieved to begin with.

Share this post


Link to post
Share on other sites

Have you thought about doing an orthographic camera instead?  You lose the visual look, but it should fix the issues.

 

Are there any good resources you know of on how it's implemented?  I was thinking of looking into orthographic projection, but I wasn't sure if it was the right thing.  It seemed like a 2D slice that follows the axis alignments.

Share this post


Link to post
Share on other sites

I believe double dragon is done with orthographic - and most of those type of games - if you do perspective rendering i still think you should only persepctive tform for rendering meaning moving forward and back would go along the projection lines - otherwise it will seem like your moving diagonally

That being said - you could simply render your characters with an orthogonal projection and everything else with perspective - but i think its going to have a strange feel.

In any case i wouldnt involve the projection for EDIT*anything but* rendering in your world positions

 

Thanks for the replies.

 

The only thing being rendered with this perspective transform are the objects in the front plane of the world.  Everything else is simply layers of 2D art that will parallax.

 

I just need a transform that sensibly scales the moving objects in the foreground to give the appearance that they are walking away from or toward the screen.  But also maintain their positions in a simple 2D coordinate system so I can use very simple and cheap collision tests.  So they need to be tied together with some kind of transformation.  Perspective does not seem to be it, unless I hack it.

 

I will look more into orthographic, if you know of any good info on it, I'd really appreciate it.  X)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!