问题描述
我目前正在使用node.js和socket.io在线制作rpg。 一切正常,直到我开始制造碰撞检测系统。 我在网上寻找解决方案,发现遇到类似问题但不了解如何解决问题的人。 以下是我的代码。
客户端:
function move_character(x){
//socket.io start
var collision = io.connect('/collision');
collision.emit('detection', x);
collision.on('col', function (msg) {
if(msg == true) {
if (x == 'up') {
$('#sprite').animate({'top': '-=50px'},150);
} else if (x == 'down') {
$('#sprite').animate({'top': '+=50px'},150);
} else if (x == 'left') {
$('#sprite').animate({'left': '-=50px'},150);
} else if (x == 'right') {
$('#sprite').animate({'left': '+=50px'},150);
}
}
});
//socket.io end
}
服务器端:
var collision = io.of('/collision');
collision.on('connection', function (socket) {
socket.on('detection', function (x) {
pool.getConnection(function (err, con) {
con.query('SELECT class_state FROM gmaps LIMIT 1',
function (err, result) {
if (err) throw err;
else {
var mapState = result[0].class_state.split(",");
var x_coord = 6;
var y_coord = 5;
var id = ((y_cord -1)*10)+(x_cord -1);
var index;
if(x == 'up'){
index = id-10;
}else if(x == 'down'){
index = id+10;
}else if(x == 'left'){
index = id-1;
}else if(x == 'right'){
index = id+1;
}
collision.emit('col', true);
}
});
con.release();
});
});
});
在服务器端,emit始终发送true,并且坐标位于固定点,我这样做是为了帮助调试。 您可能还会发现目前未使用的代码,将来我会使用它,但是我想先修复此错误。
我的实际问题是,当我第一次移动角色时,一切正常,但是第二步再次执行第一步,随后进行第二步,第三步进行第一步,第二步然后是第三步。 到我将精灵移动10次时,它正在重复第10步之前的第9个步骤,并且遍及整个屏幕。
我确实尝试通过更改代码并在各处添加console.log来找到解决方案。 我发现,如果我在服务器端发出[true,x]并适当地修复客户端,则精灵将朝我想要的方向移动,但是n次,其中n是我尝试的移动次数(第1步为1 ,则4代表相同方向的第4个移动)。 刷新确实会使一切恢复正常。 我也尝试将io.connect('/ collision')移到函数之外,但这也不起作用。 看来问题出在服务器端,发射端保留了过去已发送数据的历史记录,然后在每次调用时重新发送。 也可能是客户端上的冲撞导致该错误。
同样,在服务器端,它的作用是检查数据库是否可以将所涉及的图块移至该图块,如果是,则为true,否则为false。 由于该错误,再次将其设置为true。 当错误消失后,我将完成服务器端代码。
1楼
jfriend00
1
已采纳
2015-07-25 23:21:52
您的问题是,每次调用move_character(x)
,都会使用与其关联的事件处理程序创建一个新的socket.io连接。
因此,第一次调用它时,它会连接并设置一个事件处理程序,执行emit('detection', x)
,然后设置一个事件处理程序以侦听响应。
第二次调用move_character(x)
,您将创建另一个socket.io连接并执行相同的操作。
现在,当服务器收到消息时,它将执行一些数据库工作,然后将响应广播到所有连接的套接字。
因此,既然您在同一个浏览器窗口中有两个socket.io连接,则每个连接都将获取响应,并且它会被处理多次。
第三次,您设置了另一个,依此类推...
要修复,如果您创建一个socket.io连接,然后将其用于与该名称空间的所有通信,则socket.io的工作效果最佳。
因此,将socket.io连接的创建和事件处理程序的添加move_character(x)
函数之外,因此它只发生一次。
在服务器上,我不太了解为什么您的数据库工作后向所有连接的客户端广播响应。 我认为您只想响应发送查询的连接。 您可以通过更改以下内容来做到这一点:
collision.emit('col', true);
至
socket.emit('col', true);