玩家 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》邀请玩家一起参加最新推出的游戏内系列活动——俱乐部挑战赛

google play games:从邀请ID中获取请求的玩家总数

从服务器删除角色

Google Play 服务 - Unity - 只能在 iOS 上邀请“最近的玩家”