如何将setTimeout与立即调用的函数一起正确使用
How to properly use setTimeout with immediately invoked function?
我正在制作一个游戏,如果玩家在1秒后从顶部击中敌人(即显示死亡动画),敌人将从阵列中拼接出来。
一个接一个地杀死每个敌人时效果很好,但当两个敌人同时被杀死时,就会出现问题。
例如,如果敌人在被杀时位于阵列的2号和3号位置。拼接后,位置3变为位置2。
第二个拼接不起作用,因为位置已经更改。
有没有解决这个问题或其他方法,或者我的逻辑完全无效。
for (var i = 0; i < enemies.length; i++) {
var collWithPlayer= that.collisionCheck(enemies[i], player);
if (collWithPlayer == 't') { //kill enemies if collision is from top
enemies[i].state = 'dead';
player.velY = -((player.speed));
score.totalScore += 1000;
score.updateTotalScore();
//immediately-invoked function for retaining which enemy died
(function(i){
setTimeout(function() { //show squashed enemy for a brief moment then splice
enemies.splice(i, 1);
}, 1000);
})(i);
所以我在敌人数组上使用了一个过滤函数,返回一个新数组,其中只包含还活着或只死了一段时间的敌人。
在"dead"answers"remove"之间创建延迟可以使用对象的"decay"属性来完成。您可以在每个游戏周期更新/增加此衰减属性的值。
// inside a gametick loop
var enemyCollisions = [];
enemies = enemies.filter(function (item) {
collisionWithPlayer = that.collisionCheck(item, player);
if (collisionWithPlayer === 't') {
item.state = 'dead';
item.decay = 0;
enemyCollisions.push({
direction: collisionWithPlayer,
with: item
});
}
if (typeof item.decay === 'number') {
item.decay = item.decay + 1;
}
return (item.state !== 'dead' && item.decay > 62);
});
enemyCollisions.forEach(function (item) {
if (item.direction === 't') {
player.velY = -((player.speed));
score.totalScore += 1000;
score.updateTotalScore();
} else {
//TODO deal with collisions other then 't'
}
});
使用反向for循环。
for (var i = enemies.length; i--;){
// your stuff here
// hopefully the timeout isn't necessary, or this still has a chance of not working, considering race conditions
enemies.splice(i, 1);
}
// if it is, do the timeout outside of the for loop
这样,当你拼接时,你就在你身后拼接,而不是在你面前拼接。
您也可以像下面这样过滤数组。
function myfunc(){
var enemies = [1,2,3,4,5];
var elementToRemove = 3;
enemies = enemies.filter(function(val){
return (val !== elementToRemove ? true : false);
},elementToRemove);
alert('[' + enemies.join(' , ') + ']');
}
<button id="btn" onclick="myfunc();">Go</button>
您可以简单地捕获实际的enemies[i]
对象,而不是i
,以便在完成验尸后将其从数组中正确删除,无论当时的索引是什么:
(function(e){
setTimeout(function(){
enemies.splice(enemies.indexOf(e), 1);
}, 1000);
})(enemies[i]);
相关文章:
- setTimeout可以与闭包内的函数一起使用吗
- 如何在php中创建一个函数,该函数与文本区域一起工作,通过输入类似[color:red]的内容来打印具有等效颜色的文本
- document.title函数可以't设置它与php一起工作
- Replace()产生“;未捕获的类型错误:未定义的不是函数“;当与零一起使用时
- 将3个函数合并在一起
- 将dropzone与browserfy一起使用时,$(..).dropzone不是一个函数
- 如何使函数与.onsubmit事件一起运行
- 在将 Pickadate 与 Meteor 一起使用时,未定义不是函数错误
- $location.search() 与外部函数一起使用,重置整个$scope.如何避免它
- 将 JSDoc 与匿名对象和该对象的函数一起使用的正确方法
- 两个独立工作的javascript函数,但不能一起工作
- 我需要在单击时运行两个函数.即使嵌套在一起,我也无法让它们都工作
- While循环与jquery中的某些数学函数一起崩溃
- 如何将setTimeout()与slow函数一起使用
- 水平滚动Marquee,当函数被调用时,我的文本坚持聚集在一起
- 如何使函数的别名与javascript中的new一起使用
- '对象不是函数'尝试将页面对象与Protractor一起使用时出错
- 如何将.click函数与覆盖一起使用
- 替换匹配函数给出了未定义的错误,但它与替换一起工作
- 此JavaScript函数可以单独使用,但不能与其他JavaScript函数一起使用