Sign in to follow this  

OpenGL: How to click to move on a 2D tile map

Recommended Posts

Hi, I'm trying to create a 2D tile based game, and I'm having trouble understanding how to create the ability to move a "player" around my rendered tile map. Currently, I am able to get the 2D coordinates of where my cursor is when I click, so where I have clicked in the game window. However, I don't understand how to turn this coordinate into a "tile location" to then use to move a sprite/character to that location. What I think I want is the tile's "world" coordinate, but I'm not entirely sure.

Any and all help would be appreciated. I'm looking for pointers on how I can do this.

Share this post


Link to post
Share on other sites
Posted (edited)

This isn't really related to openGL, as it's more a general 2D problem.  Basically as your using tiles, you most likely are using a 2D grid.  each tile is x pixels wide by y pixels tall.  so to know what tile the mouse is over, you'd do:  

xTile = floor(MousexPos/TileWidth); //we use floor incase your using a language which only uses floating point numbers, floor basically removes the decimal from a number, so for example if we have 5.5, and floor that, we'd get 5.
yTile = floor(MouseyPos/TileHeight);  

if you want to then turn that into a world coordinate, you'd do:

xWorldPos = xTile*TileWidth;
yWorldPos = yTile*TileHeight;

if you want to move a player to that location(rater than teleport them there), then you need to generate a list of tiles to move through from your starting tile, to your target tile.

a simple algorithm for this would be:

TileList = []; //create an empty array of tiles.
StartxTile = PlayerxTile;
StartyTile = PlayeryTile;
DestxTile = xTile; //using the above x/y tile's assumed for our destination.
DestyTile = yTile;
CurrxTile = StartxTile;
CurryTile = StartyTile;
while(CurrxTile !=DestxTile){
    if(CurrxTile >DestxTile) CurrxTile --; //we want to move to the left.
    else CurrxTile++; //we want to move to the right.
    TileList.push(CurrxTile, CurryTile); //add this tile to our list of tiles to transverse.
}
while(CurryTile!=DestyTile){
    if(CurryTile>DestyTile) CurryTile--; //we want to move down.
    else CurryTile++; //we want to move up.
    TileList.push(CurrxTile, CurryTile); //add this tile to our list of tiles to transverse.
}
//Now we can iterate over the TileList to know what tiles we should walk through.

This is a very crude an inefficient algorithm(does not take into account walking diagonally), but should get you started on following a path.  once you get this down, you can try implementing more advanced techniques for pathing, such as A*.

 

Good luck :)

Edited by slicer4ever

Share this post


Link to post
Share on other sites
Posted (edited)
slicer4ever has already provided the core anwer to your problem:
- Convert the world mouse coordinates into tile coordinates and then back into world coordinates
 
But there a caveats you need to look for:
 
- The mouse coordinates are not in world (opengl) coordinates: Use gluUnProject() to bring it back into world space if required
- When the tilemap origin is top-left the mouse world position must be converted into the space of the tilemap
- It gets more complicated when you introduce panning and scale, but still can be solved in a simple way
 
I already have built dozens of tilemap editors and game prototypes using tilemaps, so if you have questions or want to look at sources - just ask. Also i have posted a ton of javascript sources free-to-use for everyone - which includes several tilemap techniques for moving a player around.

See:
http://root.xenorate.com/final/jsstuff/platformer/demos/tilecollisions.html
or
http://root.xenorate.com/final/jsstuff/platformer/demos/realcollisions.html
or
http://root.xenorate.com/final/jsstuff/finaljs/games/leverman/leverman.html Edited by Finalspace

Share this post


Link to post
Share on other sites

Thanks a ton for both of your help! I'm looking at your examples now Finalspace, and I will probably implement something like what you suggested Slicer. Seriously was a huge help. I'm using modern OpenGL though, so the equivalent of that gluUnProject() is messing with the modelview and projection matrices right?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this