0
votes

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.

maze datas

        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!

1
Removed OpenGL references because the problem is not related to OpenGL. Please try to provide minimal, reproducible examples. That includes removing OpenGL and any other unrelated factors (e.g. GLFW) from the question, as well as simplifying it (e.g. removing other types like Keyboard if possible).Acorn
Oooh, sorry, yees, you're totally right! I'm a bit messed up sometimes hahachuck
What you want is not only a collision detection system, but a physics engine that prevents player from clipping through the walls. Check those out: developer.mozilla.org/en-US/docs/Games/Techniques/… youtu.be/7_nKOET6zwIMarcin Poloczek
Thank you, I know this website, it's actually right now open next to this tab...Yes, I would need something to prevent going through the walls...chuck

1 Answers

1
votes

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 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.