如何在用户仍使用SFML保持密钥时在精灵表上的两个不同部分之间来回切换

问题描述 投票:0回答:2

所以我这里唯一的目标是左右移动精灵,当精灵移动时,我想每隔半秒在我的精灵表的两个不同部分之间切换。

我已经尝试了所有我能想到的东西,所以我让它保持工作,而不仅仅是实现了所需的功能。 (编辑:我试图按照另一个用户的建议改变它)我在网上看过,但据我所知,我找不到任何答案。我敢肯定有一些我忽略的东西,它很简单,但这就是我需要你输入的原因。

我要使用的精灵表的第三部分是x = 800,左边的动画是y = 0的顶部,右边的动画是y = 600的底部

Here is the sprite sheet I am using

第一个是静止不动,两行中的第二个是我想在“行走”时切换的

无论如何,这是我的代码:

#include "pch.h"
#include <iostream>
#include "SFML/Graphics.hpp"
#include <random>
#include <unordered_map>

enum State 
{
    Walking,
    Standing
};
enum Direction
{
    Left,
    Right
};

int main(int argc, char ** argv)
{
    /* Gregory */

    sf::Texture GregorySpriteSheet_T;
    GregorySpriteSheet_T.loadFromFile("Images/GregorySpriteSheet.png");
    sf::IntRect GregorySpriteRect(0, 600, 400, 600);
    sf::Sprite Gregory(GregorySpriteSheet_T, GregorySpriteRect);

    sf::RenderWindow renderWindow(sf::VideoMode(1600,800), "SFML 2 Demo");

    sf::Event event;



    sf::Time timePerFrame = sf::seconds(1.0f / 60.0f);
    sf::Clock deltaClock;
    sf::Time timeSinceLastUpdate = sf::Time::Zero;


    State isWalking{ Standing };
    sf::Clock walkClock;
    Direction direction = Right;




    /* RENDER WINDOW LOOP */


    while (renderWindow.isOpen())
    {

        sf::Time deltaTime = deltaClock.restart();
        timeSinceLastUpdate += deltaTime;

        while (timeSinceLastUpdate >= timePerFrame)
        {
            timeSinceLastUpdate -= timePerFrame;



            while (renderWindow.pollEvent(event))
            {
                if (event.type == sf::Event::EventType::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
                {
                    renderWindow.close();
                }


                if (event.type == sf::Event::EventType::KeyPressed)
                {
                    if (event.key.code == sf::Keyboard::Right)
                    {
                        isWalking = Walking;
                        direction = Right;
                    }

                }
                if (event.type == sf::Event::EventType::KeyReleased)
                {
                    if (event.key.code == sf::Keyboard::Right)
                    {
                        isWalking = Standing;
                    }

                }


                if (event.type == sf::Event::EventType::KeyPressed)
                {
                    if (event.key.code == sf::Keyboard::Left)
                    {
                        isWalking = Walking;
                        direction = Left;

                    }
                }
                if (event.type == sf::Event::EventType::KeyReleased)
                {
                    if (event.key.code == sf::Keyboard::Left)
                    {
                        isWalking = Standing;

                    }
                }
            }



            if (isWalking == Walking)
            {
                if (direction == Right)
                    GregorySpriteRect.top = 600;
                if (direction == Left)
                    GregorySpriteRect.top = 0;

                if (GregorySpriteRect.left == 0)
                    GregorySpriteRect.left = 400;

                if ((int(walkClock.getElapsedTime().asSeconds() / 1.5f) % 2) == 1)
                {
                    if (GregorySpriteRect.left == 400)
                        GregorySpriteRect.left == 800;
                    if (GregorySpriteRect.left == 800)
                        GregorySpriteRect.left == 400;
                    walkClock.restart();
                }
            }

            {
                using kb = sf::Keyboard;

                    if (kb::isKeyPressed(kb::Right))
                    {
                        Gregory.move(400 * timePerFrame.asSeconds(), 0.0f);
                        direction = Right;
                        isWalking = Walking;
                    }


                    if (kb::isKeyPressed(kb::Left))
                    {
                        Gregory.move(-400 * timePerFrame.asSeconds(), 0.0f);
                        direction = Left;
                        isWalking = Walking;
                    }

                    if (kb::isKeyPressed(kb::Right) && kb::isKeyPressed(kb::Left))
                    {
                        isWalking = Standing;
                    }

            }


            if (isWalking == Standing)
            {
                GregorySpriteRect.left = 0;

                if (direction == Right)
                    GregorySpriteRect.top = 600;
                if (direction == Left)
                    GregorySpriteRect.top = 0;
            }

        }




        Gregory.setTextureRect(GregorySpriteRect);

        renderWindow.clear();
        renderWindow.draw(Gregory);
        renderWindow.display();

    }
                /* END RENDER WINDOW LOOP */



}
c++ time sprite sfml sprite-sheet
2个回答
0
投票

这是一个建议,但有很多选择:

首先,稍微重写您的事件处理,以便您可以在第一次持有密钥和后续时间之间进行区分。一个简单的方法是使用enum State { Standing, Walking }并将其设置为您的密钥处理程序中的适当值(例如“不行走并且密钥被保持?设置状态为行走”)

然后,当玩家开始行走时,(重新启动“墙”时钟。

最后,当你实际渲染你的玩家时,检查这个时钟并划分自步行时间以来走过的时间(这决定了应该保持一个步行帧的长度)。如果有相同数量的步行时段,请使用左步行精灵,否则使用右步行精灵。

当然,这种技术很容易推广到更大的步行框架集。


0
投票

所以对于将来在这里结束的人来说,我错过了一条至关重要的路线:

Gregory.setTextureRect(GregorySpriteRect);

在“if(isWalking == Walking)”下的时钟的“if”语句中,或者在它下面(就像我在这里所做的那样)。粘贴下面的完整代码。现在适用于两个方向。不确定这是多么优越,但如果你像我这样的业余爱好者应该有所帮助。

还要注意我已经恢复了Botje的回答中提出的一些改变。虽然我必须相信他能帮助我使用enum's for Walking and Standing以及方向。由于浮点变量的舍入误差,我还使用了一个“>”运算符而不是我教授建议的“==”运算符。

干杯!

#include "pch.h"
#include <iostream>
#include "SFML/Graphics.hpp"
#include <random>
#include <unordered_map>

enum State 
{
    Walking,
    Standing
};
enum Direction
{
    Left,
    Right
};

int main(int argc, char ** argv)
{
    /* Gregory */

    sf::Texture GregorySpriteSheet_T;
    GregorySpriteSheet_T.loadFromFile("Images/GregorySpriteSheet.png");
    sf::IntRect GregorySpriteRect(0, 600, 400, 600);
    sf::Sprite Gregory(GregorySpriteSheet_T, GregorySpriteRect);

    sf::RenderWindow renderWindow(sf::VideoMode(1600,800), "SFML 2 Demo");

    sf::Event event;



    sf::Time timePerFrame = sf::seconds(1.0f / 60.0f);
    sf::Clock deltaClock;
    sf::Time timeSinceLastUpdate = sf::Time::Zero;


    State isWalking{ Standing };
    sf::Clock walkClock;
    Direction direction = Right;




    /* RENDER WINDOW LOOP */


    while (renderWindow.isOpen())
    {

        sf::Time deltaTime = deltaClock.restart();
        timeSinceLastUpdate += deltaTime;

        while (timeSinceLastUpdate >= timePerFrame)
        {
            timeSinceLastUpdate -= timePerFrame;



            while (renderWindow.pollEvent(event))
            {
                if (event.type == sf::Event::EventType::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
                {
                    renderWindow.close();
                }


                if (event.type == sf::Event::EventType::KeyPressed)
                {
                    if (event.key.code == sf::Keyboard::Right)
                    {
                        isWalking = Walking;
                        direction = Right;
                        GregorySpriteRect.top = 600;
                    }

                }
                if (event.type == sf::Event::EventType::KeyReleased)
                {
                    if (event.key.code == sf::Keyboard::Right)
                    {
                        isWalking = Standing;
                    }

                }


                if (event.type == sf::Event::EventType::KeyPressed)
                {
                    if (event.key.code == sf::Keyboard::Left)
                    {
                        isWalking = Walking;
                        direction = Left;
                        GregorySpriteRect.top = 0;

                    }
                }
                if (event.type == sf::Event::EventType::KeyReleased)
                {
                    if (event.key.code == sf::Keyboard::Left)
                    {
                        isWalking = Standing;
                    }
                }
            }



            if (isWalking == Walking)
            {
                if (direction == Right)
                    GregorySpriteRect.top = 600;
                else if (direction == Left)
                    GregorySpriteRect.top = 0;
                else 
                    GregorySpriteRect.top = 600;

                if (GregorySpriteRect.left == 0)
                    GregorySpriteRect.left = 400;

                if (walkClock.getElapsedTime().asSeconds() > 0.5f)
                {
                    if (GregorySpriteRect.left == 400)
                        GregorySpriteRect.left = 800;
                    else if (GregorySpriteRect.left == 800)
                        GregorySpriteRect.left = 400;
                    else
                        GregorySpriteRect.left += 0;

                    walkClock.restart();
                }

                Gregory.setTextureRect(GregorySpriteRect);

            }

            {
                using kb = sf::Keyboard;

                    if (kb::isKeyPressed(kb::Right))
                    {
                        Gregory.move(400 * timePerFrame.asSeconds(), 0.0f);
                        direction = Right;
                    }


                    if (kb::isKeyPressed(kb::Left))
                    {
                        Gregory.move(-400 * timePerFrame.asSeconds(), 0.0f);
                        direction = Left;
                    }

                    if (kb::isKeyPressed(kb::Right) && kb::isKeyPressed(kb::Left))
                    {
                        isWalking = Standing;
                        direction = Right;
                    }

            }


            if (isWalking == Standing)
            {
                GregorySpriteRect.left = 0;

                if (direction == Right)
                    GregorySpriteRect.top = 600;
                if (direction == Left)
                    GregorySpriteRect.top = 0;
            }

        }




        Gregory.setTextureRect(GregorySpriteRect);

        renderWindow.clear();
        renderWindow.draw(Gregory);
        renderWindow.display();

    }
                /* END RENDER WINDOW LOOP */



}
© www.soinside.com 2019 - 2024. All rights reserved.