2015-12-10 194 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/ 但你也可以使其與其他服務器