玩家 1 邀请玩家 2 与凤凰频道玩游戏
Posted
技术标签:
【中文标题】玩家 1 邀请玩家 2 与凤凰频道玩游戏【英文标题】:Player 1 invites Player 2 to play a game with Phoenix Channels 【发布时间】:2018-06-14 14:51:17 【问题描述】:我正在使用 Phoenix 频道和 GenServer 在 Phoenix 创建一个有 2 名玩家的纸牌游戏。这就是我的 Game Struct 的样子:
schema "games" do
field :winner, :integer
field :player_1, :id, default: nil
field :player_2, :id, default: nil
field :status, :string
## VIRTUAL FIELDS ##
field :player_1_hand, :map, virtual: :true
field :player_2_hand, :map, virtual: :true
timestamps()
end
因此,如您所见,我将使用虚拟字段处理玩家手牌,然后将玩家和获胜者保存到数据库中。
我现在设置了一个大厅频道,玩家可以在这里聊天。我有一个没有功能的游戏频道。如何让玩家互相邀请玩游戏,接受或拒绝,然后让两个玩家一起玩游戏?
这是我目前在大厅频道中看到的(关于游戏):
def handle_in("game_invite", %"username" => username, socket) do
data = %"username" => username, "sender" => socket.assigns.current_player.username
broadcast! socket, "game_invite", data
:noreply, socket
end
intercept ["game_invite"]
def handle_out("game_invite", %"username" => username, "sender" => sender, socket) do
if socket.assigns.current_player.username == username do
push socket, "game_invite", % username: sender
end
:noreply, socket
end
我什至不知道我是否问对了问题。我正在尝试生成一个新的游戏 ID(来自 postgres),将两个玩家 ID 放入游戏中,然后让 GameServer 使用 GenServer 来管理玩家的手。
【问题讨论】:
【参考方案1】:这将是一个伪答案,因为您也提出了一个伪问题;一种方法:
假设您有一个用户通道,您可以通过该通道向每个单独的玩家发送套接字事件(或单独到达玩家的任何其他方式)
Player_1 从一个列表中选择一个 Player_2,这会发送一个套接字事件来表示它,比如 action: 'create_invitation', invitee: 'player_2'
,然后你有一个handle_in(%'action' => 'create_invitation', 'invitee': invitee)
在handle_in
上,您检查发出邀请的玩家是否还没有任何打开的游戏,也没有玩游戏,如果是,首先您将他现在拥有的信息分配给它的套接字ID 为“#socket.current_player#invitee.id”的游戏,然后您启动一个新的 gen_server,名称为 global
的 id 为该 id,将玩家邀请 id 传递给 start
函数和受邀者ID。
在 gen_server init 上,您向 player_2 广播一条消息,询问他是否想使用您之前设置的全局 id 加入游戏,并将其初始状态设置为,例如:
% player_1: player_1_id, player_2: invitee_id, game_id: "#player_1_id#player_2_id", started: false
然后通过从init
函数返回,为这个 genserver 设置一个合理的超时时间来接收回复,比如 25 秒:
:ok, state, 25_000
现在,在 player_2 的前端,您需要接收收到的声明他被邀请的广播并将其转化为可操作的东西,这将向大厅频道发送消息,例如 %action: "accept", game_id: "player_1_idplayer_2_id"
。您进行所有检查以查看它是否有效,该玩家还没有游戏,如果在他的套接字中设置了他现在有游戏,则调用先前启动的 gen_server ,例如GenServer.call(game_id,:accept_game, player_2_id)
然后在 gen_server 你有一个 handle_call
def handle_call(:accept_game, player_2_id, _from, %started: false, player_2: p2_id = state) when player_2_id == p2_id do
#create game hands, broadcasts, etc
:reply, :ok, Map.put(state, :started, true)
end
您至少需要创建一个 handle_info 来处理邀请到期 - 这应该彻底终止 gen_server,并触发清理 player_1 的套接字等...
【讨论】:
以上是关于玩家 1 邀请玩家 2 与凤凰频道玩游戏的主要内容,如果未能解决你的问题,请参考以下文章
Zynga旗下魔法三消手机游戏《Harry Potter: Puzzles & Spells》邀请玩家一起参加最新推出的游戏内系列活动——俱乐部挑战赛