samedi 23 juillet 2022

add deltaTime to movements in sfml

im working on Pacman game with c++ and sfml.as time passes, the game becomes slower. so i want to add delta time to movements. i added in one way but collision not working correctly after using delta time.i think i used the wrong method for it.

My main code

#include <SFML/Graphics.hpp>
#include <Map.hpp>

using namespace sf;

int main()
{
RenderWindow window(VideoMode(Width * CellSize, Height * CellSize), "PacMan");
window.setFramerateLimit(120);
Map map;

float dt;
Clock clock;


while (window.isOpen())
{

    Event event;
    while (window.pollEvent(event))
    {
        if (event.type == Event::Closed)
        {
            window.close();
        }
        if (event.type == Event::KeyPressed && event.key.code == Keyboard::Escape)
        {
            window.close();
        }
    }
    
    window.clear();

    dt = clock.restart().asSeconds() * 50;
    map.draw(window, dt);

    window.display();
}

}

Map class

#include <SFML/Graphics.hpp>
#include <array>
#include <iostream>
#include <Pacman.hpp>
#include <vector>

using namespace sf;

class Map
{
private:
    std::array<std::string, Height> sketch;
    Pacman pacman;
    std::vector<sf::RectangleShape> Walls;

    void initMap();

public:
    Map();
    void draw(sf::RenderWindow & window, float dt);

};

Map::Map()
{
    this->initMap();
}

void Map::initMap()
{
    sketch = {
        " ################### ",
        " #        #        # ",
        " # ## ### # ### ## # ",
        " #                 # ",
        " # ## # ##### # ## # ",
        " #    #   #   #    # ",
        " #### ### # ### #### ",
        "    # #       # #    ",
        "##### # ##### # #####",
        "        #   #        ",
        "##### # ##### # #####",
        "    # #       # #   ",
        " #### ### # ### #### ",
        " #    #   #   #    # ",
        " # ## # ##### # ## # ",
        " #                 # ",
        " # ## ### # ### ## # ",
        " #        #        # ",
        " ################### ",
        "                     ",
        "                     "
    };
}

void Map::draw(RenderWindow & window, float dt)
{
    RectangleShape Wall(Vector2f(CellSize, CellSize));
    Wall.setFillColor(Color::Blue);

    for (size_t i = 0; i < Height; i++)
    {
        for (size_t j = 0; j < Width; j++)
        {
            switch (sketch[i][j])
            {
            case '#':
                Wall.setPosition(Vector2f(j * CellSize, i * CellSize));
                Walls.push_back(Wall);
                break;
            }
        }
    }

    for(auto & a : Walls)
    {
        window.draw(a);
    }
    
    
    pacman.draw(window);
    pacman.move(Walls, dt, sketch);
}

Pacman class

    #include <SFML/Graphics.hpp>
#include <vector>
#include <info.hpp>

class Pacman
{
private:
    sf::CircleShape player;
    sf::Vector2f Pos;
    int dir;


    void initPacman();
    bool collision(float i_x, float i_y, std::array<std::string, Height> sketch);

public:
    Pacman();
    void draw(sf::RenderWindow & window);
    void move(std::vector<sf::RectangleShape> Walls, float dt, std::array<std::string, Height> sketch);
};

#include <iostream>
#include <cmath>

using namespace sf;

Pacman::Pacman()
{
    this->initPacman();
}

void Pacman::initPacman()
{
    Pos.x = 10 * CellSize;
    Pos.y = 11 * CellSize;
    player.setRadius(CellSize / 2);
    player.setFillColor(Color::Yellow);
    player.setPosition(Pos);
    dir = -1;
}

void Pacman::draw(RenderWindow & window)
{
    window.draw(player);
}

void Pacman::move(std::vector<sf::RectangleShape> Walls, float dt, std::array<std::string, Height> sketch)
{
    std::array<bool, 4> wall;

i checking collision here.i will check the next position that hits the wall or not. i think my delta time makes it work randomly. // Collision Right wall[0] = collision(player.getPosition().x + (Speed * dt), player.getPosition().y, sketch); // Collision Down wall[1] = collision(player.getPosition().x, player.getPosition().y + (Speed * dt), sketch); // Collision Left wall[2] = collision(player.getPosition().x - (Speed * dt), player.getPosition().y, sketch); // Collision Up wall[3] = collision(player.getPosition().x, player.getPosition().y - (Speed * dt), sketch);

    Vector2f position;
    position.x = 0;
    position.y = 0;

    if(Keyboard::isKeyPressed(Keyboard::Right))
    {
        if (wall[0] == 0)
        {
            dir = 0;
        }   
    } else if(Keyboard::isKeyPressed(Keyboard::Down))
    {
        if (wall[1] == 0)
        {
            dir = 1;
        }
    } else if(Keyboard::isKeyPressed(Keyboard::Left))
    {   
        if (wall[2] == 0)
        {
            dir = 2;
        }
    } else if(Keyboard::isKeyPressed(Keyboard::Up))
    {
        if (wall[3] == 0)
        {
            dir = 3;
        }
    }

    if (wall[dir] == 0)
    { 
        switch (dir)
        {
        case 0:
            position.x += Speed * dt;
            break;
        case 1:
            position.y += Speed * dt;
            break;
        case 2:
            position.x -= Speed * dt;
            break;
        case 3:
            position.y -= Speed * dt;
            break;
        }
    }
    player.move(position.x, position.y);
}

bool Pacman::collision(float px, float py, std::array<std::string, Height> sketch)
{
    
    float cell_x = px / static_cast<float>(CellSize);
    float cell_y = py / static_cast<float>(CellSize);

// std::cout << cell_x << "\n";
    for (int a = 0; a < 4; a++)
    {
        float x = 0;
        float y = 0;

        switch (a)
        {
            case 0: //Top left cell
            {
                x = static_cast<float>(floor(cell_x));
                y = static_cast<float>(floor(cell_y));

                break;
            }
            case 1: //Top right cell
            {
                x = static_cast<float>(ceil(cell_x));
                y = static_cast<float>(floor(cell_y));

                break;
            }
            case 2: //Bottom left cell
            {
                x = static_cast<float>(floor(cell_x));
                y = static_cast<float>(ceil(cell_y));

                break;
            }
            case 3: //Bottom right cell
            {
                x = static_cast<float>(ceil(cell_x));
                y = static_cast<float>(ceil(cell_y));
            }
        }

        if (0 <= x && 0 <= y && Height > y && Width > x)
        {
            //std::cout << "x : " << x << "\t y : " << y << "\n";
            if (sketch[y][x] == '#')
            {
                return 1;
            }
        }
    }
    return 0;
}

Aucun commentaire:

Enregistrer un commentaire