使用Node.JS构建的多人JavaScript游戏 - 分离玩家

Hen*_*ryz 13 javascript canvas node.js socket.io

我有一个问题,我无法找到答案.

我正在尝试使用Node.JS和Socket.IO构建多人游戏.我已经建立了一个聊天室作为我的第一个实验,所以我有广播工作等等.现在我正处于想要使用Canvas的地方.

我遇到的问题是围绕多个独立玩家.我知道每个玩家都会将他们的x,y线发送到服务器,服务器会广播那些,但是客户端如何知道要显示多少玩家,我猜他们必须存储在某个地方的数组中.

rez*_*ner 39

我的实现将非常幼稚和简化,没有滞后补偿,外推等等,但它应该指出与节点"多人游戏"的一般概念.

我认为最简单的方法是在客户端和服务器上都有一个包含播放器(实体)的关联数组.然后从客户端发送命令,{action: "move", target:[32, 100]}并使用服务器逻辑处理此命令(真实游戏正在运行).对于每个套接字,on connection 您应该分配一个播放器对象或ID,以便您可以访问它:

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(); 
  }

});
Run Code Online (Sandbox Code Playgroud)

然后每个让我们说100毫秒你可以发送快照给所有连接的玩家:

{
  timestamp: game.delta,
  players: {
    1: {x: 32, y: 100},
    2: {x: 14, y: 11}
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在客户端接收数据并从旧值插值到新值.

// 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
  }
}
Run Code Online (Sandbox Code Playgroud)

对于具有最多20个对象的半街机游戏来说,这是一个足够的算法.减少快照的间隔使其几乎适用于具有更多对象的策略游戏.你的主要敌人是带宽使用,你可以减少数据包的大小.例如,阅读有关BiSON,LZW并且不发送自上次快照以来未更改的数据.

我的声誉不允许我发布所有链接,所以我在这里附上:http: //pastebin.com/Kh3wvF1D

Glenn Fiedler对多人概念的一般介绍:

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

Quake的一些多人游戏技术:这将给出关于插值和外推(预测)的线索

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

Valve关于延迟补偿和一般优化的文章:

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

您还可以阅读我关于优化带宽使用的文章

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

为Ivo的Wetzel Mapple.js +1,这是一大堆知识.

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


Ray*_*nos 11

玩家不会将他们的x,y坐标发送到服务器,这将允许通过手动发送坐标来作弊.

每个玩家向服务器发送"向左/向右/向上/向下移动"事件.然后,服务器更新位置并定期广播所有玩家的位置(或位置的增量).

然后每个客户端获取所有这些玩家增量并呈现它们.在客户端实现方面,我会有一些Board/Map对象,它会有一个RenderableEntities列表.然后,我只需使用新位置更新RenderableEntities并定期重绘所有实体.

我建议你看一下Maple.js