2012-01-27 1 views
13

답변을 찾을 수없는 질문이 있습니다.Node.JS로 작성된 멀티 플레이 자바 스크립트 게임 - 플레이어 분리하기

Node.JS 및 Socket.IO를 사용하여 멀티 플레이어 게임을 제작하는 실험을하고 있습니다. 첫 번째 실험으로 대화방을 만들었으므로 방송 등을 할 수있게되었습니다. 이제 Canvas와 관련된 작업을하고 싶습니다.

내가 가지고있는 문제는 여러 명의 독립적 인 플레이어를 두렵게 생각하는 것입니다. 나는 각 플레이어가 x와 y 코드를 서버에 보내고 서버가이를 방송 할 것이지만 클라이언트는 얼마나 많은 플레이어를 표시해야 하는지를 어떻게 알 수 있겠는가? 어딘가 배열에 저장해야한다고 생각한다.

답변

39

내 구현을 살펴 권장하지만, 노드와 "multiplayering"의 일반적인 개념을 가리켜 야합니다.

가장 간단한 방법은 클라이언트와 서버 모두에서 플레이어 (엔티티)가 포함 된 연관 배열을 만드는 것입니다. 그런 다음 클라이언트 측에서 {action: "move", target:[32, 100]}과 같은 명령을 보내고이 명령을 서버 로직 (실제 게임이 실행되는 곳)으로 처리하십시오. 당신이 액세스 할 수 있도록 플레이어 객체 또는 아이디를 할당해야합니다 on connection 각 소켓에 좋아 :에서 다음

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

를 실행 한 다음, 다음

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로 말을하자 클라이언트 쪽에서 데이터를 받고 이전 값에서 새 값으로 보간합니다.

// 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

일반 소개 글렌 Fiedler는에 의해 개념을 멀티 플레이어하기 :

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

퀘이크의 일부 멀티 플레이어 기술 : 이것은 i에 대한 단서를 제공합니다. nterpolation 및 추정 (예측)

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

지연 보상 및 일반 최적화에 대한 밸브의 기사 :

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

제국의 시대

멀티 기술 :

,

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

당신은 또한 지식의 큰 더미의 이보의 Wetzel는 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 좌표를 보내지 않아 좌표를 수동으로 보내서 부정 행위를 허용합니다.

각 플레이어는 "왼쪽/오른쪽/위/아래 이동"이벤트를 서버로 보냅니다. 그런 다음 서버는 위치를 업데이트하고 주기적으로 모든 플레이어의 위치 (또는 위치의 델타)를 브로드 캐스트합니다.

각 클라이언트는이 모든 플레이어 델타를 가져 와서 렌더링합니다. 클라이언트 측 구현 측면에서 어떤 종류의 Board/Map 객체를 가지며 RenderableEntities 목록을 갖게됩니다. 그런 다음 RenderableEntities를 새 위치로 업데이트하고 주기적으로 모든 항목을 다시 그립니다.

나는 당신이 매우 순진하고, 아니 지연 보상, 추정 및 단순화 될 것 Maple.js

+0

물론. 설명 해줘서 고마워. 따라서 로직은 서버에 앉아 새로운 위치를 플레이어에게 방송합니다. 배열이나 객체를 브로드 캐스팅 한 다음 표시 할 클라이언트 측에서 반복할까요? 덕분에 Maple.js를 살펴 보겠습니다 :) – Henryz

+0

효율성을 높이기 위해 @Henryz는 위치를 변경 한 객체 만 브로드 캐스팅하고 위치는 실제 위치가 아니라 전체 위치로 방송합니다. 데이터 구조는 당신에게 달렸습니다. 튜플의 객체는 꽤 좋습니다. {{id : [x, y], otherid : [x, y]} 등 – Raynos

+0

Maple.js 데모를 실행하려고하고 있습니다. 그것은 전혀 작동하지 않습니다. 지난 3 년간 Repo 업데이트가 없습니다. 클라이언트와 서버간에 이러한 종류의 동기화 된 업데이트를 구현할 수있는 다른 제안 사항은 무엇입니까? –

0

& Y는 각 플레이어의 좌표 X를 동기화하는 다른 방법은 Lance를 사용하는 것이다. 신뢰할 수있는 서버로 여러 플레이어의 위치 수정을 처리하는 오픈 소스 JavaScript 라이브러리입니다.

개체 이름이나 아바타 속성과 같은 좌표 이외의 다른 것들을 동기화해야하는 경우 유용합니다. 또는 당신의 선수들이 속도를 가지고 있다면.

관련 문제