How to change a tile in a tile map like in level editor (SDL)

I'm making a 2D rpg game with a level editor so I dont need to hard code every level. I have created a tile map that I load into the program from a text file, and it works perfect. The thing is that I want the possibility to change the tiles to an another type of tiles while I'm running the program like a level editor (See video link below).

https://www.youtube.com/watch?v=fEGibPzOZoY

This is what I try to do
1
2
3
4
5
6
7
8
9
10
11
for(int i = 0; i < TOTAL_TILES; i++)
    {
        ///check if the mouse is over the tile
        if(( mouseX > tileRectDst.x ) &&
           ( mouseX < tileRectDst.x + tileRectDst.w ) &&
           ( mouseY > tileRectDst.y ) &&
           ( mouseY < tileRectDst.y + tileRectDst.h ))
           {
            ///I dont know how to find the specific tile that the mouse is over.                  
           }
    }


Here is how I draw the tiles:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 ///Draw Tiles
    for(int y = 0; y < TILES_Y; ++y)
    {
        for(int x = 0; x < TILES_X; ++x)
        {
        Vector2<int> position;

        position.x = (x*tile::TILESIZE_X)-camera.x;
        position.y = (y*tile::TILESIZE_Y)-camera.y;
        
        ///Find Tile Type 
        switch(tileMap[y][x])
        {
           case 1:
           MAP[x][y].render(position.x, position.y,1);
           break;

           case 2:
           MAP[x][y].render(position.x, position.y,2);
           break;

           case 3:
           MAP[x][y].render(position.x, position.y,3);
           break;
        }
        }
    }


My problem is basically that I dont know how to find the specific tile that the mouse is over.
Last edited on
or you calculate back from the mouse position
1
2
3
4
5
6
7
8
Vector2<int> position;
position.x = tileRectDst.x / tile::TILESIZE_X; // i just think tileRectDst is the mouse position
position.y = tileRectDst.y / tile::TILESIZE_Y;

// now depending on how you store the data:
MAP[position.x][position.y].setTile(??); // when mapdata is stored in MAP

tileMap[position.y][position.x] = ???; // When mapdata is stored in tileMap 



or if that is to complicated you loop through them just like when you draw them to know it
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    for(int y = 0; y < TILES_Y; ++y)
    {
        for(int x = 0; x < TILES_X; ++x)
        {
        Vector2<int> position;
        position.x = (x*tile::TILESIZE_X)-camera.x;
        position.y = (y*tile::TILESIZE_Y)-camera.y;
        
        ///check if the mouse is over the tile
        if(( mouseX > position.x) &&
           ( mouseX < position.x + tile::TILESIZE_X ) &&
           ( mouseY > position.y) &&
           ( mouseY < position.y + tile::TILESIZE_Y)
           {

// now depending on how you store the data:
MAP[position.x][position.y].setTile(??); // when mapdata is stored in MAP

tileMap[position.y][position.x] = ???; // When mapdata is stored in tileMap
                                                          // this seems to be the case here
             
           }
        }
    }


Also: here are some lines of code to much
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
/// this
        switch(tileMap[y][x])
        {
           case 1:
           MAP[x][y].render(position.x, position.y,1);
           break;

           case 2:
           MAP[x][y].render(position.x, position.y,2);
           break;

           case 3:
           MAP[x][y].render(position.x, position.y,3);
           break;
        }

/// could be replaced with
MAP[x][y].render(position.x, position.y, tileMap[y][x]);



Also: you have
1
2
tileMap[y][x];
MAP[x][y];


you will want to make both in the same way:
1
2
tileMap[x][y]; 
MAP[x][y];

or
1
2
tileMap[y][x]; 
MAP[y][x];


Also: I like your code, it's well structured and easy to read :b
Last edited on
@Gamer2015

Thanks, it works alomost perfect. It's only one more problem I have, and that is when the tile map move. I have made a scrolling tile map, and I could only change the tiles when the tile map is standing still and not started to move. That's because I draw the new tiles realative to the window since I use the mouseX and mouseY from the SDL_getmousestate(). Do you know how to draw the new tiles relative to the tile map instead of relative to the window?

Here is how I set the new tiles:
1
2
3
4
5
Vector2<int> position;
position.x = mouseX / tile::TILESIZE_X;
position.y = mouseY / tile::TILESIZE_Y;

tileMap[position.x][position.y] = WALL;


Also: here are some lines of code to much

Thanks, that make my program a lot more structured and easier to work with :-)
If you use an anchor point to align the map/world with the screen 0,0 then all you need is to add the anchor to the mouse coords.
oh sure, you also have to keep in mind that there is scrolling...
ahcfan allready explained it but I'll just be more detailed

