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

Started by
2 comments, last by TacticalWolf 7 years ago

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.

Advertisement

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

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.
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

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?

This topic is closed to new replies.

Advertisement