1. ホーム
  2. c++

[解決済み] sfmlの派生クラスでテクスチャを一度初期化する

2022-02-25 05:05:27

質問

最近、テクスチャを使ったSFMLの演習を試みています。しかし、いくつかの問題に遭遇しました。SFMLのサイトでは、テクスチャを使うにはスプライトを更新するのが一番効率的だと書かれています。そうでないと、メモリを大量に消費してしまいます。ベースクラスが1つあり、そこから派生したクラスが2つあります。どのように私の texture この変数があれば、派生クラスはそのスプライトを使用することができますか?テクスチャを初期化するために Base というのも、1つのコンストラクタを2回呼び出すのはナンセンスだからです。というのも、私はステートパターンを使っていて、動的に割り当てられるオブジェクトを大量に生成しているからだ。

#include <iostream>

class Base
{
protected:
    sf::Texture texture; //How to initialize this?
    sf::Sprite sprite;
public:
    Base();
};

class Derived1 : public Base
{
public:
    Derived1()
    {
        sprite.setTexture(texture);
    }
};

class Derived2 : public Base
{
public:
    Derived2()
    {
        sprite.setTexture(texture);
    }
};

解決方法は?

フライウェイトパターン

<ブロッククオート

SFMLのサイトによると、テクスチャを最も効率的に使う方法は、スプライトを更新することだそうです。そうでないと、プログラムが大量のメモリを消費する可能性があります。

そうです、この関係で sf::Spritesf::Texture フライウェイトパターン 構造的なデザインパターンである。

について sf::Texture は、一種の ヘビー級 オブジェクトのデータは、可能な限り共有し、メモリを節約したい。また sf::Sprite フライ級 オブジェクトと、複数の sf::Sprite オブジェクトは、同じ sf::Texture オブジェクトを作成し、そのデータを共有することができます。

sf::Sprite は、参照するテクスチャの特定の用途に特化した情報(例えば、テクスチャの位置、回転、サイズなど)のみを含みます。 外部状態 . また sf::Texture オブジェクトはデータ(つまりテクスチャ画像そのもの)を含み、複数の sf::Sprite オブジェクトを作成します。 固有状態 が共有する、すべての sf::Sprite を参照するオブジェクトは、同じ sf::Texture .

SFML ライブラリでは、このパターンが sf::Text / sf::Fontsf::Sound / sf::SoundBuffer .


フライ級をあきらめない

上記で公開されたパターンを念頭に置きながら、デザインもそれに倣ってみてはいかがでしょうか。

class Base {
public:
    Base(const sf::Texture& texture): sprite(texture) {}
protected:
    sf::Sprite sprite;
};

class Derived: public Base {
public:
    Derived(const sf::Texture& texture): Base(texture) {}
    // ...
};

sprite のデータメンバが初期化されます。 sf::Texture コンストラクタに参照渡しされ、複数の BaseDerived オブジェクトは、同じ sf::Texture .

例として

sf::Texture myTexture;
myTexture.loadFromFile("myImageFile.png");

Base b1(myTexture), b2(myTexture);
Derived d1(myTexture), d2(myTexture);

b1 , b2 , d1d2 はすべて同じ sf::Texture インスタンス myTexture :

もちろん、これらのオブジェクトはいずれも myTexture .