在服务器端存储Java多层自顶向下游戏数据的最佳方法

在服务器端存储Java多层自顶向下游戏数据的最佳方法,java,multiplayer,2d-games,Java,Multiplayer,2d Games,我和一些朋友正在用Java制作一个自上而下的解决方案,并希望使其在线。我们已经建立了一个UDP套接字连接,该连接工作正常,但我们不确定如何存储从客户端接收的数据 目前,我们正在使用许多散列图来存储数据,例如,我们有三个散列图用于玩家跟踪、游戏信息(玩家数量等)和子弹(子弹位置、射击者等) 但我确信,除了hashmaps之外,必须有一种更好、更安全的方式来存储这些数据,但不确定是什么 编辑thx-Philipp(很抱歉花了这么长时间才提出了一个不太像样的问题) 我对使用hashmaps存储这些数据

我和一些朋友正在用Java制作一个自上而下的解决方案,并希望使其在线。我们已经建立了一个UDP套接字连接,该连接工作正常,但我们不确定如何存储从客户端接收的数据

目前,我们正在使用许多散列图来存储数据,例如,我们有三个散列图用于玩家跟踪、游戏信息(玩家数量等)和子弹(子弹位置、射击者等)

但我确信,除了hashmaps之外,必须有一种更好、更安全的方式来存储这些数据,但不确定是什么

编辑thx-Philipp(很抱歉花了这么长时间才提出了一个不太像样的问题)

我对使用hashmaps存储这些数据的担忧是,有很多数据需要放入其中,我们目前正在使用一行来存储对象的所有数据。例如,播放器hashmap中的一行将以播放器id为键,并使用字符串值存储任何其他数据,如“hp、xloc、yloc”。然后我们分开使用。我认为这不是存储和检索数据最有效的方法

抱歉,如果这仍然没有意义

我想我真正的问题是,是否有更有效的替代方案,或者hashmap是否是最好的方法


谢谢

Hashmaps是一个不错的解决方案-它们是线程安全的,所以假设你没有10000个用户同时访问你的网站,它们应该可以为你工作

但是,目前所有数据都存储在内存中。如果程序终止,这是一个问题

我能给它的最简单的建议是将哈希映射写入文件。这是通过在Java中向类声明中添加
Serializable
接口来实现的,但是您不需要对HashMap执行此操作,因为它已经可以序列化了。(您只需对存储在HashMap中的已编写类执行此操作。)

然后只需将以下内容添加到main()方法(从文件中读取):


正如您自己所想,将游戏中每个实体的数据存储在字符串中不是一个好主意

每当需要有关字符串的信息时,都必须对其进行解析,而字符串解析不是很快,而且当每个实体的数据变得更复杂时,它很容易变得相当复杂

更好的方法是使用一组类变量为每个实体类型创建一个类,并使用该类存储关于每个实体的数据:

class Player {
    public: 
         int positionX;
         int positionY;
         int lifes;
         String name;
         //...
}
(顺便说一句:一个有经验的面向对象程序员会将这些变量声明为私有变量,并使用getter和setter方法来更改它们,但现在我们不要走那么远)

然后,哈希映射将存储此类的实例:

 HashMap<Integer, Player> players;
(顺便说一下:有经验的OOP程序员会使用构造函数)

您可以通过访问哈希映射设置和获取每个播放器的变量:

 players.get(42).positionX += 10; // move player 42 10 pixels to the right
在记忆中是美好的。除非需要持久化数据,否则不要担心

然而,“然后我们分割使用”并不好。这是一个微观的“优化”,实际上会更慢/效率更低:这条路线上除了痛苦和损失的时间外什么都没有

我不知道你的具体设置,但是考虑一下:

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());
职业玩家{
公共玩家(int玩家ID){
this.playerId=playerId;
}
//游戏期间ID-非永久性;用于链接回哈希键
公共最终int playerId;
//根据需要添加方法和字段
字符串名;
国际卫生组织;
//位置、盔甲颜色、仙尘等。
}
//ID如何“连接”到玩家:
//playerId->Player
地图玩家=新的HashMap。。;
//当玩家“连接”
int playerId=getUniqueIdForGameInstance();
玩家=新玩家(玩家ID);//根据需要设置其他信息
players.add(player.playerId,player);
//受到攻击。。
int attackerId=getAttackerFromClient();
int targetId=getTargetFromClient();
玩家攻击者=玩家。获取(攻击);
玩家目标=players.get(targetId);
target.getWumped(攻击者.wumpStength());
这同样适用于游戏中的其他实体。请注意,地图用于在给定特定ID的情况下查找玩家,但player类的实例保存有关该玩家的信息


查看是否存在跨线路的序列化。

为什么您认为您的方法不充分?什么让你烦恼?IDK我只是觉得hashmaps在某种程度上是错误的,可能是因为它太简单了,我对它有点偏执,哈哈。如果你们认为hashmap是好的,那么就忽略这个问题(可能是我的偏执),为什么你认为你的方法太简单了?(顺便说一句:这和我之前的问题都不是花言巧语——我是想帮助你更好地理解你的问题。否则你不能提出一个有意义的问题来帮助你解决问题)好的,我会试着解释我的推理。正如我上面提到的,这个游戏有三个hashmap。我承认我对它们不太了解,但目前我们使用地图中的一行来存储玩家、子弹或游戏的所有信息,然后将这些信息拆分以获得我们需要的值,例如,玩家地图将是player.put(id,“100100”);然后,我们将从id中分割值并返回它,但是每次都要分割它似乎有点低效,对meah来说,我们越来越近了。你应该编辑你的问题,并添加关于拆分携带你信息的字符串的问题。我明白你的意思,基本上是创建一个类,然后使用hashmap访问动态生成的播放器类,并根据需要更新内容。非常感谢你的帮助。
 Player p = new Player();
 p.positionX = 200;
 p.positionY = 400;
 p.lifes = 3;
 p.name = "Ford Prefect";
 players.put(42, p);
 players.get(42).positionX += 10; // move player 42 10 pixels to the right
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());