c++ - 为什么我的按钮类项目共享相同的 lambda 函数?

标签 c++ class sfml

我正在尝试在 SFML 中制作我自己的可重用按钮类。这将允许我创建一个按钮并向其添加回调函数,以便更轻松地创建按钮。

这是我的 hpp 文件:

#ifndef Button_hpp
#define Button_hpp

#include <stdio.h>
#include <SFML/Graphics.hpp>
#include "View.hpp"
#include "State.hpp"
#include "Window.hpp"
namespace kge {
  class Button: public View{
  private:
    sf::RectangleShape* _buttonOutline;
    sf::RenderWindow* _window;
    sf::Clock _clock;
    std::string _textString;
    sf::Text* _text;
  public:
    Button(Window*, std::string);
    ~Button();
    virtual void update(float td);
    std::function<void(void)> callback;
    void setPosition(float x, float y);
  };
}
#endif /* Button_hpp */

这里是我生成按钮的地方:

_restartButton = new kge::Button(_window, "Restart");
_restartButton->setPosition(getCenterOfScreen().x-((11*fontSize)/2), 300);
_restartButton->callback = ([this](){
  State::instance().currentView = new GameView(this->_window);
  this->_window->setView(State::instance().currentView);
});
_exitButton = new kge::Button(_window, "Quit");
_exitButton->setPosition(getCenterOfScreen().x-((11*fontSize)/2), 500);
_exitButton->callback = ([this](){
  this->_window->close();
});

最后,我告诉按钮更新并检查我的窗口更新,button->update(td)

我的所有按钮似乎都执行上次设置回调的操作。在这种情况下,我的重启按钮会执行我的退出代码。

为什么会发生这种情况,我该如何解决?

编辑

这是我的生成代码:

#ifndef GameOver_hpp
#define GameOver_hpp

#include <stdio.h>
#include "View.hpp"
#include "Button.hpp"
#include "GameView.hpp"
#include "State.hpp"

namespace kge{
  class View;
};

class GameOver: public kge::View{
private:
  sf::Text* _text;
  kge::Button* _restartButton;
  kge::Button* _exitButton;

  void restartFunction(void){

  }
public:
  GameOver(kge::Window* screen) : View(screen){
    int fontSize = 50;
    _text = new sf::Text();
    _text->setFont(kge::AssetManager::mainBundle().getFontNamed("mainfont"));
    _text->setString("Game Over");
    _text->setCharacterSize(fontSize);
    _text->setPosition(getCenterOfScreen().x-((9*fontSize)/2), 100);
    _text->setFillColor(sf::Color(255,0,0));

    _restartButton = new kge::Button(_window, "Restart");
    _restartButton->setPosition(getCenterOfScreen().x-((11*fontSize)/2), 300);

    _exitButton = new kge::Button(_window, "Quit");
    _exitButton->setPosition(getCenterOfScreen().x-((11*fontSize)/2), 500);

    _restartButton->callback = ([this](){
//      State::instance().currentView = new GameView(this->_window);
//      this->_window->setView(State::instance().currentView);
      puts("Restart");
    });

    _exitButton->callback = ([this](){
//      this->_window->close();
      puts("Restart");
    });


    this->addItemToView(_text);
    this->addItemToView(_restartButton);
    this->addItemToView(_exitButton);
  }

  void update(float td){
    _restartButton->update(td);
    _exitButton->update(td);

  }

  ~GameOver(){
    delete _text;
    delete _restartButton;
  }
};

#endif /* GameOver_hpp */

请注意,kge::View 只是一个自定义的 sf::Drawable 类(我如何创建自己的“ View ”)

编辑 2 按钮更新函数:

  void Button::update(float td){
    if(_clock.getElapsedTime().asMilliseconds() < 400) return;
    if(!sf::Mouse::isButtonPressed(sf::Mouse::Left)) return;
    if(mouseIsIn(*_buttonOutline, _window)){
      callback();
      _clock.restart();
    }
  }

请注意:_clock 是一个 sf::Clock,它私有(private)地存储在按钮类中。

最佳答案

问题已在聊天中解决。总而言之,@iProgram 发布的 mouseIsIn 函数没有正确检查碰撞,导致多个按钮同时触发。

原函数:

bool mouseIsIn(sf::RectangleShape shape, sf::RenderWindow* window){
    sf::FloatRect shapeBounds = shape.getGlobalBounds();
    sf::Vector2i mousePos = sf::Mouse::getPosition(*window);
    sf::FloatRect mouseRect = sf::FloatRect(mousePos.x, mousePos.y, mousePos.x+shapeBounds.width, mousePos.y+shapeBounds.height);
    return mouseRect.intersects(shapeBounds);
}

固定函数:

bool mouseIsIn(sf::RectangleShape shape, sf::RenderWindow* window){
    sf::FloatRect shapeBounds = shape.getGlobalBounds();
    sf::Vector2i mousePos = sf::Mouse::getPosition(*window);
    return shapeBounds.contains(mousePos.x, mousePos.y);
}

关于c++ - 为什么我的按钮类项目共享相同的 lambda 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55295508/

相关文章:

c++ - 在 C++ 中重用 vector

Javascript OOP/类 - 多个实例共享相同的数据

c++ - 编译一个使用 sfml 和 mingw 从 linux 移植到 windows 的 C++ 程序

c++ - 图标是 SFML 中的黑色方 block

c++ - vector resize() 自动填充

C++/Qt : passing variables to be changed in the class

c++ - 从数组构造

java - 检测未初始化对象的类型

python - 如何链接不同Python文件中的类(多框架)?将不同页面链接回 MenuPage?

c++ - 运行最基本的 sfml 应用程序时的性能问题