简体   繁体   中英

Collision detection in C++

I am working on a 3D maze game where the labyrinth itself is generated automatically and randomly each time I run the program. So basically the walls are always somewhere else. This is where I need help to figure out how to detect collision thus not able the player to press the buttons to move since there's a wall. (3D actually doesn't really matter since it's seen from above and it works like a 2D maze now)

This is where I am so far:

My character is a simple cube:

struct Cube {
    glm::vec3 position;
    glm::vec3 size;
};

Below you can find how I make my character moveable. I could check whether there's the edge of the maze so you can't move thru those walls but inside the labyrinth, you still can. The walls are always 0.25 wide. I'd like to implement a function like IsCollide but I don't really know how. When I'd call the function, the std::vector<Cube> maze will contain the datas I'll show on the picture.

迷宫数据

        static void MoveCharacter(Cube &character, Keyboard keyboard, std::vector<Cube> maze)
        {
            if (keyboard.getKey(GLFW_KEY_UP))
            {

                if (character.position.x >= MazeHeight - 1.0f) || IsCollide(character, maze))
                {
                   character.position += glm::vec3(0,0,0);
                } else character.position += glm::vec3(0.05, 0, 0);
            }
            if (keyboard.getKey(GLFW_KEY_DOWN))
            {
                if (character.position.x <= 0.0f)
                {
                    character.position += glm::vec3(0, 0, 0);
                } else character.position -= glm::vec3(0.05, 0, 0);

            }
            if (keyboard.getKey(GLFW_KEY_RIGHT))
            {
                if (character.position.z >= MazeWidth - 1.0f)
                {
                    character.position += glm::vec3(0, 0, 0);
                } else character.position += glm::vec3(0, 0, 0.05);
            }
            //...
         }

I tried to write my function like this somehow but I am pretty much lost in this and not sure how to go on...

     static bool IsCollide(Cube character, std::vector<Cube> maze)
        {
        for (auto i : maze)
            if ( (character.position.x < (i.position.x + i.size.x)) && (character.position.x + character.size.x > i.position.x)) // && (//...) && (//...)
     // to implement!
            {
                return true;
            } return false;
        }

I'd be VERY happy for every answer and help!

Thank you so much in advance!

Collision detection is a very complex topic, so that you may want to consider using an already existing library instead of attempting to program this all yourself.

If you really want to attempt to program this yourself, then you could do the following:

In the program you posted, the player moves by 0.05 units at a time, and walls have a thickness of 0.25 units. Therefore, it may be sufficient to implement collison testing by simply testing whether the player's new position is inside a wall. With faster moving objects (such as bullets fired from a gun), such collison detection may not be sufficient, as the object could pass through the wall in one step without ever being inside it.

In order to test whether the player's new position is inside a wall, you could compare the player's position with every single wall on the map. However, depending on the number of walls on the map, this could be a lot of work. Therefore, a more efficient algorithm would only test the player's new position with walls that are nearby.

In order for your program to be able to determine which walls are nearby, your program needs to have a data structure in which all walls near a certain position are listed. For example, you could divide your map into a fixed grid and for every tile in that grid, you have a list of all walls that touch that tile. That way, in order to determine whether the player's new position is inside a wall, all you have to do is compare the player's new position with the list of all walls in the tile of the player's new position. If the player's new position is touching several tiles, then you will have to compare the player's new position with the lists of walls in all of the tiles the player is touching.

Instead of using a fixed grid, you could also use a more adaptive data structure, such as an R-tree . Generally, such a data structure works better if the objects are not evenly spaced, such as when you have many objects in a small area and most of the rest of the map is empty.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM