2015-12-10 158 views
1

我正在用令人惊叹的phaser.io开发一个非常简单的HTML5游戏。这场比赛非常简单:2D版的1vs1排球比赛...实际上它是伟大的“皮卡丘排球”(http://imagenes.es.sftcdn.net/es/scrn/12000/12531/pikachu-volleyball-2.jpg)的“复制品”。多人游戏 - 同步球

正如我所说的,这场比赛是很容易的,我有:

  • PLAYER1
  • Player2
  • 静态元素

而且我刚刚来控制: - 球员运动 - 球运动(实际上由街机物理控制) - 玩家 - 球碰撞

我只是为了好玩,把我的朋友的面孔添加到玩家。 这款游戏工作得很好,我和朋友一起玩,真的很开心。所以我想,为什么不让它在线多人游戏,所以我们可以从不同的位置远程玩?

阅读了关于多人游戏的HTML5游戏之后,我开始用带有nodeJS服务器的websocket(socket.io)开发它。 socket.io的实现非常简单,通讯工作正常。

事情是让游戏真正可玩。

这些都是我的步骤现在:

在客户端连接,则创建:

  • PLAYER1(我自己)
  • 静态元素

而且客户端等待新客户连接创建:

  • 远程播放器

因此,两个客户端连接后,每个客户端上,我有:

  • OwnPlayer
  • RemotePlayer
  • 静态元素

然后游戏开始......在这个阶段它不是很公平,因为远程玩家根本没有移动。所以,为了让远程播放器移动(在一些尝试之后),我决定实施一种权威的服务器,就像那样工作。

  • 本地球员动作(输入注册) - >客户端发送的输入到服务器 - >服务器发送输入到两个客户端 - >每个客户端应用运动(通过改变速度)

这技工使球员的运动在过去工作,但'同步'(等待时间是可以接受的)。

这看起来不错,每个客户端都在播放他们的播放器,另一个播放器正在远程客户端移动。

问题是球...

在每个客户端有一个球,与街机物理移动(在网或在每个玩家的头弹跳)......所以很少有动作后,因为球员位置的同步并不完美,每个客户球的位置也不一样。

你将如何实现球同步?

有些选项我在想:

  • 定期送球位置服务器 - >服务器发送的球位的客户端 - >客户端更新球位置(有一些插值)

  • 仅在一个客户机(主站)和然后启用球物理发送从“主客户端”球位置“从属客户”周期性地(与的WebRTC,也许)

  • 重新开始和制作一个真正的“权威服务器”,在服务器上安装Arcade Physics(如果可能的话),并在客户端插值?

回答

0

你的问题让我想起了一个过去的问题,我的是一样的。我正在网上开发地图应用程序。所有客户端的地图对象必须相同(同步)。

我如何解决这个问题是我已经将类库移动到服务器端,并使地图对象单身。看看单身模式。单例对象不能实例化多次。我的意思是每个游戏都会有一个球对象,客户端会用它更新他们的本地对象。

这里是维基百科页面:https://en.wikipedia.org/wiki/Singleton_pattern

之后,在客户端做的第一件事就是让最近的地图实例(也就是你的情况,球),修改和服务器更新。

另一点是,多个客户端可能希望在sime时间更新服务器上的共享对象。这会导致一致性问题。许多实现包括锁定变量以限制访问。其他客户端等待锁释放和更新。

无论如何,在客户端有多个相同对象的实例并不是一个好方法。

1

解决你的问题,你可以去一个简单的方法, 你传送到服务器,这是附着, 现在玩家的攻击状态,所有球员从服务器订阅攻击的信息和现在的“克林斯“必须渲染子弹。

这里豆蔻代码示例

第1部分:[发布数据]

  transferData = [ 
      { 
       id: id, 
       name: Player.name, 
       position: Player.position, 
       facing: Player.facing, 
       hitFacing: Player.hitFacing, 
       health: Player.health, 
       energie: Player.energie, 
       healtbar: {width: Player.healthbar.width}, 
       energiebar: {width: Player.energiebar.width}, 
       isAttacking: Attack.isAttacking 
      } 
     ]; 

     session.publish('org.example.character.data', transferData); 
     Attack.isAttacking = false; 

第二部分:[订阅数据]

// get player position 
    session.subscribe('org.example.character.data',function (args) { 
     var player = args[0]; 
     var exists = false; 
     for (var i = 0; i < onlinePlayer.length; i++) { 

      if (onlinePlayer[i].uid == player.uid) { 
       var tmp = onlinePlayer[i]; 
       player.sprite = tmp.sprite; 
       player.label = tmp.label; 
       player.status = tmp.status; 


       if (player.isAttacking && player.sprite != undefined) { 
        // HERE RENDER THE BALL 
        renderBall(player, this.game); 
       } 

       onlinePlayer[i] = player; 
       exists = true; 
      } 
     } 

     if (!exists) 
      onlinePlayer.push(player); 

    }).then(
     function (sub) { 
      //console.log('subscribed to topic'); 
     }, 
     function (err) { 
      console.log('failed to subscribe to topic', err); 
     } 
    ); 

此示例是用于WebSocket的服务器,像crossbar.io与节点基础上的autobahn.js。

http://crossbar.io/docs/Quick-Start/ 但你也可以使其与其他服务器