使用Node.JS构建的多人JavaScript游戏-分离玩家
Multiplayer JavaScript game built with Node.JS - Separating players
我有一个问题找不到答案。
我正在尝试用Node.JS和Socket.IO构建一个多人游戏。我已经建立了一个聊天室作为我的第一个实验,所以我可以使用广播等。现在我正处于想用Canvas做点什么的时候。
我遇到的问题是,我的头脑里有很多独立的球员。我知道每个玩家都会将他们的x,y线发送到服务器,服务器会广播这些,但客户端如何知道要显示多少玩家,我猜它们必须存储在某个阵列中。
我的实现将非常天真和简化,没有滞后补偿、外推等,但它应该指出带有节点的"多层"的一般概念。
我认为最简单的方法是在客户端和服务器上都有一个包含播放器(实体)的关联数组。然后从客户端发送类似{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对多人游戏概念的总体介绍:
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
+1对于Ivo的Wetzel Mapple.js来说,这是一大堆知识。
https://github.com/BonsaiDen/Maple.js
玩家不会将他们的x,y坐标发送到服务器,这将允许通过手动发送坐标进行作弊。
每个玩家向服务器发送"向左/向右/向上/向下移动"事件。服务器随后更新位置并定期广播所有玩家的位置(或位置上的增量)。
然后,每个客户端获取所有这些玩家增量并进行渲染。在客户端实现方面,我会有某种Board/Map对象,它会有一个RenderableEntities列表。然后,我只是用新的位置更新RenderableEntities,并定期重新绘制所有实体。
我建议您查看Maple.js
同步X&每个玩家的Y坐标都是使用Lance。这是一个开源JavaScript库,通过权威服务器为多个玩家处理位置校正。
如果你需要同步坐标之外的其他东西,比如对象名称或化身属性,这将很有用。或者如果你的球员有速度。
- Javascript游戏输入失去焦点
- HTML5内存游戏-JavaScript功能
- 正面或反面游戏javascript do/while循环
- 结束一个反应游戏Javascript
- 如何在制作简单的纸牌游戏(Javascript)时给卡牌一个数值
- 根据游戏 JavaScript 中的级别更改背景图像
- 匹配游戏.Javascript.DOM lastChild
- 不可能的井字游戏Javascript
- 第一个编程游戏(javascript/jQuery)的问题
- 随机颜色猜测游戏(JavaScript)
- 井字游戏JavaScript帮助(我没有得到我想要的警报)
- 井字游戏Javascript不会改变玩家
- 井字游戏JavaScript
- 简单纸牌游戏javascript中的indexOf问题
- 游戏JavaScript / JSON链接文本框
- 西蒙游戏javascript,我如何同步按钮的灯不踩在彼此与动画()和延迟()JQUERY
- 井字游戏javascript.如何储存玩家的胜利,并提醒是否有平局
- 内存游戏Javascript中瓦片的悬停状态
- 在游戏 JavaScript 中添加暂停键
- 重新启动逻辑井字游戏(JavaScript)时遇到问题