【问题标题】:Meteor 1.0 - Hosting a lobby and redirecting other usersMeteor 1.0 - 托管大厅并重定向其他用户
【发布时间】:2015-02-11 00:54:45
【问题描述】:

我有一个我不知道解决方案的问题。我正在创建涉及多个玩家的游戏。一个人“主持”游戏并向其他用户发送“邀请”以加入“大厅”。如果您曾经玩过《使命召唤》或任何类似游戏,那就是同一个概念。

这个过程的大部分目前都可以正常工作。

我创建了一个名为 Lobby 的集合来跟踪所有开放和关闭的大厅。当用户想要主持一个大厅时,他点击按钮,这会创建一个新的大厅并将用户重定向到正确的 url:

Template.lobby.events
  'click button#host-lobby': (e,t) ->
    lobbyId = Lobby.insert
      host: Meteor.user()._id
      hostName: Meteor.user().username
      status: true
      players: []
    Router.go("currentLobby", _id: lobbyId)

然后,用户可以通过模态框邀请其他用户到大厅(url),该模态框将通知对象添加到被邀请用户的个人资料中。可能不是最好的方法,所以我愿意接受这方面的建议。

Template._playerItem.events
  'click button': (e,t) ->
    lobbyId = Session.get "currentLobby"
    Meteor.call "sendNotification", @_id, lobbyId, Meteor.user().username
    Lobby.update
      _id: lobbyId
    ,
      $addToSet:
        invitedPlayers: @_id

以及方法:

Meteor.methods
  sendNotification: (userId, lobbyId, hostName) ->
    sendTo = Meteor.users.findOne(_id: userId)
    Meteor.users.update
      _id: userId
    ,
      $push:
        invite:
          hostName: hostName
          lobbyId: lobbyId

因此,此时用户可以接受或拒绝邀请。如果他接受,他将被路由到大厅并被添加到大厅对象中的players 数组中。正如人们所期望的那样,用户出现在玩家列表中。

当我尝试“开始”游戏时,我的问题就开始了。单击按钮时,游戏会正确创建,并且主机(按下按钮的人)会被路由到新游戏的 url:

Template.currentLobby.events
  'click #start-game': (e,t) ->
    playerIds = [@host]
    @players.forEach (player) ->
      playerIds.push(player.id)
    Meteor.call 'createGame', playerIds
    Router.go('home')

问题是大厅中的其他用户没有被重定向。如果他们手动访问 url,他们可以访问游戏,但他们不会被带到那里。他们根本不知道游戏真的开始了……

一种解决方案是添加一个“游戏已开始”徽章,并带有游戏链接,但我认为更优雅的解决方案是将当前大厅 url 处的所有用户路由到刚刚开始的游戏。

这个功能可行吗?有没有更好的方式来举办大厅?

编辑

感谢 Chet 提供的解决方案。这就是我最终实现它的方式:

Template.currentLobby.rendered = ->
  @autorun ->
    data = Template.currentData()
    if data.url
      Router.go data.url

@autorun 有一些上下文困难,所以我只使用了大厅数据。然后,当有人点击“开始游戏”按钮时,当前大厅会更新为新游戏的 url(Meteor.call 'createGame' 返回新游戏的 _id)。

Template.currentLobby.events
  'click #start-game': (e,t) ->
    playerIds = [@host]
    lobbyId = Template.currentData()._id

    @players.forEach (player) ->
      playerIds.push(player.id)

    Meteor.call 'createGame', playerIds, (err, res) ->
      Lobby.update
        _id: lobbyId
      ,
        $set:
          url: "/game/#{res}"

像魅力一样工作。谢谢!

【问题讨论】:

    标签: meteor coffeescript iron-router


    【解决方案1】:

    好的。首先,解决您的通知。这是一个有效的解决方案。但是,您可能希望按日期对它们进行排序!您还需要创建一个单独的 Notifications 集合。每当您更新文档时,整个事情都会通过 DDP 发送到客户端。因此,添加到配置文件的任何新通知都会导致将整个配置文件发送给客户端。您还需要某种方式将通知标记为已读,以便将其删除。

    要解决您关于重定向大厅的问题,请创建名为 url 的属性。最初它被设置为假。一旦主机准备好开始游戏,他们将 url 属性设置为 url。

    当用户进入大厅时,启动重定向的自动运行。

    Template.lobby.rendered = ->
      @autorun ->
        if game.url
          Router.go(game.url)
    

    您必须确保game.url 是一个反应式数据源。如果您使用 Iron 路由器将游戏作为数据上下文传递,那么您应该可以使用 @data.url 但我不能 100% 确定它会是被动的。为了安全起见,请尝试Games.findOne(@data._id)——这肯定是被动的。

    编辑: 为了清楚起见,试试这个:

    Template.lobby.rendered = ->
      @autorun ->
        game = Games.findOne(@data._id)
        if game.url
          Router.go(game.url)
    

    【讨论】:

    • @autorun 是关键。以前没用过。很有用!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 2017-02-16
    相关资源
    最近更新 更多