Meteor 1.0 - 托管大厅并重定向其他用户

时间:2015-02-09 19:25:50

标签: meteor coffeescript iron-router

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

目前大部分流程都正常运作。

我创建了一个名为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)

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

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')

问题是大厅中的其他用户未被重定向。如果他们手动转到网址,他们可以访问游戏,但是他们不会被带到那里。他们无法知道游戏真的开始......

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

这项功能可行吗?是否有更好的方式来举办大厅?

修改

谢谢切特的解决方案。这就是我最终实现它的方式:

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

@autorun有一些上下文困难,所以我只使用了大厅数据。然后,当有人点击“开始游戏”按钮时,当前大厅将使用新游戏的网址进行更新(The 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}"

像魅力一样工作。谢谢!

1 个答案:

答案 0 :(得分:0)

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

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

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

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

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

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

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