我正在尝试实现一个可以通过RMI在网络上播放的2人游戏。我有一个Game
接口和一个实现接口的GameImpl
类。为了让客户端玩一个游戏,我有一个服务器类,如下所示:
public class RMIServer {
public RMIServer(int port) throws RemoteException, AlreadyBoundException {
Registry registry = LocateRegistry.createRegistry(port);
Game game = new GameImpl();
registry.bind("Game", game);
}
public static void main(String[] args) throws RemoteException, AlreadyBoundException {
RMIServer server = new RMIServer(1099);
}
}
另一方面,客户端类看起来如下:
public class RMIClient {
RMIClient(String host, int port) throws RemoteException, NotBoundException {
Registry registry = LocateRegistry.getRegistry(host, port);
Game game = (Game) registry.lookup("Game");
game.play();
}
public static void main(String[] args) throws RemoteException, NotBoundException {
RMIClient client = new RMIClient("127.0.0.1", 1099);
}
}
如果只有一个玩家需要通过网络玩游戏,这个实现很有效。我现在遇到的问题是我想登录,以便两个不同的玩家可以通过网络互相对战。主要问题是,我真的不知道在哪里可以使用可能的用户及所有游戏,以及如何查看他们的登录信息。
我想在服务器中保留一个Map<User, Game>
并注册正确的游戏,如果用户已登录,但我不知道如何登录,或者如何确保客户端到达正确的位置游戏。
感谢任何帮助
答案 0 :(得分:2)
当我使用RMI开发2-player minesweeper game时,我想知道完全相同的问题。首先,您必须想知道如何创建游戏?
您想在前两个可用的玩家之间创建一个游戏(&#34;尽快玩#34;模式)?例如:
- player1 connects
- player2 connects
- the server automatically starts a game between player1 and player2
你想让球员选择他们的对手(沙龙)吗?例如:
- player1 connects
- player2 connects
- player3 connects
- player1 decides to start a game with player3
如果您决定使用第二种模式,这是一种方法。
在服务器上,保留当前连接的播放器的列表。每次客户端连接到服务器并成功登录时,将其添加到该列表中:
/** The connected players */
private List<Player> connectedPlayers;
同时准备一张地图,其中包含每个玩家关联的游戏实例(顺便说一下,你是在正确的轨道上!)。
/** The games currently being played */
private Map<Player, Game> gameList;
当在两个玩家之间创建游戏时(player1想要玩玩家2),将它们添加到游戏列表中。
Game game = new Game(player1, player2);
this.gameList.put(player1, game);
this.gameList.put(player2, game);
如果您需要知道用户是否可用且尚未加入游戏:
public boolean isUserAvailable(String potentialOpponent) throws RemoteException {
for (Entry<Player, Game> entry : this.gameList.entrySet()) {
if (entry.getKey().getUsername().equals(potentialOpponent)) {
return false;
}
}
return true;
}
游戏结束后,从地图中删除2名玩家。
this.gameList.remove(game.getPlayerHost());
this.gameList.remove(game.getPlayerClient());
我无法在此处复制/粘贴更多代码,但如果您需要灵感,可以在我的游戏中找到source code。这些文件很有趣:
答案 1 :(得分:1)
首先,你在极低的水平上解决这个问题。除非你有充分的理由,否则你应该考虑使用更高级别的抽象,例如......
这些技术将允许您继续使用RMI作为传输,但也可以使用Session Facade轻松构建组件。
单独完成这一切非常繁琐。
稍微澄清一下我的答案。您应该使用会话外观模式存储您的游戏对象。
这是你的核心问题......
我不知道如何登录,或者如何确保客户端能够进入正确的游戏。
这是一个看似复杂的问题。