- SFML Game Development By Example
- Raimondas Pupius
- 822字
- 2021-07-23 14:55:05
Implementing the window class
Now that we have our blueprint, let's begin actually building our window class. The entry and exit points seem as good a place as any to start with:
Window::Window(){ Setup("Window", sf::Vector2u(640,480)); } Window::Window(const std::string& l_title, const sf::Vector2u& l_size) { Setup(l_title,l_size); } Window::~Window(){ Destroy(); }
Both implementations of the constructor and destructor simply utilize the helper methods which we'll be implementing shortly. There's also a default constructor that takes no arguments and initializes some pre-set default values, which is not necessary, but it's convenient. With that said, let's take a look at the setup method:
void Window::Setup(const std::string l_title, const sf::Vector2u& l_size) { m_windowTitle = l_title; m_windowSize = l_size; m_isFullscreen = false; m_isDone = false; Create(); }
Once again, this is quite simple. As mentioned before, it initializes and keeps track of some of the window properties that will be passed to the constructor. Aside from that, it calls another method named Create
to break up the code even more, which is what we'll be implementing next in addition to the Destroy
method:
void Window::Create(){ auto style = (m_isFullscreen ? sf::Style::Fullscreen : sf::Style::Default); m_window.create({ m_windowSize.x, m_windowSize.y, 32 }, m_windowTitle, style); } void Window::Destroy(){ m_window.close(); }
Here, we introduce a new data type that SFML offers: sf::Uint32
. It gets stored inside the style
local variable, which is automatically deduced to said type by using the auto
keyword. It's simply an unsigned, fixed size integer type. In this particular case, we're using the 32-bit integer, although SFML offers both signed and unsigned types of 8, 16, and 32 bits. We use this value to hold the current style for a window using a ternary operator and assigning it to either the default or full screen styles of the window style enumeration. This is the full list of all possible window styles within SFML:

The mutually exclusive column simply denotes whether the style in question can be used with other styles in tandem. For example, it is possible to have a window with a title bar, resizable border, the maximize button, and a close button by combining two styles together using the bitwise or operator in C++:
auto style = sf::Style::Resize | sf::Style::Close;
If, however, a style is mutually exclusive, it cannot be used with any other styles in this way.
Once we have our style, we can simply pass it to the create
method of our window, in addition to the sf::VideoMode
type that gets constructed, using uniform initialization. It's that simple.
The destroy
method of our Window
class will simply close the window by invoking its close
method. It's important to note here that the closed window will have all of its attached resources destroyed, but you can still call its create
method again to re-create the window. Polling events and calling the display
method will still work if a window is closed. It will just have no effect.
Let's proceed in breaking up our once solid chunk of code by processing the events of the window in the appropriate update
method:
void Window::Update(){ sf::Event event; while(m_window.pollEvent(event)){ if(event.type == sf::Event::Closed){ m_isDone = true; } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::F5) { ToggleFullscreen(); } } }
It's the same drill as before, we're simply handling events. Instead of closing the window right off the bat, however, we simply flip the Boolean flag we keep around for checking if the window has been closed or not: m_isDone
. Since we're also interested in toggling between full screen and normal states of our window, we need to keep an eye out for another type of event: sf::Event::KeyPressed
. This event gets dispatched whenever a keyboard key is pressed down and it includes information about that key stored in the event.key
struct. For now, we're only interested in the code of the key being pressed, which we can then check against the sf::Keyboard
enumeration table. Upon receiving an event of an F5 key being pressed, we call the ToggleFullscreen
method, which is fairly simple to implement now that we have broken up the code into manageable sections:
void Window::ToggleFullscreen(){ m_isFullscreen = !m_isFullscreen; Destroy(); Create(); }
As you can see, the only thing we do here is invert the value of our Boolean class member, m_isFullscreen
, that keeps track of the window state. Afterwards, we need to destroy and re-create the window in order to make it honor our changes. Let's take a look at the drawing methods:
void Window::BeginDraw(){ m_window.clear(sf::Color::Black); } void Window::EndDraw(){ m_window.display(); }
Nothing new gets introduced here. We're simply wrapping the functionality of clearing and displaying in BeginDraw
and EndDraw
methods. All that's left now are the simple helper methods:
bool Window::IsDone(){ return m_isDone; } bool Window::IsFullscreen(){ return m_isFullscreen; } sf::Vector2u Window::GetWindowSize(){ return m_windowSize; } void Window::Draw(sf::Drawable&l_drawable){ m_window.draw(l_drawable); }
These basic methods provide the means for retrieving information about the window without giving too much control to anything outside the window class. For now, our window class is more than sufficient.
- 數據庫系統原理及MySQL應用教程(第2版)
- ExtGWT Rich Internet Application Cookbook
- Python數據分析入門與實戰
- C語言程序設計(第3版)
- SpringMVC+MyBatis快速開發與項目實戰
- JIRA 7 Administration Cookbook(Second Edition)
- 神經網絡編程實戰:Java語言實現(原書第2版)
- Mastering Rust
- Mastering JBoss Enterprise Application Platform 7
- Express Web Application Development
- Java Web開發詳解
- 執劍而舞:用代碼創作藝術
- 深入理解C指針
- Learning Modular Java Programming
- Troubleshooting Citrix XenApp?