【问题标题】:SFML - sf::RenderWindow, dividing filesSFML - sf::RenderWindow,分割文件
【发布时间】:2016-01-06 01:36:08
【问题描述】:

所以这可能是一些琐碎的事情,但我真的需要知道为什么它会以这种方式发生以及我该如何改变它。

所以我今天开始学习 SFML,我正在阅读 SFML 游戏开发电子书,看到了非常有趣且编写良好的代码。我浏览了有关 SFML 的教程并开始学习语言,因为我了解了它应该如何工作的一般概念。

所以我想记住新的关键字、构造函数、方法,同时也让我的代码井井有条 - 使用我学到的东西来保持它的整洁和易于编辑、调试。

我的第一个代码是显示 Window,我以两种方式创建了相同的代码,通常将所有内容都放在 main 函数中并分开。问题是,只要我不关闭它,就会显示第一个窗口,而第二个窗口的显示时间少于第二个,并且程序正在关闭。

这可能是因为在我打开它之后立即调用析构函数并添加更多函数以保持对象忙碌是一种可行的方法,但是我想了解它。这是我在学习目标编程时不太了解的最后一件事。对象的工作方式。在我创建它们之后,我将它们用于某些任务,但是当我完成它们时,它们被删除了,有时我又需要它们。我只是想了解它是如何工作的,并找到真正简单快捷的修复/想法,让它在我想要的时候工作。

代码:

第一个程序:

#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();
        }
    }
}

第二个节目:

ma​​in.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;

};

【问题讨论】:

    标签: c++ sfml


    【解决方案1】:
    Game::Game()
    {
        sf::RenderWindow mainWindow(sf::VideoMode(800,600),"Main Window");
    }
    

    在你的构造函数中,你正在创建一个新的RenderWindow 对象,一旦构造函数退出,它就会立即被销毁。您要做的是初始化RenderWindow,它是您班级的成员。您可以通过以下两种方式之一执行此操作,或者使用成员初始值设定项列表中的 RenderWindow 构造函数:

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

    或者在构造函数体中调用create函数如下:

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

    【讨论】:

    • 感谢您的回答:)
    【解决方案2】:

    你需要改变这个:

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

    到这里:

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

    在第一个示例中,您在构造函数中创建了一个sf::RenderWindow,然后立即将其销毁,而在第二个示例中,您正在初始化成员变量版本,这将保持您的窗口只要Game 包含它的对象不会被销毁(或者只要您不手动销毁窗口)。

    【讨论】:

    • 哦,原来是我看的书上写的,只是没看懂。你的解释让我明白了。非常感谢!
    【解决方案3】:

    您的第二个程序应该使用一个小的更改。

    您已经有一个名为 mainWindow 的 RenderWindow 类型的变量。您必须使用 mainWindow 中的 create() 函数,而不是按照您的方式创建它。

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

    只是一个提示,通常您不希望将 isOpen() 用于游戏循环。我建议您查看枚举类。

    这是一个很棒的视频,介绍了如何使用它们。

    link

    【讨论】:

    • 谢谢,我会检查的。为什么我不应该使用 isOpen() ?我的意思是,我在实际创建 SFML 库的人的代码中看到了这一点,那么使用它真的有什么不好的理由吗?我没有学到很多关于枚举的知识,我上了一堂课,有时将它用于大学项目,但我发现对于我现在正在编写的较小程序来说没有必要,这样我就完全忘记了在全部。你能帮我推理一下,并举一些例子,它实际上可以节省你一些时间/使代码更容易阅读/编辑吗?
    • 例如。你知道有多少游戏可以通过按 alt+f4 来关闭窗口吗?使用 Enum 类,您可以定义游戏的状态,例如 - MainMenu、GameStart、GameClose、Options 以及您在游戏中可能拥有的许多其他内容,并且根据用户所做的事情,您只需更改枚举对象的状态。这是一个非常简单和有用的概念。而且它是干净的代码,所以如果用户按下 alt+f4,您可以将枚举对象更改为等于 gameClose。保持干净整洁。
    • 好的,因此更改此行使其工作。你能告诉我为什么会这样吗?
    • 因为您正在从先前存在的窗口(您在 .h 文件中创建的窗口)重新创建另一个窗口。那不是你想要的。你想初始化你第一次在 .h 文件中创建的那个,以便你可以在其他功能中使用它。
    • alt+f4 向窗口发送关闭事件。所以它会通过检查isOpen()来关闭。
    猜你喜欢
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多