Sfml как сделать кнопку
Перейти к содержимому

Sfml как сделать кнопку

  • автор:

How to create a button in SFML?

How can I get clickable buttons working in SFML? I’ve failed figuring it out on my own. At first I tried just putting in text and then I tried an image for the Exit button. Neither of them work in the sf::Event::MouseMoved event. I want the exit button to highlight a different color when I mouse over it but it just flickers every time the mouse moves whether its in the coordinates or not. Also, doing a sf::FloatRect = exitButtonImage.getRect(); seems to not work either.

2 Answers 2

The first thing to note, is that you have a ; after an if statement, before the code for the true condition. This means that the if line is useless, and that code for the true condition will always be executed.

Removing that semi-column will be our first step.

The second thing to note is that you don’t need all that code for the if condition. SFML offers a contains method on the rectangle which returns true if the vector passed is in the rectangle. This really reduces the code and improves readability and reliability.

The third thing to note is that the window.draw( exitButtonImage ); is useless in that if( isOver ) condition because you’ll draw it anyway at the end of the while.

The fourth thing to note is that, with the previous changes, the button will become ‘red’ only when you actually move the mouse over it. We need a way to preserve the state. This is nice because.

The fifth thing to note is that the code is doing a very bad usage of memory allocation and disk access. The creation of your buttons could be done only once, with the objects reused every frame, instead of being recreated every frame.

We’ll take the text and image creation outside of the while ( window.isOpen() ) . This will allow us to keep the state of the exitButtonImage from frame to frame. If the mouse moves over the exit button, it will set it to ‘red’, and if we stop moving the mouse, no more mouse event are received, so the last state stays in place. Nice, our button stays put!

But that causes another bug: the button does not get back to its ‘pristine’ state when we mouse-out.

To fix that, we simply add an else to the ‘mouse move and mouse is over the button’ if : exitButtonImage.setColor( sf::Color( 255, 255, 255 ) ); . This will put the button in it’s original state.

With that, you only need to detect the ‘click’ event, and you’ll have something usable.

Note that this is a bit of a hackish way of doing things as you’ll change the colour of the button every frame the mouse moves, whether you actually need to change it or not, which may take up more resources than needed. I think in your situation it’s fine to go that way, though; you can ignore this small issue for now.

That’s basically what I had to say about your code 🙂

For your convenience, here is the code I think you wanted to write:

This only manages the exit button that you wanted to create, but a lot of programming is generally done by monkey-see-monkey-do, so I assume you’ll be able to adapt the code.

I’ll end this answer by noting that it might not be the most optimal way of doing what you want, architecturally speaking, but since you’re just starting, you’ll find ways to improve your software as you see fit.

Игровое меню SFML C++

Меню один из неотъемлемых элементов игровой разработки. Благодаря ему мы можем насытить игру множественными разделами такими важными как настройка игры или смена пользователя. Без игрового меню, проект выглядит путешествием через туннель, в котором есть вход и есть выход, а между ними игровой процесс без права выбора.

В этой статье я познакомлю Вас с моей разработкой простого игрового меню на базе мультимедийной библиотеки SFML и языка программирования С++.

Инструментарий разработчика

Перед тем как я познакомлю Вас с прототипом моего игрового меню. Я обязан посвятить Вас в перечень софта, который использовался мною для данной разработки.

Для разработки кода я использовал:

Интегрированную среду разработки Visual Studio 2022 c установленной рабочей нагрузкой «Разработка классических приложений на С++».

Начинаем работу

Пишем класс игрового меню

Более подробную инструкцию вы можете получить посмотрев видео «Игровое меню SFML C++ «.

Name already in use

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

SFML GUI Button class example

special note Did not distribute font with the example — it can be found here: http://www.dafont.com/continuum.font

This tiny project, while written long ago, originally depended on the Thor library for SFML. You may find support for features out of the box via the Thor repo. However, as this was originally written in 2014, things may have changed in the APIs for either SFML or Thor. I may or may not update the repo if I find the time to investigate, but this should outline the issue well enough for anyone curious enough to track down and troubleshoot any errors when building.

