SFML community forums

Help => General => Topic started by: valva-ro on September 15, 2020, 08:35:08 pm

Title: Check player collisions in a maze
Post by: valva-ro on September 15, 2020, 08:35:08 pm
Hi, I'm new to SFML and I'm trying to make a simple maze game. So far I've been able to build the maze with a backtracking algorithm and make the player move up, down, left, and right. The thing is the maze and the player don't "interact" with each other, they're like two separate things. I know SFML has methods to get the sprite boundaries and I found tons of information about that, but I don't think it suits the structure I'm using

I created a Cell class with these attributes
sf::RectangleShape cell;
sf::RectangleShape walls[4];
sf::Texture background;
uint8_t activeWalls;

Then I added to the Maze a Cell matrix (using std::vector).

What I tried (and failed) to implement is a method in my Player class  that receives a pointer of the maze and checks if the position in which is going is allowed or not:

bool Player:: locationAllowed(Maze *maze, sf::Vector2f position, const char &direction) {

    bool allowed = false;
    Cell *aux;

    switch (direction) {
        case UP:
            position += sf::Vector2f(0.f, 1.f);
            aux = maze->getCell(position);
            if (aux)
                allowed = (aux->getActiveWalls() != UP_WALL);
            break;
        case DOWN:
            position += sf::Vector2f(0.f, -1.f);
            aux = maze->getCell(position);
            if (aux)
                allowed = (aux->getActiveWalls() != DOWN_WALL);
            break;
        case LEFT:
            position += sf::Vector2f(-1.f, 0.f);
            aux = maze->getCell(position);
            if (aux)
                allowed = (aux->getActiveWalls() != LEFT_WALL);
            break;
        case RIGHT:
            position += sf::Vector2f(1.f, 0.f);
            aux = maze->getCell(position);
            if (aux)
                allowed = (aux->getActiveWalls() != RIGHT_WALL);
            break;
    }
    return allowed;
}

The method above is used here:
void Player::move(Maze *maze, float deltaTime) {

    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && locationAllowed(maze, position, UP)) {
        this->position += sf::Vector2f(0, -speed * deltaTime);
        this->player.move(0, -speed * deltaTime);
    }

    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && locationAllowed(maze, position, DOWN)) {
        this->position += sf::Vector2f(0, speed * deltaTime);
        this->player.move(0, speed * deltaTime);
    }

    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && locationAllowed(maze, position, LEFT)) {
        this->position += sf::Vector2f(-speed * deltaTime, 0);
        this->player.move(-speed * deltaTime, 0);
    }

    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right) && locationAllowed(maze, position, RIGHT)) {
        this->position += sf::Vector2f(speed * deltaTime, 0);
        this->player.move(speed * deltaTime, 0);
    }
}

The problem is that the player doesn't move at all. I think it's because the line
Code: [Select]
aux = maze->getCell(position); returns always null because the position given doesn't exist in the maze, therefore allowed is always false. I need to change the position's value so that it belongs to the maze, but I don't know how. Any suggestions?

If you want to see the full code you can check https://github.com/valva-ro/maze (https://github.com/valva-ro/maze) branch develop and I also pasted it here:
Title: Re: Check player collisions in a maze
Post by: eXpl0it3r on September 16, 2020, 08:16:20 am
You can simplify the code quite a bit by calculating which position in the maze the player will move to, regardless of the direction the go, then before moving, check whether the player can move there and if so move them.

That way you have one location where you check whether the player can move to a place instead of four for each direction.
If getCell() returns the wrong position, make sure you double check your math on calculating the right cell.