我想为我正在进行的游戏实现一个检查点系统,为此我需要复制一个级别内的所有可变对象,以便创建一个级别的独立副本.在一个简化的例子中,我的类看起来像这样:
public class GameObject
{
...
private Level level;
...
}
public class Level
{
...
private List<GameObject> gameObjects;
...
}
Run Code Online (Sandbox Code Playgroud)
但是有一个问题:当我想要复制一个级别及其对象时,引用变得不一致.例如,我可以深度复制我的Level-instance并深度复制所有gameObjects.但是当我这样做时,GameObject中的Level-reference不再指向"正确"(新)级别.在这种情况下,我可以为每个对象调用一个方法并重置其级别.但随着越来越多类型的对象被包含,这将变得越来越复杂,因为对象可能或可能没有自己创建的对象集,然后这些引用也必须更新等等.
是否存在类似于这种情况的设计模式,或任何特定于Java的问题,使这个问题变得更容易?
编辑
我刚才有一个想法:如何为每个GameObject创建一些包装类,如下所示:
public class GameObjectWrapper
{
...
private long gameObjectID;
private Level level;
...
}
Run Code Online (Sandbox Code Playgroud)
这将作为对需要引用的所有对象的引用.每个GameObject都会获得一个唯一的id,而level将有一个地图将每个id链接到一个真实的GameObject(类似的东西GameObject Level.getObject(long id)
).虽然这可能会奏效,但我仍然觉得必须有更好的解决方案.
编辑:进一步澄清
似乎我没有让我的问题足够清楚,所以我将简化并概括一点:
我有两个示例对象(objectA
和objectB
):objectA
包含对它的引用objectB
并objectB
包含对它的引用objectA
.
像这样的东西:
public class MyObject
{
private MyObject partner;
...
public MyObject shallowCopy()
{
return new MyObject(partner);
}
}
Run Code Online (Sandbox Code Playgroud)
我想复制两者.使用浅拷贝,我得到两个新对象:newObjectA
和newObjectB
.然而,newObjectA
存储的引用(应该指向newObjectB
)仍然指向原始引用,objectB
反之亦然.
MyObject objectA = new MyObject(), objectB = new MyObject();
objectA.setPartner(objectB);
objectB.setPartner(objectA);
MyObject newObjectA = objectA.copy(); //newObjectA's partner now is objectB (instead of newObjectB)
MyObject newObjectB = objectB.copy(); //newObjectB's partner now is objectA (instead of newObjectA)
Run Code Online (Sandbox Code Playgroud)
现在,我可以 "只是"遍历所有对象并将旧对象映射到新对象,但这对我来说似乎很慢而且太复杂了.解决此问题的最简单,最有效的方法是什么?
注意:我考虑将此发布到gamedev.stackexchange.com,但我发现这更像是一个编程和设计特定问题,而不是游戏开发特定问题.
如果您只是复制Level
对象并希望其列表中的引用指向新副本,那么您不能在复制方法中循环遍历它们吗?
像这样的东西:
class Level {
List<GameObject> gameObjects;
Level copy() {
Level level = new Level();
level.gameObjects = new ArrayList<>(gameObjects.size());
for (GameObject gameObject : gameObjects) {
level.gameObjects.add(gameObject.copyWithReference(level));
}
return level;
}
}
class GameObject {
Level level;
GameObject copyWithReference(Level level) {
GameObject gameObject = new GameObject();
gameObject.level = level;
return gameObject;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
您可以有一个容器用于gameObjects
:
class GameObjectSet {
Level level;
List<GameObject> gameObjects;
GameObjectSet copy(Level newLevel) {
GameObjectSet gameObjectSet = new GameObjectSet();
gameObjectSet.level = newLevel;
// copy all gameObjects and make them point to new gameObjectSet
return gameObjectSet;
}
}
Run Code Online (Sandbox Code Playgroud)
GameObjectSet
现在您将在课堂上Level
和课堂上都有对 a 的引用GameObject
。
归档时间: |
|
查看次数: |
141 次 |
最近记录: |