【问题标题】:Using object outside class在类外使用对象
【发布时间】:2023-03-26 13:17:01
【问题描述】:

我正在尝试使用 SFML 创建一些包含纹理和精灵的类。 当我在我的类的 SFML 库中创建类对象时 - 我不能在 main.xml 中使用该对象。 我想知道如何在 main 中显示精灵(例如):

class MainMenu
{
   public:
      int DrawMenu(){
         sf::Texture texture;
         if (!texture.loadFromFile("idle.png"))
            return EXIT_FAILURE;
         sf::Sprite spritemenu(texture);
         return 0;
      }

};

int main()
{
   // Create the main window
   sf::RenderWindow app(sf::VideoMode(800, 600), "SFML window");

   // Load a sprite to display
   sf::Texture texture;
   if (!texture.loadFromFile("cb.bmp"))
      return EXIT_FAILURE;
   sf::Sprite sprite(texture);

   MainMenu menu;
   // Start the game loop
   while (app.isOpen())
   {
      // Process events
      sf::Event event;
      while (app.pollEvent(event))
      {
         // Close window : exit
         if (event.type == sf::Event::Closed)
            app.close();
      }

      // Clear screen
      app.clear();

      // Draw the sprite
      app.draw(sprite);

      menu.DrawMenu();
      app.draw(spritemenu);

      // Update the window
      app.display();
   }

   return EXIT_SUCCESS;
}

【问题讨论】:

  • 请记住,当 DrawMenu 完成时,局部变量会超出范围。也许你想要类成员变量而不是局部变量(所以它们在 DrawMenu 完成后存在)?
  • 是的,当然。如何让它工作?

标签: c++ class sfml


【解决方案1】:

您的DrawMenu 函数名称是lying。它不绘制任何东西。它加载纹理和精灵。

DrawMenu 应该只是绘制菜单精灵:

void DrawMenu(sf::RenderWindow& window) { // window = where to draw the menu
   window.draw(spritemenu);
}

现在你在哪里加载spritemenu?它在MainMenu 的生命周期内保持不变,因此它自然应该在MainMenu构造函数 中实例化:

class MainMenu
{
   public:
      MainMenu() {
         if (!texture.loadFromFile("cb.bmp"))
            abort(); // or throw exception
         spritemenu.setTexture(texture); // "initialize" spritemenu with texture
      }
   …
   private:
      sf::Texture texture;   // Store these as member data, so they will be
      sf::Sprite spritemenu; // kept alive through the lifetime of MainMenu.
};

现在当您执行MainMenu menu; 时,纹理和精灵将被初始化一次,而不是每次您调用绘图函数时。

当您需要绘制menu 时,只需调用menu.DrawMenu(app); 而不是menu.DrawMenu(); app.draw(spritemenu);

【讨论】:

    【解决方案2】:

    最好的方法可能是将app 作为参数传递给DrawMenu,如下所示:

    class MainMenu {
    public:
        int DrawMenu(sf::RenderWindow& app){
            sf::Texture texture;
            if(!texture.loadFromFile("idle.png"))
                return EXIT_FAILURE;
            sf::Sprite spritemenu(texture);
            app.draw(spritemenu);
            return 0;
        }
    };
    

    然后调用menu.DrawMenu(app) 而不是menu.DrawMenu()


    请注意,从main() 以外的任何函数返回EXIT_FAILURE 是没有意义的;我建议改为抛出异常。

    此外,每次绘制菜单时都重新加载菜单很愚蠢。我建议将加载移动到 MainMenu 构造函数。

    【讨论】:

    • 请注意,您的代码将无法编译,因为您从 void 函数返回 int(我会修复它,但不确定您是否故意选择 void 返回来备份您的关于抛出异常的一点)
    • 最初我更改了代码以支持另外两个 cmets。然后我改变了主意,但忘了把返回类型放回去。
    猜你喜欢
    • 1970-01-01
    • 2019-03-08
    • 2018-11-30
    • 2018-08-26
    • 1970-01-01
    • 2015-11-27
    • 2020-06-16
    • 2018-01-06
    • 2014-01-26
    相关资源
    最近更新 更多