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

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

我试图在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类(我如何创建自己的“视图”)

编辑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。

c++ class sfml
1个回答
1
投票

这个问题在聊天中解决了。总而言之,@ 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);
}
© www.soinside.com 2019 - 2024. All rights reserved.