2012-01-27 12 views
13

私には答えが見つからない質問があります。Node.JSで構築されたマルチプレイヤーJavaScriptゲーム - プレーヤーを分ける

私は、Node.JSとSocket.IOでマルチプレイヤーゲームを構築しようとしています。私は最初の実験としてチャットルームを作りましたので、放送などがありました。今私はCanvasで何かをしたいと思っています。

私が抱えている問題は、複数の独立したプレーヤーの周りに頭を上げていることです。私は各プレーヤーがxとyのコードをサーバーに送信し、サーバーがそれらをブロードキャストすることを知っていますが、クライアントは表示するプレイヤーの数をどのように知っていますか、どこかの配列に格納する必要があります。

答えて

39

私の実装を見てみましょうお勧めしますが、それはノードと「multiplayering」の一般的な概念を指摘しなければなりません。

私は、最も簡単なアプローチは、クライアントとサーバーの両方にプレーヤー(エンティティ)を含む連想配列を持たせることだと思います。クライアント側からは、{action: "move", target:[32, 100]}のようなコマンドを送信し、サーバーロジック(実際のゲームが実行されている場所)でこのコマンドを処理します。あなたが好きそれにアクセスできるように、選手オブジェクトかIDを割り当てる必要がありますon connection各ソケットへ:

var lastPlayerID = 0; 
var players = {}; 

server.on("connection", function(socket) { 

    var newcommer = new Player({id: lastPlayerID});  
    players[lastPlayerID] = newcommer; 
    socket.player = newcommer; // or lastPlayerID 
    lastPlayerID++;  

    socket.onMessage = function(message) { 
    this.player.doSomething(); 
    } 

}); 

その後、それぞれのは、あなたが接続されているすべてのプレイヤーにスナップショットを送ることができるの100msを言わせて:

{ 
    timestamp: game.delta, 
    players: { 
    1: {x: 32, y: 100}, 
    2: {x: 14, y: 11} 
    } 
} 

そして時クライアント側はデータを受信し、古い値から新しい値に補間する。

// duration in this simplified example is snapshot sending interval in [ms] 
Player.prototype.interpolateTo = function(data, duration) { 
    if(typeof data.x != "undefined") { 
    // step needed to get `destination x` within `duration` miliseconds 
    this.stepValues.x = Math.abs(data.x - this.x)/duration; 
    this.target.x = data.x; 
    } 
    // ... 
} 

// step you call for each game loop iteration 
Player.prototype.step = function(delta) { 
    if(this.x < this.target.x) { 
    this.x += delta * this.stepValues.x 
    } 
} 

これは、最大20個のオブジェクトを備えたセミアーチ型ゲームには十分なアルゴリズムです。スナップショットの間隔を短くすると、より多くのオブジェクトを持つ戦略ゲームに最適です。あなたの主な敵は、パケットのサイズを最小限に抑えることができる帯域幅の使用です。たとえば、BiSON、LZWについて読んで、最後のスナップショット以降に変更されていないデータは送信しないでください。

私の評判は私がすべてのリンクを投稿することができませんので、私はそれらをここに添付した: http://pastebin.com/Kh3wvF1D

一般的な導入は、グレン・フィードラーによって概念をマルチプレイヤーする:

http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/

Quakeのいくつかのマルチプレイヤー技術: これは私にnterpolationと外挿(予測)

http://fabiensanglard.net/quakeSource/quakeSourcePrediction.php

レイテンシー補正と一般的な最適化についてのバルブの記事:

https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization

Age of Empiresの中

マルチプレイ技術:

http://zoo.cs.yale.edu/classes/cs538/readings/papers/terrano_1500arch.pdf#search=%22Real%20time%20strategy%20networking%20lockstep%22

また、それは知識の大きな山だイヴォのウェッツェルMapple.jsのための帯域幅の使用

http://rezoner.net/minimizing-bandwidth-usage-in-html5-games-using-websocket,299

1の最適化についての私の記事を読むことができます。

https://github.com/BonsaiDen/Maple.js

+0

ようこそStackoverflowへ!非常に良い答えは、このようにして、あなたの担当者の欠如は非常に長い問題ではないはずです。 :) – RedRiderX

+0

このような詳細な説明ありがとうございます:) – Henryz

10

プレイヤーはx、y座標をサーバーに送信せず、手動で座標を送信して不正行為を許可します。

各プレイヤーは、サーバーに「左/右/上/下に移動」イベントを送信します。次に、サーバは位置を更新し、すべてのプレーヤの位置(または位置のデルタ)を定期的にブロードキャストする。

各クライアントは、これらのすべてのプレーヤーデルタを受け取り、レンダリングします。クライアントサイドの実装に関して、私はある種のボード/マップオブジェクトを持っていて、RenderableEntitiesのリストを持っています。次に、RenderableEntitiesを新しい位置で更新し、すべてのエンティティを定期的に再描画します。

は、私はあなたが非常にナイーブと、無遅れ補償、外挿と、このような簡略化されますMaple.js

+0

もちろんです。説明ありがとう。したがって、ロジックはサーバー上に座り、プレイヤーに新しいポジションをブロードキャストします。配列やオブジェクトをブロードキャストして、それをクライアント側でループして表示するでしょうか?私はMaple.jsに感謝します:) – Henryz

+0

@Henryz効率的な目的のためには、位置を変更したオブジェクトだけをブロードキャストし、位置全体ではなく位置の実際の差異だけをブロードキャストします。データ構造はあなた次第です。タプルのオブジェクトはかなり良いです。{{id:[x、y]、otherid:[x、y]}等 – Raynos

+0

Maple.jsのデモを実行しようとしているのですか?それは全く働いていません。過去3年間のレポアップデートはありません。この種の同期された更新をクライアントとサーバーの間で実装する可能性のある他の提案はありますか? –

0

各プレイヤーのX & Y座標を同期させる別の方法は、Lanceを使用することです。 オープンソースのJavaScriptライブラリで、権限のあるサーバーを使用して複数のプレイヤーの位置補正を処理します。

オブジェクト名やアバタープロパティなどの座標以外のものを同期させる必要がある場合に便利です。またはあなたの選手が速度を持っている場合。

関連する問題