ゲームエンジンにオブジェクトのクローンを実装するための探求で、少しつまずきました。私の目標は、クラスが特別な扱いを必要としない限り、クラスごとに維持する必要のないクローンシステムを作成することです。
私のゲームエンジンのセットアップは、Texture2Dの形式でいくつかの画像データを含む基本クラスObject2Dを中心に展開しています。長い話は、Texture2Dを含むSpriteを含むDisplayObjectが含まれているということです。当然、「Player」、「Enemy」、「Projectile」などの他のクラスはすべて、基本的なObject2Dクラスから派生します。
残念ながら、XNAのTexture2Dクラスはシリアル化できないことがわかりました。これは理にかなっています。メモリ内のテクスチャデータを意地悪に複製したくないからです。
これは私にとってジレンマを生み出します。オブジェクトのクローンを作成するためにディープクローンメソッドを使用していましたが、シリアル化できないため、それを行うことができなくなりました。Texture2D [NonSerializable]をマークしようとしましたが、クローンのテクスチャがnullであるため、描画しようとすると問題が発生します。クローン作成後に割り当てることができる隠されたトリックを見つけることができませんでした(ある種の「onClone()」メソッドのように)。
だから私はこれをやろうと思った。一般的にディープクローンを作成できないオブジェクトの場合、clone()メソッドを指定できる「SpecialClone」インターフェイスを実装します。
ただし、一般的にディープクローンを作成できないクラスは基本クラスであるため、クラスごとにクローンメソッドを作成するという最初の段階に戻ります。
public static T clone<T>(T obj) {
if (obj == null) return default(T);
if (!typeof(T).IsSerializable) {
if (obj is SpecialClone) {
object obj2 = ((SpecialClone)obj).clone();
return (T)obj2;
} else {
throw new ArgumentException("Object type is not serializable.", "obj type: " + Type.GetTypeHandle(obj));
}
} else {
return deepClone(obj);
}
}
public static T deepClone<T>(T obj) {
if (obj == null) return default(T);
if (typeof(T).IsSerializable) {
try {
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
T obj2 = (T)bf.Deserialize(ms);
ms.Dispose();
return obj2;
}
catch (Exception e) {
Console.WriteLine(e);
return default(T);
}
} else {
Console.WriteLine(typeof(T) + " is not marked as serializable!");
return default(T);
}
}
私はまだC#が得意ではないので、使用できるトリックが不足しているかどうか、またはこれが本当にこの問題に対処する方法であるかどうかはわかりません。このクローン作成の主な目的はObject2Dタイプを対象としているため、作成する新しいサブクラスごとにクローンメソッドを作成する必要があるのは非常に困難です。
これを回避する方法はありますか?