我想在我的平铺游戏中实现角色移动,这样它就不会通过关键事件向服务器发送垃圾邮件。目前,我已使用setInterval限制了发送的事件数量。
我的想法出现问题:
如果玩家没有在合适的时间点按某个键,则该动作可能无效
连续点击一个键(例如右箭头),只会在setInterval拾取事件时发送键事件。这使它看起来很麻烦。
我的代码很好:
如果你所做的只是拿着钥匙,那就完美了。
您可以通过一次按住两个键来对角移动。代码存储了正在按下的键。
可能会有所帮助的事情:
以下是我的代码的简要基本示例:http://jsfiddle.net/empXx/66/
var canvas = document.getElementById('c'),
ctx = canvas.getContext("2d"),
tileSize = 10;
var holdingUp = false;
var holdingDown = false;
var holdingLeft = false;
var holdingRight = false;
var cx = 150;
var cy = 150;
$(document).keydown(function(e) {
if(e.which==37) { holdingLeft = true; }
if(e.which==38) { holdingUp = true; }
if(e.which==39) { holdingRight = true; }
if(e.which==40) { holdingDown = true; }
});
$(document).keyup(function(e) {
if(e.which==37) { holdingLeft = false; }
if(e.which==38) { holdingUp = false; }
if(e.which==39) { holdingRight = false; }
if(e.which==40) { holdingDown = false; }
});
ctx.fillRect(150, 150, tileSize, tileSize);
setInterval(function() {
if(holdingUp) {
cls();
ctx.fillRect(cx, cy - tileSize, tileSize, tileSize);
cy -= tileSize;
} else if(holdingDown) {
cls();
ctx.fillRect(cx, cy + tileSize, tileSize, tileSize);
cy += tileSize;
}
if(holdingLeft) {
cls();
ctx.fillRect(cx - tileSize, cy, tileSize, tileSize);
cx -= tileSize;
} else if(holdingRight) {
cls();
ctx.fillRect(cx + tileSize, cy, tileSize, tileSize);
cx += tileSize;
}
}, 120);
function cls() { ctx.clearRect(0, 0, canvas.width, canvas.height); }
如何让这个游戏互动更顺畅,让用户更加愉快,同时降低垃圾邮件的数量?
答案 0 :(得分:0)
感谢John S的原始修复。我稍微修改了代码以使其更好。目前,如果用户左右握住,则玩家将不会移动。这是一个比处理键优先级更简单的解决方案,具体取决于按下的顺序。我也这样做,以便upCount / downCount等,当holdUp& holdingDown是活跃的。左右动作相同。
简化jsfiddle with bare basics here
实施此代码的生产游戏+反垃圾邮件/作弊检测是here
JSFiddle代码,根据SO的要求:
var canvas = document.getElementById('c'),
ctx = canvas.getContext("2d"),
tileSize = 10;
var holdingUp = false;
var holdingDown = false;
var holdingLeft = false;
var holdingRight = false;
var cx = 150;
var cy = 150;
var upCount = 0;
var downCount = 0;
var leftCount = 0;
var rightCount = 0;
$(document).keydown(function(e) {
if(e.which==37 && !holdingLeft) { holdingLeft = true; leftCount++; }
if(e.which==38 && !holdingUp) { holdingUp = true; upCount++; }
if(e.which==39 && !holdingRight) { holdingRight = true; rightCount++; }
if(e.which==40 && !holdingDown) { holdingDown = true; downCount++; }
});
$(document).keyup(function(e) {
if(e.which==37) { holdingLeft = false; }
if(e.which==38) { holdingUp = false; }
if(e.which==39) { holdingRight = false; }
if(e.which==40) { holdingDown = false; }
});
ctx.fillRect(150, 150, tileSize, tileSize);
setInterval(function() {
if(!(holdingUp && holdingDown)) {
if((upCount > 0) || holdingUp) {
if (upCount > 0) { upCount--; }
cls();
ctx.fillRect(cx, cy - tileSize, tileSize, tileSize);
cy -= tileSize;
} else if((downCount > 0) || holdingDown) {
if (downCount > 0) { downCount--; }
cls();
ctx.fillRect(cx, cy + tileSize, tileSize, tileSize);
cy += tileSize;
}
} else {
downCount = upCount = 0;
}
if(!(holdingLeft && holdingRight)) {
if((leftCount > 0) || holdingLeft) {
if (leftCount > 0) { leftCount--; }
cls();
ctx.fillRect(cx - tileSize, cy, tileSize, tileSize);
cx -= tileSize;
} else if((rightCount > 0) || holdingRight) {
if (rightCount > 0) { rightCount--; }
cls();
ctx.fillRect(cx + tileSize, cy, tileSize, tileSize);
cx += tileSize;
}
} else {
leftCount = rightCount = 0;
}
}, 120);
function cls() { ctx.clearRect(0, 0, canvas.width, canvas.height); }