官术网_书友最值得收藏!

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.

主站蜘蛛池模板: 杭锦后旗| 丰县| 同江市| 太谷县| 嘉鱼县| 岑巩县| 芜湖市| 扎兰屯市| 兴安县| 瑞安市| 阿拉善盟| 新兴县| 永靖县| 长海县| 上高县| 巴楚县| 定襄县| 吴江市| 新安县| 尉氏县| 凌云县| 惠来县| 项城市| 康马县| 六枝特区| 文昌市| 东乡县| 普兰店市| 酉阳| 北碚区| 襄樊市| 青阳县| 乃东县| 溧阳市| 渑池县| 恩平市| 纳雍县| 诸暨市| 石城县| 陆良县| 沐川县|