我目前正在开发一款用Java编写的游戏。目前,我一直在寻找一种简单的方法来存储我的游戏对象(玩家、敌人等等…),这样我就可以通过它们的坐标访问它们,同时仍然可以轻松地移动它们。
我已经尝试过多维数组,这很好,但不会让我轻易移动对象。每次移动数组中的对象时,我都必须对其进行物理移动。
然后我尝试了"普通"数组,它可以让你轻松地移动东西,只需增加对象的x、y或z值,但不允许我在不迭代整个数组的情况下通过坐标访问对象。
现在,我正试图找到一个折衷方案,让我两者兼得。
提前感谢,//265
简单的解决方案是同时使用两个表单。将坐标存储在GameObject
实例中,但同时将其缓存在三维阵列中。数组最好封装在一个提供更新和查询方法的对象中
public class GameObjectDatabase implements LocationChangeListener {
private int [] [] [] data;
private Set<GameObjects> objects;
...
public GameObject gameObjectAt(int x, int y, int z) {
return data[x][y][z];
}
@Override
public void positionUpdated(GameObject obj, int oldX, int oldY, int oldZ) {
....
}
}
为什么是侦听器和被重写的方法?因为更新这些数据实际上不是GameObject
的工作,而是GameObjectDatabase
的责任。因此,理想情况下,GameObject
应该允许在Set
中注册侦听器,并在每次位置更改时调用其positionUpdated
方法。
所有有位置的游戏对象(玩家、敌人等)都应该有一个对其位置的内部引用,例如;
class Position {
int x;
int y;
}
interface Positionable {
Position getPosition();
void setPosition(int x, int y, GameArea area);
}
class Player implements Positionable {
//stuff
}
class Enemy implements Positionable {
//stuff
}
然后你可以有一个类来代表你的游戏区域;
class GameArea {
Positionable[][] grid;
List<Positionable> gameObjects;
public Positionable getByLocation(int x, int y) {
return grid[x][y];
}
public void setAtLocation(int x, int y, Positionable p) {
grid[x][y] = p;
}
public List<Positionable> getAll() {
return gameObjects;
}
}
这允许您按位置访问并迭代所有对象。当游戏对象移动时,它需要在内部更新其位置并显式更新GameArea
,如下面的示例setPosition()
实现所示。
void setPosition(int x, int y, GameArea area) {
area.setAtLocation(this.x, this.y, null);
area.setAtLocation(x, y, this);
this.x = x;
this.y = y;
}