mardi 27 avril 2021

Is there a way I can keep something at a constant speed in C++ game?

I currently have a game where there is a player, enemies, and projectiles. The user can spawn projectiles to damage enemies. However, the problem that I am having, is that the enemies speed up the more projectiles the user spawns in a row. I tried to use a game clock to keep everything constant and my game loop is below.

while (window.isOpen())
{
    std::chrono::high_resolution_clock::time_point begin = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < enemies.size(); i++)
    {
        enemies[i].move(begin, HEIGHT, WIDTH, player);
    }
    for (size_t i = 0; i < player.projectiles.size();)
    {
        if (player.projectiles[i].move(begin, WIDTH))
        {
            player.projectiles.erase(player.projectiles.begin() + i);
        }
        else
        {
            i++;
        }
    }
    for (int i = 0; i < enemies.size();)
    {
        for (int j = 0; j < player.projectiles.size();)
        {
            if (enemies[i].hit(player.projectiles[j]))
            {
                player.projectiles.erase(player.projectiles.begin() + j);
            }
            else
            {
                j++;
            }
        }
        if (enemies[i].hp <= 0)
        {
            enemies.erase(enemies.begin() + i);
        }
        else
        {
            i++;
        }
    }
    sf::Event event;
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
        {
            window.close();
            break;
        }
        if (sf::Mouse::isButtonPressed(sf::Mouse::Right))
        {
            enemies.push_back(Enemy(100.0, 1.0, Mouse::getPosition().x, Mouse::getPosition().y, Color::White));
        }
        if (event.type == Event::KeyPressed)
        {
            if (event.key.code == player.up)
            {
                player.moving_up = true;
            }
            else if (event.key.code == player.down)
            {
                player.moving_down = true;
            }
            else if (event.key.code == player.right)
            {
                player.moving_right = true;
            }
            else if (event.key.code == player.left)
            {
                player.moving_left = true;
            }
            else if (event.key.code == player.shoot)
            {
                player.shooting = true;
            }
            if (event.key.code == player.exit)
            {
                window.close();
            }
        }
        if (event.type == Event::KeyReleased)
        {
            if (event.key.code == player.up)
            {
                player.moving_up = false;
            }
            else if (event.key.code == player.down)
            {
                player.moving_down = false;
            }
            else if (event.key.code == player.right)
            {
                player.moving_right = false;
            }
            else if (event.key.code == player.left)
            {
                player.moving_left = false;
            }
            else if (event.key.code == player.shoot)
            {
                player.shooting = false;
            }
        }
        player.input(begin, HEIGHT, WIDTH);
        for (int i = 0; i < enemies.size();)
        {
            for (int j = 0; j < player.projectiles.size();)
            {
                if (enemies[i].hit(player.projectiles[j]))
                {
                    player.projectiles.erase(player.projectiles.begin() + j);
                }
                else
                {
                    j++;
                }
            }
            if (enemies[i].hp <= 0)
            {
                enemies.erase(enemies.begin() + i);
            }
            else
            {
                i++;
            }
        }
    }
    window.clear();
    player.draw(window);
    for (int i = 0; i < enemies.size(); i++)
    {
        enemies[i].draw(window);
    }
    window.display();
}

The enemy.move function looks like this, where speed is set to 1.0:

void Enemy::move(std::chrono::high_resolution_clock::time_point begin, float height, float width, Player player)
{
    std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
    if (player.x < this->x)
    {
        if (this->x - (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0) < 0)
        {
            this->x = 0;
        }
        else
        {
            this->x = this->x - (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0);
        }
        if (player.y < this->y)
        {
            if (this->y - (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0) < 0)
            {
                this->y = 0;
            }
            else
            {
                this->y = this->y - (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0);
            }
        }
        else
        {
            if (this->y + (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0) > (height - double(this->sprite.getSize().y)))
            {
                this->y = height - double(this->sprite.getSize().y);
            }
            else
            {
                this->y = this->y + (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0);
            }
        }
    }
    else
    {
        if (this->x + (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0) > (width - double(this->sprite.getSize().x)))
        {
            this->x = width - double(this->sprite.getSize().x);
        }
        else
        {
            this->x = this->x + (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0);
        }
        if (player.y < this->y)
        {
            if (this->y - (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0) < 0)
            {
                this->y = 0;
            }
            else
            {
                this->y = this->y - (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0);
            }
        }
        else
        {
            if (this->y + (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0) > (height - double(this->sprite.getSize().y)))
            {
                this->y = height - double(this->sprite.getSize().y);
            }
            else
            {
                this->y = this->y + (enemy_speed * (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000.0);
            }
        }
    }
    this->sprite.setPosition(this->x, this->y);
}

I apologize for the long segments of code but these are the relative parts and I don't know specifically what pieces of code you may need. Any help is greatly appreciated.

Aucun commentaire:

Enregistrer un commentaire