我有一个我无法找到答案的问题。
我正在尝试使用Node.JS和Socket.IO构建多人游戏。我已经建立了一个聊天室作为我的第一个实验,所以我有广播工作等等。现在我正处于想要使用Canvas的地方。
我遇到的问题是围绕多个独立玩家。我知道每个玩家都会将他们的x,y线发送到服务器,服务器会广播这些,但是客户端如何知道要显示多少玩家,我猜他们必须存储在某个阵列中。
答案 0 :(得分: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();
}
});
然后每个让我们说100毫秒你可以发送快照给所有连接的玩家:
{
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 击>
Glenn Fiedler对多人概念的一般介绍:
Quake的一些多人游戏技巧: 这将给出关于插值和外推(预测)的线索
http://fabiensanglard.net/quakeSource/quakeSourcePrediction.php
Valve关于延迟补偿和一般优化的文章:
帝国时代的多人游戏技术:
您还可以阅读我关于优化带宽使用的文章
http://rezoner.net/minimizing-bandwidth-usage-in-html5-games-using-websocket,299
+1 Ivo的Wetzel Mapple.js这是一大堆知识。
答案 1 :(得分:11)
玩家不会将x,y坐标发送到服务器,这样可以通过手动发送坐标来进行作弊。
每个玩家向服务器发送“向左/向右/向上/向下移动”事件。然后服务器更新位置并定期广播所有玩家的位置(或位置的增量)。
然后每个客户端获取所有这些玩家增量并呈现它们。在客户端实现方面,我会有一些Board / Map对象,它会有一个RenderableEntities列表。然后,我只需使用新位置更新RenderableEntities并定期重绘所有实体。
我建议你看一下Maple.js
答案 2 :(得分:1)
同步X&amp; amp;的另一种方法每个玩家的Y坐标是使用Lance。 它是一个开源JavaScript库,可以使用权威服务器处理多个玩家的位置校正。
如果您需要同步除坐标之外的其他内容(如对象名称或头像属性),这将非常有用。或者如果你的球员有速度。