The camera position gives you an offset of where you are, calculated from 0 you are at position camera, then you add the mouse Vector
brings back memories from Vector Calculation in school.

in vector additions:
0 + camera = top left of the view;
camera + mouse = the tile;


1
2
3
4
5
Vector2<int> position;
position.x = (mouseX + camera.x) / tile::TILESIZE_X;
position.y = (mouseY + camera.y) / tile::TILESIZE_Y;

tileMap[position.x][position.y] = WALL;



EDIT:
Suggestion for Improvement:

why do you not use a Vector2<int> to store the Tilesize and the Mouse position?
when doing this and overloading some operators you could write it like this:
position = (mouse + camera)/tile::Tilesize;

And since you probably need to do more vector additions, i think it would be a good idea :)
Also: it would be a good exercise ;)
Last edited on
Thanks, it works alomost perfect. It's only one more problem I have, and that is when the tile map move. I have made a scrolling tile map, and I could only change the tiles when the tile map is standing still and not started to move. That's because I draw the new tiles realative to the window since I use the mouseX and mouseY from the SDL_getmousestate(). Do you know how to draw the new tiles relative to the tile map instead of relative to the window?


What you seem to be talking about is called Global/Absolute Coordinate System and Screen Coordinate System (Some use others names). The Absolute Coordinate System is a coordinate system which in your case would cover your entire tilemap and go on for infinity (Basically everything in your game even if it is off screen). Whereas the Screen Coordinate System is a coordinate system which covers only the portion of your game which is viewable on screen (Through your camera viewport).

Now for your problem you are going to need to go through this process to get the current tile which is under the mouse and then change it.

1. - Get the current screen coordinates for your mouse.

2. - Convert those screen coordinates to absolute coordinates. The exact process to go about this depends on what you are using, what state the viewport is in, etc. Though the gist of it is finding where the viewport is positioned and adding that vector to your screen coordinates.

3. Once you have the global coordinates you then use that vector to determine which tile you are on. Once you have determined the tile you can then switch its texture.

Though I am just mainly repeating what Gamer2015 mentioned already so I will stop now ;p. Though I would highly suggest digging in and making sure you have a very good understand of the different coordinate systems and how they interact with eachother.
Whoow, it works perfect!! Thanks guys, I have learned a lot of new things today. I'm relatively new with C++, and I ask therefore a lot of questions in this forum because I think that is the best way to learn C++ best.

@Gamer2015

Suggestion for Improvement:

why do you not use a Vector2<int> to store the Tilesize and the Mouse position?
when doing this and overloading some operators you could write it like this:
position = (mouse + camera)/tile::Tilesize;

And since you probably need to do more vector additions, i think it would be a good idea :)
Also: it would be a good exercise ;)


That's a pretty good Idea, I will definitely try that out :D

@Zereo

Though I am just mainly repeating what Gamer2015 mentioned already so I will stop now ;p. Though I would highly suggest digging in and making sure you have a very good understand of the different coordinate systems and how they interact with eachother.


Thanks, it was nice with a little more detailed explanation of the various step :-)

Last edited on
Have fun making your game ;)
Last edited on
Topic archived. No new replies allowed.