2016-01-06 4 views
0

, так что это, вероятно, что-то тривальное, но мне действительно нужно знать, почему это происходит так, как это происходит, и как я могу его изменить.SFML - sf :: RenderWindow, деля файлы

Итак, я начал изучать SFML сегодня, и я читал SFML Game Development ebook и видел очень интересный и хорошо написанный код. Я прошел учебники по SFML и начал изучать язык, поскольку я понял общее представление о том, как он должен работать.

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

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

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

Код:

Первая программа:

#include <SFML/Graphics.hpp> 

int main() 
{ 
    sf::RenderWindow mainWindow(sf::VideoMode(800,600),"Main Window"); 

    while(mainWindow.isOpen()) 
    { 
     sf::Event openEvent; 
     while(mainWindow.pollEvent(openEvent)) 
     { 
      switch(openEvent.type) 
      { 
       case sf::Event::Closed: 
       mainWindow.close(); 
       break; 
      } 
      mainWindow.clear(); 
      mainWindow.display(); 
     } 
    } 
} 

Вторая программа:

main.cpp

#include <SFML/Graphics.hpp> 
#include "Game.cpp" 

int main() 
{ 
    Game game; 
    game.run(); 
} 

Game.cpp

#include "Game.h" 

    Game::Game() 
    { 
     sf::RenderWindow mainWindow(sf::VideoMode(800,600),"Main Window"); 
    } 

    void Game::run() 
    { 
     while(mainWindow.isOpen()) 
     { 
      sf::Event openEvent; 
      while(mainWindow.pollEvent(openEvent)) 
      { 
       switch(openEvent.type) 
       { 
        case sf::Event::Closed: 
        mainWindow.close(); 
        break; 
       } 
      } 
      mainWindow.clear(); 
      mainWindow.display(); 
     } 
    } 

Game.h

class Game 
{ 
    public: 
    Game(); 
    void run(); 

    private: 
    sf::RenderWindow mainWindow; 

}; 

ответ

2
Game::Game() 
{ 
    sf::RenderWindow mainWindow(sf::VideoMode(800,600),"Main Window"); 
} 

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

Game::Game() 
    :mainWindow(sf::VideoMode(800,600),"Main Window") 
{} 

Или вызов функции создания в теле конструктора.

Game::Game() 
{ 
    mainWindow.create(sf::VideoMode(800,600),"Main Window); 
} 
+0

Спасибо за ответ :) – Advent

1

Ваша вторая программа должна работать с одним небольшими изменениями.

У вас уже есть переменная с именем mainWindow типа RenderWindow. Вместо того, чтобы создавать его так, как вы это делаете, вам нужно будет использовать функцию create() в mainWindow.

Game::Game() 
{ 
    mainWindow.create(sf::VideoMode(800,600),"Main Window"); 
} 

Только совет, как правило, вы не хотите использовать isOpen() для игрового цикла. Я рекомендую вам посмотреть классы enum.

Вот отличное видео, объясняющее, как вы будете их использовать.

link

+0

Спасибо, я проверю. Почему я не должен использовать isOpen()? Я имею в виду, что я видел это в коде людей, которые фактически создали библиотеку SFML, так что действительно есть причина, почему это плохо использовать? Я не много узнал об переписках, я сделал один урок об этом и иногда использовал его для проектов в колледже, но я не счел нужным делать небольшие программы, которые я писал сейчас, и таким образом я полностью забыл об использовании перечислений в все. Не могли бы вы мне помочь, рассудив об этом и давая несколько примеров, где это на самом деле экономит ваше время/упрощает чтение и редактирование кода? – Advent

+0

Ну, например. Вы знаете, как во многих играх вы можете закрыть окно, нажав alt + f4? Используя классы Enum, вы можете определить состояние игр, таких как - MainMenu, GameStart, GameClose, Options и многое другое, что может быть у вас в игре, и в зависимости от того, что пользователь просто изменил состояние вашего объекта enum. Это очень простая и полезная концепция. И это чистый код, поэтому, если пользователь нажимает alt + f4, вы можете просто изменить объект перечисления равным gameClose. Сохраняет это красиво и чисто. –

+0

Хорошо, поэтому изменение этой строки заставило ее работать. Не могли бы вы сказать мне, почему это работает? – Advent

2

Вы должны изменить это:

Game::Game() 
{ 
    sf::RenderWindow mainWindow(sf::VideoMode(800,600),"Main Window"); 
} 

Для этого:

Game::Game() : mainWindow(sf::VideoMode(800,600),"Main Window"); 
{ 

} 

В первом примере, вы создаете sf::RenderWindow внутри конструктора, а затем уничтожить его немедленно, тогда как во втором примере вы инициализируете версию-член-переменную, которая будет сохранять ваше окно, пока объект Game, содержащий его, не будет уничтожен (или так долго так как вы вручную не уничтожаете окно).

+1

О, точно так оно и было написано в книге, которую я читал, я просто не понял ее полностью. Ваши объяснения дали мне понять. Большое спасибо ! – Advent

Смежные вопросы