SFML定义按钮控件

SFML自定义按钮控件

我们在开发游戏的过程中常常会涉及到按钮的设置,但是SFML不能像游戏引擎一样提供按钮控件,为了方便游戏开发,我们自定义一个按钮类,通过实例化这个类来方便地获得一个按钮。

定义按钮类

Button.h

#pragma onceclass Button
{//将需要用到Button的类定义为友员类,给app赋值friend class StartScene;friend class GameScene;friend class Menu;
public:Button():app(NULL),isActive(false),PreBehRel(false) {};bool isActive;//按钮是否活跃状态,这个后面会解释bool PreBehRel;//松开之前是否按下,这个后面会解释void setTextrue(String s);//设置贴图路径void setPosition(int x, int y);//位置void setScale(float x, float y);//大小void show();//显示按钮bool onClick(Event& e);//按钮响应Sprite s;//精灵
private:Texture t;//贴图RenderWindow* app;//在app窗口中显示按钮
};

类中方法的实现

Button.cpp

#include "Button.h"void Button::setTextrue(String s)
{this->t.loadFromFile(s);this->s.setTexture(this->t);
}void Button::setPosition(int x, int y)
{this->s.setPosition(x, y);
}void Button::setScale(float x, float y)
{this->s.setScale(x, y);
}bool Button::onClick(Event& e)
{if (!isActive) //如果按钮不是活跃状态(不显示),不响应return false;bool flag = false;FloatRect box = s.getGlobalBounds();//获取按钮的有效点击范围if (Mouse::getPosition(*app).x >= box.left && Mouse::getPosition(*app).x <= (box.left + box.width) && Mouse::getPosition(*app).y >= box.top && Mouse::getPosition(*app).y <= (box.top + box.height)){if (e.type == Event::MouseButtonReleased && e.key.code == Mouse::Left && PreBehRel){this->PreBehRel = false;//要先按下再松开才返回true,置于为什么要判断先按下,后面会讲flag = true;}elseflag = false;if (e.type == Event::MouseButtonPressed && e.key.code == Mouse::Left){this->s.setColor(Color(125, 125, 0, 255));//按钮按下时的颜色和不透明度this->PreBehRel = true;}elsethis->s.setColor(Color(125, 125, 0, 100));//鼠标指着按钮但未按下时的颜色和不透明度}elsethis->s.setColor(Color(255,255,255, 255));//默认状态的按钮颜色return flag;
}void Button::show()
{isActive = true;//若要显示,则为活跃状态(*app).draw(s);
}

部分变量的说明

(1)bool isActive:在由于我在判断鼠标是否在按钮里面是用的getGlobalBounds()方法,不管按钮是否被draw,只要设置了贴图精灵,都能获取按钮的响应范围,这就会导致按钮没有显示的情况下我在设置按钮的位置按下也会触发按钮点击事件,这就不合理,所以设置isActive布尔变量来记录按钮是否活跃(被绘制),所以在调用Button的程序里要把isActive重置为false,在绘制按钮时再设为true。
(2)bool PreBehRel:这个是为了防止场景切换时在同一位置两个场景都有按钮的情况下两个按钮的点击都被触发,本来按照sfml的MouseButtonReleased应该是鼠标松开后返回true,也就是说鼠标点击一下只会返回一次Release,但是在实现中发现如果一个按钮被点击后就在同一位置绘制另一个按钮,这回导致两个按钮的MouseButtonReleased都被返回为true,置于为什么会这样我也不知道,所以设置PreBehRel布尔变量来判断鼠标松开前是否被按下,从而避免了这一问题。另外也是防止鼠标在按钮外面按下不放然后移到按钮里面再松开导致触发按钮事件。

如何使用Button

举例代码如下

RenderWindow app;
Button bt;
bt.app=&app;
while(app.isOpen())
{Event e;while(app.pollEvent(e)){if(e.type==Event::Closed())app.close();}bt.isActive=false;bt.show();if(bt.onClick(e)){cout<<"clicked!";}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部