How to Create Simple Buttons for your SFML Game

Ah, yes, the button. The "Holy Grail" of GUI development. Without it, there is little you can accomplish. Whether it is a simple hyperlink-like clickable piece of text, or a full-on GUI-licious button you need something like this for your call-to-action. In this tutorial, I'll step you through the implementation of a simple reusable button component for your games. The code for this tutorial can be found on github. Please be advised that this project depends upon the Thor library for SFML. At the time this tutorial was written, the example was known to compile on Windows using some version of GCC. As time goes on and things get dusty, there may be some growing pains as APIs change and the C++ standards are revised.

First, we will create the class definition (button.hpp). It consists of a default constructor, an "I know what I'm doing here, so give me a real constructor" constructor, an enum for the styles of buttons we are supporting out of the box, an enum for the button's internal state, lots of housekeeping methods and variables for keeping track of states and returning the button's properties, and a partridge in a pear tree. Here is the class definition:

There really isn't anything that exciting about any of this. We have many methods that are self-describing. Most of them set or get properties of either the sf::Text m_text or the sf::ConvexShape m_button. We side-step what is really going on under the covers, because whoever uses this class isn't likely to care — they just want it to work. So, we create methods to set button properties, but we hide things like event handling and instead simply give them public access to gui::Button::getState(), which returns an sf::Uint32 that maps to the state enum defined in the namespace gui. It is entirely up to the user of the button to use this value to their own advantage — or peril. But at least we clearly delineated what those values wil always be. They have the flexibility to implement reactionary content (such as the "pop-over" you frequently see on the interwebz that is used primarily to give you information about the object you clicked on or hovered over) or generate some action in response to a click. Trying to add such functionality to the button itself would most likely result in a class that is impossible to maintain or incredibly difficult to use. Finally, it is important to note, we inherited from sf::Drawable, and thus, need to override its sf::Drawable::draw(sf::RenderTarget& target, sf::RenderState states) const method. Easy as pie, but this is an important detail if you want people to easily understand your button implementation.

Without further adieu, here is the complete implementation of our button class (button.cpp):

Although the user of the button class need only pass in a reference to an sf::Event and an sf::RenderWindow, there is still quite a bit going on in the gui::button::update() method. Every property that is set by the user is updated in the switch(m_style) statement. There may be a way to avoid this or implement it in a cleaner way, but I have not noticed an impact performance-wise, so I have no reason to change it. Perhaps setting some flags that indicate that a setting was changed would cut down on the number of function calls, but implementing this type of functionality seemed overly complicated for the purposes it is serving.

On the upside, the local variable bool mouseInButton cuts down on a lot of boilerplate for detecting mouseovers for the button, and makes the rest of the related code much easier to follow. Now we could read it out loud and not sound too deranged. It simply reads, if the user moves the mouse and it is inside the button, the state is hovering — else it is normal. Then we check for clicks the in the same manner — if the user clicks and mouseInButton is true we set the state to clicked — else it is normal. We also check for mouse button release and use similar logic there. The rest is cake. We simply set up a switch statement for m_btnstate, which was set according to mouse events, and set the properties of the m_text and m_button elements according to the settings set by the user or the canned style we provided via the m_style member variable.

Finally, we override the pure virtual function sf::Drawable::draw so that we can draw our wonderful button with a simple call to window.draw(button) — or whatever the button happens to be instantiated as. Nifty, and pretty clean on the part of the user. Let's see a simple, minimal, and complete example of using our new button class:

Enjoy button-making bliss — hack as you see fit. There are some obvious improvements to be made — perhaps an sf::Sprite used as a button icon — or you could even use an icon set from some popular web frameworks, many of them offer their resources with a pretty promiscuous license. In many cases they have already done the research to determine which icons drive user behavior effectively for a particular call-to-action.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *