我正在使用惊人的phaser.io在HTML5中开发一个非常简单的游戏。游戏非常简单:2D中的1vs1凌空游戏......实际上它是伟大的“皮卡丘凌空”(http://imagenes.es.sftcdn.net/es/scrn/12000/12531/pikachu-volleyball-2.jpg)的“复制”。
正如我所说,游戏非常简单,我有:
而我只能控制: - 球员动作 - 球运动(实际上由Arcade Physics控制) - 球员 - 球碰撞
我只是为了好玩,将我朋友的面孔添加到玩家手中。 游戏运行得很好,我和朋友一起玩真的很开心。所以我想,为什么不在线进行多人游戏,所以我们可以从不同地点远程玩游戏?
在阅读了多人HTML5游戏后,我开始使用带有nodeJS服务器的websocket(socket.io)进行开发。 socket.io的实现非常简单,通信工作正常。
事情是让游戏真正可玩。
这是我现在的步骤:
在客户端连接上,创建它:
客户端等待新的客户端连接创建:
因此,在连接两个客户端之后,我在每个客户端上都有:
然后游戏开始...在这个阶段它不是很公平,因为远程播放器它根本不移动。所以,为了让远程播放器移动(经过一些尝试),我决定实现一种权威的服务器,就像那样工作。
这种机制让玩家的动作在过去时起作用,但是“同步”(等待时间可以接受)。
这看起来很棒,每个客户正在播放移动他们的播放器,而另一个播放器则由远程客户端移动。
问题是球......
在每个客户端都有一个球,随着Arcade物理移动(在每个玩家的网中弹跳)...所以经过很少的动作,因为球员位置的同步不完美,球每个客户的位置都不一样。
您将如何实施球同步?
我在想的一些选择:
定期将球位置发送到服务器 - >服务器向客户发送球位置 - >客户更新球位置(带一些插值)
仅在一个客户端(主站)中启用球物理,然后定期将球位置从“主客户端”发送到“从客户端”(可能使用webRTC)
重新开始并制作一个真正的'权威服务器',在服务器上使用Arcade Physics(如果可能的话),只在客户端进行插值?
答案 0 :(得分:1)
要解决您的问题,您可以轻松解决 你转移到服务器,附加的玩家的攻击状态, 现在,所有玩家都从服务器订阅了攻击信息,现在是" clints"必须渲染子弹。
这是一个小代码示例
第1部分:[发布数据]
transferData = [
{
id: id,
name: Player.name,
position: Player.position,
facing: Player.facing,
hitFacing: Player.hitFacing,
health: Player.health,
energie: Player.energie,
healtbar: {width: Player.healthbar.width},
energiebar: {width: Player.energiebar.width},
isAttacking: Attack.isAttacking
}
];
session.publish('org.example.character.data', transferData);
Attack.isAttacking = false;
第2部分:[订阅数据]
// get player position
session.subscribe('org.example.character.data',function (args) {
var player = args[0];
var exists = false;
for (var i = 0; i < onlinePlayer.length; i++) {
if (onlinePlayer[i].uid == player.uid) {
var tmp = onlinePlayer[i];
player.sprite = tmp.sprite;
player.label = tmp.label;
player.status = tmp.status;
if (player.isAttacking && player.sprite != undefined) {
// HERE RENDER THE BALL
renderBall(player, this.game);
}
onlinePlayer[i] = player;
exists = true;
}
}
if (!exists)
onlinePlayer.push(player);
}).then(
function (sub) {
//console.log('subscribed to topic');
},
function (err) {
console.log('failed to subscribe to topic', err);
}
);
此示例适用于websocket-server,例如crossbar.io,节点库上有autobahn.js。
http://crossbar.io/docs/Quick-Start/ 但您也可以使用其他服务器
答案 1 :(得分:0)
你的问题让我想起了我过去的一个微笑的问题。我正在网上开发地图应用程序。所有客户端的Map对象必须相同(已同步)。
我是如何解决这个问题的,我已经将类库移动到服务器端并使地图对象成为单例。看看单身模式。 Singleton对象不能多次实例化。我的意思是每个游戏都会有一个球对象,客户端会用它来更新它们的本地对象。
以下是维基百科页面:https://en.wikipedia.org/wiki/Singleton_pattern
之后,在客户端做的第一件事就是获取最近的地图实例(在你的情况下是球),在服务器上修改和更新。
另一点是,多个客户端可能希望在sime时更新服务器上的共享对象。这会导致一致性问题。许多实现包括锁定变量以限制访问。其他客户端等待锁定释放和更新。
无论如何,在客户端拥有同一个对象的多个实例并不是一个好方法。