具有多个具有过期计时器的对象的阵列失败



我正在用HTML5制作一个游戏,现在我遇到了一个令人不安的问题。

在我的游戏中,我有一个包含所有粒子的数组,所有粒子都有过期计时器,具有不同的随机生成延迟。

当过期计时器到期时,他们会使用Array.splice()函数删除自己的Object,这会造成麻烦,因为Array.splace()函数会打乱Array的顺序。

首先,我有这样的功能:(n=要生成的血液粒子,x和y=起点。)(所有粒子从中间向随机方向扩散,然后通过摩擦减速)

function spawnBlood(x, y, n) {
for (var i = 0; i < n; i++) {
var tetra = Math.floor(Math.random() * 360) * (180 / Math.PI)
var speed = Math.floor(Math.random() * 4) + 3
var j = particles.length
particles.push({
x: x,
y: y,
vx: Math.cos(tetra) * speed,
vy: Math.sin(tetra) * speed,
r: 1.5,
angle: 0,
expireTimer: setTimeout(function(j) {
return function() {
particles.splice(j, 1)
}
}(j), Math.floor(Math.random() * 500) + 500),
})
}
}

然后我有了这样的函数,不再有拼接函数,这样就不会给数组顺序带来麻烦,但仍然有一个问题,当循环遍历数组以更改x和y值时,例如应用摩擦力时,它失败了。失败的原因是它无法从null定义值:

function spawnBlood(x, y, n) {
for (var i = 0; i < n; i++) {
var tetra = Math.floor(Math.random() * 360) * (180 / Math.PI)
var speed = Math.floor(Math.random() * 4) + 3
particles.push({
x: x,
y: y,
vx: Math.cos(tetra) * speed,
vy: Math.sin(tetra) * speed,
r: 1.5,
angle: 0,
expireTimer: setTimeout(function(i) {
return function() {
particles[i] = null
for (var j = 0; j < particles.length; j++) {
if (particles[particles.length - 1] == null) {
particles.splice(particles.length - 1, 1)
}
}
}
}(i), Math.floor(Math.random() * 500) + 500),
})
}
}

我在游戏中为自己的音频功能制作过期计时器时也遇到了类似的问题,但通过用新的音频(")替换null来欺骗错误。由于这与不起作用的对象有关,所以我想知道是否有类似的方法可以制作假对象,如果它们没有指定的值,则不会返回错误。一个例子:

对于这种情况下的对象,这将抛出错误:

null.x*=摩擦力<----摩擦力=0.8,将抛出错误

但当它涉及音频时,它可以使用伪造的新音频:

new Audio().play()<----不会抛出错误

有没有什么方法可以制作一个假对象,如果它没有像示例x中那样指定的值,就不会返回错误?或者这是错误的方式,是否有其他解决方案不会弄乱数组和对象?

谢谢。


function spawnBlood(x, y, n) {
for (var i = 0; i < n; i++) {
var tetra = Math.floor(Math.random() * 360) * (180 / Math.PI)
var speed = Math.floor(Math.random() * 4) + 3
particles.push(new function() {
this.x = x
this.y = y
this.vx = Math.cos(tetra) * speed
this.vy = Math.sin(tetra) * speed
this.r = 1.5
this.angle = 0
this.expireTimer = setTimeout(function(self) {
return function() {
particles.splice(particles.indexOf(self), 1)
}
}(this), Math.floor(Math.random() * 500) + 500)
})
}
}

终于好了!

@tewathia-这是一个好的解决方案还是可以改进,我的意思是,除了使用"new function()"来创建一个可以检索自己的"this"的对象之外,没有其他方法吗?

您是否尝试保留一个虚拟对象(所有属性都设置为0)来代替要删除的粒子元素?用替换particles[i] = null

particles[i] = {
x: 0,
y: 0,
vx: 0,
vy: 0,
r: 0,
angle: 0
};

另一种解决方案可能是保留particles[i] = null行,但修改代码,将摩擦力应用于xy,以检查有问题的对象是否具有这些属性。

if(particles[i].hasOwnProperty('x') && particles[i].hasOwnProperty('y')){
//apply friction
}

最新更新