虽然这里的每个人都是对的,但他们缺少的是你需要延迟开火,而不是延迟被调用的事件......
在您的 keydown 事件中,设置一个时间戳,为该事件设置一个先前时间和一个当前时间。在函数内部,有一个 time_limit。
因此,当您按下该键(或它反复触发)时,请检查:
current_time - last_fired >= rate_limit;
如果当前时间距离上一次射击超过 3000 毫秒,则将last_fired
时间戳设置为当前时间,然后开火。
编辑
考虑这个简单的例子:
var Keyboard = {};
var player = (function () {
var gun = {
charging : false,
lastFired : 0,
rateLimit : 3000
},
controls = { shoot : 75 },
isHit = false,
public_interface;
function shoot () {
var currentTime = Date.now();
if (gun.rateLimit > currentTime - gun.lastFired) { return; }
/* make bullet, et cetera */
gun.lastFired = currentTime;
}
function update () {
if (Keyboard[controls.shoot] || gun.charging) { this.shoot(); }
// if key was released before this update, then the key is gone...
// but if the gun was charging, that means that it's ready to be fired
// do other updates
}
function draw (ctx) { /* draw player */ }
public_interface = {
shoot : shoot,
damage : function (amt) { isHurt = true; /* rest of your logic */ }
draw : draw,
update : update
};
return public_interface;
}());
document.addEventListener("keydown", function (e) {
// if key is already down, exit
if (!!Keyboard[e.keyCode]) { return; }
// else, set the key to the time the key was pressed
// (think of "charging-up" guns, based on how long you've held the button down)
Keyboard[e.keyCode] = e.timeStamp;
});
document.addEventListener("keyup", function (e) { delete Keyboard[e.keyCode]; });
在你的游戏循环中,你现在要做一些不同的事情:
你的玩家将自我更新。
在该更新中,它询问键盘是否按下了拍摄键。
如果是,那么它会调用 shoot 方法。
这仍然不是 100%正确,因为玩家不应该关心或知道键盘。
它应该通过某种服务来处理,而不是要求window.Keyboard
. 不管...
您的控件现在被包裹在播放器内部——因此您可以定义这些控件是什么,而不是到处询问keyCode
。
您的事件现在正在做他们应该做的事情:设置密钥并离开。
在您当前的迭代中,每次浏览器触发时,可能是300xkeydown
/sec,如果它愿意,该事件还必须调用您的所有播放器逻辑... 300x/sec...
在更大的游戏中,您可以更进一步,用 and 制作组件Controls
,Health
每个组件都具有完成自己工作所需的所有属性和方法,仅此而已。
以这种方式分解代码也会使拥有不同的枪支变得非常简单。
想象一个Inventory
组件:
库存包含不同的guns
.
每个gun
人都有自己的rateLimit
,有自己的lastFired
,有自己的bulletCount
,做自己的,自己damage
开火bulletType
。
所以你会打电话player.shoot();
,在里面,它会打电话inventory.equipped.shoot();
。
该内部函数将负责射击装备好的枪的所有逻辑(因为你会inventory.add(Gun);
使用你的枪和inventory.equip(id);
你想要的枪。