如何减慢我的精灵动画?

agt*_*gtv 5 c++ animation sfml

目前我有这个player.cpp课程,我正在使用我的精灵动画.我正在使用计数器来更新每一帧.它动画,但它通过动画飞行.

我想放慢速度.我找到了可以用来减慢精灵动画的代码,但我不确定如何将它实现到我当前的程序中.

下面是我的player.cpp文件,然后是我发现可以减慢精灵动画的代码.当我试图添加一个时钟时counterWalking++它根本没有动画,我已经尝试实现这个代码同样的效果.

player::player()
{
    rect.setSize(sf::Vector2f(32, 32));
    rect.setFillColor(sf::Color::White);
    rect.setPosition(300, 300);
    sprite.setTextureRect(sf::IntRect(0, 0, 32, 32));
}

void player::update()
{
    sprite.setPosition(rect.getPosition());
}

void player::updateMovement()
{
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {

        if (canMoveRight == true) {

            rect.move(movementSpeed, 0);
            sprite.setTextureRect(sf::IntRect(counterWalking * 32, 64, 32, 32));
            direction = 4;
            canMoveUp = true;
            canMoveDown = true;
            canMoveLeft = true;
            canMoveRight = true;
        }
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {

        if (canMoveLeft == true) {

            rect.move(-movementSpeed, 0);
            sprite.setTextureRect(sf::IntRect(counterWalking * 32, 32, 32, 32));
            direction = 3;
            canMoveUp = true;
            canMoveDown = true;
            canMoveLeft = true;
            canMoveRight = true;
        }
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {

        if (canMoveUp == true) {

            rect.move(0, -movementSpeed);
            sprite.setTextureRect(sf::IntRect(counterWalking * 32, 96, 32, 32));
            direction = 1;
            canMoveUp = true;
            canMoveDown = true;
            canMoveLeft = true;
            canMoveRight = true;
        }
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {

        if (canMoveDown == true) {

            rect.move(0, movementSpeed);
            sprite.setTextureRect(sf::IntRect(counterWalking * 32, 0, 32, 32));
            direction = 2;
            canMoveUp = true;
            canMoveDown = true;
            canMoveLeft = true;
            canMoveRight = true;
        }
    }
    else {
        //Player not moving
    }
    counterWalking++;

    if (counterWalking == 3)
        counterWalking = 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我发现的代码,显示一个慢动画:

int main()
{
    sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "Demo Game");
    sf::Event event;
    sf::Texture texture;
    texture.loadFromFile("images/player.png");
    sf::IntRect rectSourceSprite(0, 0, 32, 32);
    sf::Sprite sprite(texture, rectSourceSprite);
    sf::Clock clock;

    while (renderWindow.isOpen()) {

        while (renderWindow.pollEvent(event)) {

            if (event.type == sf::Event::EventType::Closed)
                renderWindow.close();
        }

        if (clock.getElapsedTime().asSeconds() > 1.0f) {

            if (rectSourceSprite.left == 96)
                rectSourceSprite.left = 0;
            else
                rectSourceSprite.left += 32;

            sprite.setTextureRect(rectSourceSprite);
            clock.restart();
        }

        renderWindow.clear();
        renderWindow.draw(sprite);
        renderWindow.display();
    }
}
Run Code Online (Sandbox Code Playgroud)

Tre*_*cos 1

由于解决方案已在评论中给出,但未在答案中实现,因此这里有某种“代码审查”

按键绑定

这段代码实际上使用的是每个循环sf::Keyboard::isKeyPressedsf::Keyboard::isKeyReleased需要调用的,而按下/释放按键时切换的简单布尔值可以使用事件来工作。

while (renderWindow.pollEvent(event)) {

            if (event.type == sf::Event::EventType::Closed)
                renderWindow.close();
        }
Run Code Online (Sandbox Code Playgroud)

主循环中使用的事件也包含有关 KeyEvents 的信息,但不是以这种方式使用的。我建议每次发生关键事件时向玩家发送 evet:

    while (renderWindow.pollEvent(event)) {
        switch(event.type){
        case sf::Event::EventType::Closed:
            renderWindow.close();
            break;

        case sf::Event::KeyPressed: case sf::Event::KeyReleased:
            myPlayer.keyEvent(event);
            break;
        }
    }
Run Code Online (Sandbox Code Playgroud)

播放器中的函数keyEvent应如下所示:

void player::keyEvent(sf::Event event){
    //Keycode of your keyboard's arrows goes from 71 to 74
    if (event.key.code >= 71 && event.key.code <= 74){
        //Gets the array ID from the enumeration value
        int ID = event.key.code - 71;
        //Stores false if the key is release, and true if it's pressed
        keys[ID] = (event.type == sf::Event::KeyPressed);
    }
}
Run Code Online (Sandbox Code Playgroud)

它将更改 Player.h 中数组的每个值:

private:
    bool keys[4];
Run Code Online (Sandbox Code Playgroud)

移动

现在您所要做的就是每秒在游戏循环中调用玩家 update() 函数:

if (clock.getElapsedTime().asSeconds() > 1.0f) {

        if (rectSourceSprite.left == 96)
            rectSourceSprite.left = 0;
        else
            rectSourceSprite.left += 32;

        sprite.setTextureRect(rectSourceSprite);
        myPlayer.update();
        clock.restart();
    }
Run Code Online (Sandbox Code Playgroud)

在该update()函数中,您将根据按下的键构建移动向量:

void player::update()
{
    sf::Vector2f movementVector(0,0);
    //Left
    if (keys[0]){
        movementVector.x -= movementSpeed;
        //Sends the sprite Rectangle position based on the movement type
        move(32);
    }
    //Right
    if (keys[1]){
        movementVector.x += movementSpeed;
        move(64);
    }
    //Up
    if (keys[2]){
        movementVector.y -= movementSpeed;
        move(96);
    }
    //Down
    if (keys[3]){
        movementVector.y += movementSpeed;
        move(0);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,移动函数将根据移动矢量和计数器移动您的精灵位置,然后设置精灵。
你的移动计数器将增加到 30,并且只有当该计数器等于 0、10 或 20 时,你的玩家才可以移动:

void move(int spritePos){
    //Here, the check() function should tell if the player isn't going outside of the screen / in a wall
    if (check(sprite.getPosition() + movementVector)){
        sprite.move(movementVector);
        ++counterWalking %= 30;

        if(!counterWalking % 10)
            sprite.setTextureRect(sf::IntRect(counterWalking / 10 * 32, spritePos, 32, 32));
    }
}
Run Code Online (Sandbox Code Playgroud)

有多种方法可以做到这一点,这只是我会这样做的方式