我和一些朋友正在使用Java制作一个自上而下的射击游戏,并希望将其设置为联机,我们已经建立了一个UDP套接字连接,但工作正常但我们不确定如何存储我们收到的数据客户。
目前我们正在使用一些哈希图来存储数据,例如我们有三个用于玩家跟踪的哈希图,游戏信息(玩家数量等)和子弹(子弹位置,谁开火等)。
但我确信除了哈希映射之外,必须有一种更安全的方式来存储这些数据,但不能确定是什么。
编辑 thx- Philipp(对不起,我花了这么长时间才得到一个不错的问题)
我对使用散列图来存储这些数据的担心是,有很多数据需要放入其中,我们当前正在使用单行来存储对象的所有数据,例如播放器hashmap中的一行将玩家ID作为键,使用字符串值来存储其他任何内容,例如" hp,xloc,yloc"。我们然后拆分使用。我似乎无法想到存储和检索数据的最有效方法。
很抱歉,如果这仍然没有意义。
我想我真正的问题是,是否有更高效的替代方案,或者如果hashmap是最好的方法?
由于
答案 0 :(得分:1)
正如您自己想出的那样,将游戏中每个实体的数据存储在一个字符串中并不是一个好主意。
每当需要关于它的信息时,你必须解析字符串,并且字符串解析不是很快,并且当每个实体的数据变得更复杂时,很容易变得非常复杂。
更好的方法是使用一组类变量为每个实体类型创建一个类,并使用它来存储每个实体的数据:
class Player {
public:
int positionX;
int positionY;
int lifes;
String name;
//...
}
(顺便说一下:一位经验丰富的面向对象的程序员会将这些变量声明为私有,并使用getter和setter方法来更改它们,但是现在不要走得那么远)
然后,您的哈希映射将存储此类的实例:
HashMap<Integer, Player> players;
设置这些很容易:
Player p = new Player();
p.positionX = 200;
p.positionY = 400;
p.lifes = 3;
p.name = "Ford Prefect";
players.put(42, p);
(顺便说一下:经验丰富的OOP程序员会使用构造函数)
您可以通过访问哈希映射来设置和获取每个玩家的变量:
players.get(42).positionX += 10; // move player 42 10 pixels to the right
答案 1 :(得分:1)
内存很好。除非您需要保留数据,否则不用担心。
然而,“然后我们拆分使用”是不正常。这是一种微观“优化”,实际上会更慢/更低效:没有,但痛苦和失去的时间就在这条路上。
我不知道您的具体设置,但请考虑一下:
class Player {
public Player (int playerId) {
this.playerId = playerId;
}
// ID during game - not permanent; for link-back to Hash key
public final int playerId;
// Add methods and fields as appropriate
String name;
int health;
// position, armour color, fairy dust, etc.
}
// How ids are "connected" to players:
// playerId -> Player
Map<Integer,Player> players = new HashMap..;
// When a player "connects"
int playerId = getUniqueIdForGameInstance();
Player player = new Player(playerId); // setup other information as required
players.add(player.playerId, player);
// On attack ..
int attackerId = getAttackerFromClient();
int targetId = getTargetFromClient();
Player attacker = players.get(attackerId);
Player target = players.get(targetId);
target.getWumped(attacker.wumpStength());
同样可以应用于游戏中的其他实体。请注意,Map用于查找给定特定ID的玩家,但Player类的实例保存有关玩家的信息。
通过电话查看ProtocolBuffers序列化。
答案 2 :(得分:0)
Hashmaps是一个不错的解决方案 - 它们是线程安全的,所以假设您没有10,000个用户一次访问您的网站,它们应该适合您。
但是,目前您的所有数据都存储在内存中。如果程序终止,这是一个问题。
我可以将最简单的建议用于将HashMaps写入文件。这是通过在类声明中添加Serializable
接口在Java中完成的 - 但是您不需要为HashMap执行此操作,因为它已经是Serializeable。 (您只需对已编写的存储在HashMap中的类执行此操作。)
然后只需将以下内容添加到main()方法中(从文件中读取):
try {
FileInputStream fis = new FileInputStream("Game.sav");
ObjectInputStream ois = new ObjectInputStream(fis);
HashMap<K,V> loadedGame = (HashMap<K,V>) ois.readObject();
} catch (Exception e) {
// Create new hash maps (no HashMap files found)
}
这是一个可以自行调用的saveGame()方法
try {
FileOutputStream fos = new FileOutputStream("Game.sav");
ObjectOutputStream oos = new ObjectOutputStream(fos);
o.writeObject(hashmapGameVariable);
o.close();
} catch (IOException ioe) {
ioe.printStackTrace(); // something went wrong, you may not have write premissions
}