我正在multiplayer game
平台上工作,该平台将有多个(主要是turn-based
)multiplayer games
。主要思想是每个player
都连接到特定的game
,并且在这些game
中它们将具有多个lobbies
。用户可以输入每个lobby
,在那里他们将看到lobby
中的其他玩家以及该game instances
中的lobby
(开放游戏)。用户还可以在game instance
内创建新的lobby
,并等待其他玩家加入以开始游戏。
我对当前玩家状态的体系结构有疑问。具有某种形式的播放器模型(实际上只是扩展的用户模型)可以保持播放器的整体状态吗?像这样:
public interface IPlayer
{
Guid UserId { get; set; }
string Name { get; set; }
Guid GameDefinitionId { get; set; }
Guid? LobbyId { get; set; }
Guid? GameId { get; set; }
}
GameDefinitionId
-确定用户选择了哪个游戏定义(扑克,二十一点等)。每个游戏都有自己的hub
,因此,当用户连接到hub
(特定于game
)时,Player
实例是使用指定的GameDefinitionId
创建的该game
的标识符(因此在模型中不是可选的)。LobbyId
-lobby
的可选标识符,显示用户在指定的大厅中。GameId
-可选的game
实例标识符,显示该用户位于指定的game
中。 通过更改此属性(当前IPlayer
的列表为in-memory
,但是如果需要,我稍后将其移至database
),我可以确切地知道用户所在的位置并控制他的状态。请注意,用户不能同时处于多个大厅或游戏中。当然,每个更改都会由service
进行验证,如果更改有效,则会通知所有感兴趣的clients
。
这是每个游戏都应实现的基本中心
public abstract class MultiplayerGameHub : HubBase
{
protected IPlayerHandler PlayerHandler { get; private set; }
public MultiplayerGameHub(
IOnlineClientManager onlineClientManager,
ISessionProvider sessionProvider,
IPlayerHandler playerHandler)
: base(onlineClientManager, sessionProvider)
{
PlayerHandler = playerHandler;
}
public virtual async Task Connect()
{
var gameDefinition = await GetGameDefinitionAsync();
if (gameDefinition == null)
{
throw new HubException("Unknown game definition");
}
await PlayerHandler.ConnectAsync(Context.ConnectionId, gameDefinition.Id);
}
public virtual Task Disconnect()
{
return PlayerHandler.DisconnectAsync(Context.ConnectionId);
}
public Task JoinLobby(JoinLobbyParams model)
{
return PlayerHandler.JoinLobbyAsync(Context.ConnectionId, model.LobbyId);
}
public Task LeaveLobby()
{
return PlayerHandler.LeaveLobbyAsync(Context.ConnectionId);
}
public abstract Task<IGameDefinition> GetGameDefinitionAsync();
}
这是好方法还是应该以其他方式处理?