Socket.io 多人游戏-同步球
我正在用HTML5开发一个非常简单的游戏,带有惊人的phaser.io。游戏非常简单:一个1vs1截击游戏在2D。。。实际上,它是伟大的“皮卡丘凌空抽射”(pikachu凌空抽射)的“复制品” 正如我所说,游戏非常简单,我有:Socket.io 多人游戏-同步球,socket.io,webrtc,game-physics,phaser-framework,Socket.io,Webrtc,Game Physics,Phaser Framework,我正在用HTML5开发一个非常简单的游戏,带有惊人的phaser.io。游戏非常简单:一个1vs1截击游戏在2D。。。实际上,它是伟大的“皮卡丘凌空抽射”(pikachu凌空抽射)的“复制品” 正如我所说,游戏非常简单,我有: 玩家1 玩家2 静态元素 球 我必须控制: -球员动作 -球的运动(实际上由街机物理控制) -球员球碰撞 我这样做只是为了好玩,把我朋友的脸加入到玩家中。 这个游戏玩得很好,我和朋友玩得很开心。所以我想,为什么不让它成为在线多人游戏,这样我们就可以从不同的地点远程玩
- 玩家1
- 玩家2
- 静态元素
- 球
- 玩家1(我自己)
- 静态元素
- 遥控器
- 球
- 自有玩家
- 遥控播放器
- 静态元素
- 球
- 本地玩家移动(输入注册)->客户端将输入发送到服务器->服务器将输入发送到两个客户端->每个客户端应用移动(通过更改速度)
- 定期向服务器发送球位->服务器向客户端发送球位->客户端更新球位(使用一些插值)
- 仅在一个客户端(主客户端)中启用球物理,然后定期将球位置从“主客户端”发送到“从客户端”(可能使用webRTC)
- 重新开始,做一个真正的“权威服务器”,在服务器上安装Arcade物理(如果可能的话),在客户端安装
- 你的问题让我想起了我过去的一个问题,那是个笑脸。我在网上做一个地图应用程序。所有客户端的映射对象必须相同(已同步)
我解决这个问题的方法是将类库移动到服务器端,并使map对象成为单例对象。看看单例模式。单例对象不能实例化多次。我的意思是,每场比赛将只有一个球对象,客户端将使用它更新其本地对象
以下是维基百科页面:
在这之后,客户端要做的第一件事就是获取地图的最新实例(即您案例中的球),在服务器上进行修改和更新
另一点是,多个客户端可能希望在sime时间更新服务器上的共享对象。这将导致一致性问题。许多实现包括对变量的锁定以限制访问。其他客户端等待锁释放和更新
无论如何,在客户端拥有同一对象的多个实例不是一个好方法。要解决您的问题,您可以采用一种简单的方法, 你把玩家的攻击状态转移到服务器上, 现在,所有玩家从服务器订阅攻击信息,现在“客户”必须渲染子弹 下面是一个小代码示例 第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;
// 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);
}
);
第2部分:[订阅数据]
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;
// 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);
}
);
//获取玩家位置
session.subscribe('org.example.character.data',函数(args){
var player=args[0];
var=false;
对于(变量i=0;i
此示例适用于websocket服务器,例如在节点基础上带有autobahn.js的crossbar.io
但您也可以使用其他服务器