繁体   English   中英

在 sfml 中拖动精灵

[英]Dragging a sprite in sfml

我现在正在做一项任务,为此,我需要将棋子拖到棋盘上,问题是我不知道如何使这项工作不止一个棋子。 我可以计算鼠标 position 并且我只能移动一件,但代码仅适用于该单件。 我的问题是我如何点击一个片段,让它成为活动片段,直到我释放鼠标按钮。 如果我只检查它是否与一件相交,这将不起作用,因为那时它不是动态的。 我的代码因为我尝试不同的东西而一团糟,但这里有一些相关的部分。

这是精灵的设置:

// load the texture and setup the sprite for the logo
void Game::setupSprite()
{
    sf::IntRect pieceRect(m_wking.getPosition().x, m_wking.getPosition().y, 128, 128);

    if (!m_boardTexture.loadFromFile("ASSETS\\IMAGES\\board.png"))
    {
        // simple error message if previous call fails
        std::cout << "problem loading board" << std::endl;
    }
    m_boardSprite.setTexture(m_boardTexture);
    m_boardSprite.setPosition(0.0f, 0.0f);


    //pieces
    if (!m_wkingTex.loadFromFile("ASSETS\\IMAGES\\PIECES\\wking.png"))
    {
        // simple error message if previous call fails
        std::cout << "problem loading piece" << std::endl;
    }
    m_wking.setTexture(m_wkingTex);
    m_wking.setPosition(0.0f, 0.0f);
    sf::IntRect wkingRect(pieceRect);
}

如果鼠标按钮按下

void Game::processMouseButtonDown(sf::Event t_event)
{
    if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
        std::cout << "Mouse button pressed\n";
        sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
        if (isSpriteClicked() && !m_holdingPiece) {

            m_holdingPiece = true;
        }
    }
}

鼠标按钮向上:

void Game::processMouseButtonUp(sf::Event t_event)
{
    m_holdingPiece = false;
    sf::IntRect pieceRect(m_wking.getPosition().x, m_wking.getPosition().y, 128, 128);
    m_wking.setTextureRect(pieceRect);
}

如果精灵被点击

bool Game::isSpriteClicked()
{
    sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
    sf::FloatRect bounds(mouse.x, mouse.y, 1.0f, 1.0f);
    if (bounds.intersects(wkingRect.I dont know what Im doing)) {

        std::cout << "King has Been clicked!\n";
        return true;
    }
    else {
        return false;
    }
}

最后移动精灵:

void Game::move()
{
    if (m_holdingPiece) {
        sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
        m_wking.setPosition(mouse);
    }
}

对不起,如果这看起来像很多代码,但我觉得这一切都与问题有关。

问题:

您已经对所有变量进行了硬编码,因此即使您创建一个列表并对其进行迭代以运行Game::move()它也会移动所有部分而不是仅移动一个,因为变量m_holdingPiece对于所有部分都是相同的。

解决方案:

您应该使用更多的 OOP 方法为棋子创建 class 而Game class 可能应该只控制游戏何时开始,何时结束并检查移动是否合法。 解释所有这些都太宽泛了 Stack Overflow 并且它是你必须做的工作的一部分,所以我将举一个例子来说明一个基本的chessPiece class 将如何使棋子变得可拖动。

例子:

这是一个如何使一组片段可拖动的示例。

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

class chessPiece: public sf::Drawable, public sf::Transformable
{
private:
    sf::RenderWindow& window;
    sf::Texture texture;
    sf::Sprite sprite;
    bool moving;
public:
    chessPiece(sf::RenderWindow& windowRef, const std::string& fileName): window(windowRef)
    {
        if(!texture.loadFromFile(fileName))
            exit(0);
        this->sprite.setTexture(this->texture);
        this->moving = false;
        this->sprite.setScale(128/this->sprite.getGlobalBounds().width,128/this->sprite.getGlobalBounds().height);
    }
    chessPiece(chessPiece&& rval): window(rval.window)
    {
        this->texture = std::move(rval.texture);
        this->sprite.setTexture(this->texture);
        this->sprite.setScale(rval.sprite.getScale());
        this->moving = std::move(rval.moving);
    }
    chessPiece(const chessPiece& lval): window(lval.window)
    {
        this->texture = lval.texture;
        this->sprite.setTexture(this->texture);
        this->sprite.setScale(lval.sprite.getScale());
        this->moving = lval.moving;
    }
    void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        states.transform *= this->getTransform();
        target.draw(this->sprite,states);
    }
    void move(bool& movingAPiece)
    {
        sf::Vector2f mousePosition = window.mapPixelToCoords(sf::Mouse::getPosition(window));
        if(this->moving)
        {
            this->setPosition(mousePosition.x - this->sprite.getGlobalBounds().width/2,mousePosition.y - this->sprite.getGlobalBounds().height/2);
            if(!sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
            {
                this->moving = false;
                movingAPiece = false;
            }
        }
        else
        {
            if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Left) && mousePosition.x > this->getPosition().x &&
               mousePosition.y > this->getPosition().y && mousePosition.x < this->getPosition().x + this->sprite.getGlobalBounds().width &&
               mousePosition.y < this->getPosition().y + this->sprite.getGlobalBounds().height && !movingAPiece)
            {
                this->moving = true;
                movingAPiece = true;
            }
        }
    }
};

int main()
{
    sf::RenderWindow window(sf::VideoMode(1000,500),"Window");
    std::vector<chessPiece> pieces = {chessPiece(window,"white-king.png"),chessPiece(window,"white-pawn.png")};
    pieces[0].setPosition(400,400);
    bool movingAPiece = false;
    while(true)
    {
        sf::Event event;
        if(window.pollEvent(event))
            if(event.type == sf::Event::Closed)
                window.close();
        for(unsigned int i = 0; i < pieces.size(); i++)
            pieces[i].move(movingAPiece);
        window.clear();
        for(unsigned int i = 0; i < pieces.size(); i++)
            window.draw(pieces[i]);
        window.display();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM