La matriz con varios objetos con temporizadores de expiración falla

Estoy haciendo un juego en HTML5, y ahora tengo un problema inquietante.

En mi juego tengo una matriz con todas las partículas, todas las partículas tienen temporizadores de expiración, con diferentes retrasos generados aleatoriamente.

Cuando los temporizadores de expiración caducan, eliminan su propio Objeto con la función Array.splice (), que causa problemas, ya que la función Array.splice () desordenará el orden de la Array.

Primero tuve la función como esta: (n = Partículas de sangre para engendrar, y x e y = punto de partida). (Todas las partículas se distribuyen en direcciones aleatorias desde el centro y luego se desaceleran por fricción)

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),
        })
   }
}

Luego tuve la función como esta y ya no tenía la función de empalme, por lo que no causaría problemas con el orden de los Arrays, pero sigue habiendo un problema: cuando se realiza un bucle en el array para cambiar los valores de x e y, por ejemplo, para aplicar la fricción, falla. . El error se debe a que no puede definir valores desde nulo:

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),
        })
   }
}

Tuve un problema similar al hacer temporizadores de caducidad para mi propia función de audio en el juego, pero engañé a los Errores reemplazando null con nuevo Audio (""). Dado que esto está relacionado con los objetos que no funcionan, me pregunto si podría haber una forma similar de crear objetos falsos que no devuelvan errores si no tienen el valor especificado. Un ejemplo:

Para los Objetos en este caso, esto arrojará un Error:

null.x * = fricción <---- fricción = 0.8 aunque, lanzará un Error

Pero funciona con el nuevo audio falso cuando se trata de audio:

nuevo Audio (). play () <---- No arrojará un error

¿Hay alguna manera de hacer un objeto falso que no devuelva el error si no tiene el valor especificado como en el ejemplo x? ¿O es esto de la manera incorrecta, hay tal vez otra solución que no arruine la matriz y los objetos?

Gracias.

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)
        })
    }
}

Ok finalmente!

@tewathia: ¿Es esta una buena solución o puede mejorarse? Quiero decir, ¿no existe otra forma que no sea usar "nueva función ()" para crear un objeto que pueda recuperar su propio "esto"?

Respuestas a la pregunta(1)

Su respuesta a la pregunta