用Node.JS构build的多人游戏JavaScript游戏 – 分离玩家
我有一个问题,我找不到答案。
我正在尝试用Node.JS和Socket.IO构build一个多人游戏。 我已经build立了一个聊天室作为我的第一个实验,所以我已经广播工作等。现在我正处在我想要与Canvas合作的地步。
我遇到的问题是让我的头多个和独立的球员。 我知道每个玩家都会把他们的x,y线发送给服务器,服务器会把这些线发送出去,但是客户怎么知道要显示多less个玩家,我猜测他们必须存储在某个数组中。
我的实现很简单朴素,没有滞后补偿,外推等,但是应该指出一个“多人游戏”与节点的一般概念。
我认为最简单的方法是在客户端和服务器上都有一个包含播放器(实体)的关联数组。 然后从客户端发送类似{action: "move", target:[32, 100]}
命令并使用服务器逻辑(在真实游戏运行的地方)处理该命令。 对于on connection
每个套接字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(); } });
然后,让我们说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个对象的半街机游戏,这是一个足够的algorithm。 缩短快照的时间间隔使其几乎适用于具有更多对象的策略游戏。 你的主要敌人是带宽使用,你可以减less数据包的大小。 比如读一下BiSON,LZW,不要发送自上次快照以来没有更改过的数据。
我的声望不允许我发布所有的链接,所以我把它们附在这里: http : //pastebin.com/Kh3wvF1D
Glenn Fiedler对多人游戏概念的总体介绍:
Quake的一些多人游戏技巧:这将提供关于内插和外推(预测)的线索,
http://fabiensanglard.net/quakeSource/quakeSourcePrediction.php
Valve关于延迟补偿和一般优化的文章:
帝国时代的多人游戏技巧:
你也可以阅读我关于优化带宽使用的文章
http://rezoner.net/minimizing-bandwidth-usage-in-html5-games-using-websocket,299
+1为伊沃的Wetzel Mapple.js这是一大堆的知识。
玩家不会将他们的x,y坐标发送给服务器,这样就可以通过手动发送坐标来进行作弊。
每个玩家发送“向左/向右/向上/向下移动”事件到服务器。 然后,服务器更新位置并周期性地广播所有玩家的位置(或位置上的增量)。
然后,每个客户端都会获取所有这些玩家angular色并渲染它们。 在客户端实现方面,我将拥有某种Board / Map对象,并且它将包含一个RenderableEntities列表。 然后我用新的职位更新RenderableEntities并定期重新绘制所有的实体。
我build议你看看Maple.js
同步每个玩家的X和Y坐标的另一种方法是使用Lance 。 它是一个开放源代码的JavaScript库,用权威服务器处理多个玩家的位置更正。
如果您需要同步坐标之外的其他东西,比如对象名称或头像属性,这将会非常有用。 或者如果你的球员有速度。