p5. js - невозможно прочитать мою функцию обновления в случайную точку во время выполнения программы - PullRequest
1 голос
/ 28 апреля 2020

Я пытаюсь создать программу, в которой частицы, сгенерированные на левом краю холста, удаляются из массива (используя сращивание), когда они достигают правого конца холста.

let P = [];
let n = 10;

function setup() 
{
    createCanvas(500,500);
    for(let i = 0; i < n; i++)
        P.push(new particle());
}

function draw() 
{
    background(0);
    for(let i = 0; i < n; i++)
    {
        if(P[i].out == true)
        {
            P.splice(i, 1);
            n--;
        }
        P[i].update();     
        P[i].plot();
        console.log(P.length)
    }   
}

class particle
{
    constructor()
    {
        this.brightness = 0;
        this.vel = random(1);
        this.dia = 3;
        this.x = 0;
        this.y = random(height);
        this.out = false;
    }

    update()
    {
        this.x += this.vel;
        if(this.x >= width)
            this.out = true;
    }

    plot()
    {
        noStroke();
        fill(255);
        circle(this.x, this.y, this.dia);
    }  
}

Программа, кажется, работает нормально по большей части, когда она работает. Чтобы убедиться, что элементы в массиве действительно удаляются, я попытался записать длину массива. Когда я запускаю его, элементы удаляются, когда они достигают правого края холста, но когда размер массива уменьшается примерно до 30% или около того (каждый раз, когда я его запускаю, он меняется), я получаю эту ошибку:

Uncaught TypeError: Невозможно прочитать свойство 'update' с неопределенным значением

Я озадачен этим, потому что я не понимаю, как функция обновления не может быть прочитана, когда она имеет уже использовался несколько раз в l oop ранее.

Ответы [ 2 ]

2 голосов
/ 28 апреля 2020

Проблема в том, что вы удаляете элементы из массива, пока вы выполняете итерацию по массиву. Примечание P.splice(i, 1); удаляет элемент из массива, если это был последний элемент в массиве, тогда P[i].update(); получает доступ к массиву за пределами. Это приводит к ошибке «Uncaught TypeError: Невозможно прочитать свойство 'update' of undefined"

Я рекомендую обойти массив сзади:
(См. Также Цикл массив и удаление элементов без разбивки на l oop)

let i = P.length;
while (i--) {
    if (P[i].out == true) {
        P.splice(i, 1);
        n--;
    } else {
        P[i].update();     
        P[i].plot();
    }
}

См. пример:

let P = [];
let n = 10;

function setup() 
{
    createCanvas(500,500);
    for(let i = 0; i < n; i++)
        P.push(new particle());
}

function draw() 
{
    background(0);

    let i = P.length;
    while (i--) {
        if (P[i].out == true) {
            P.splice(i, 1);
        } else {
            P[i].update();     
            P[i].plot();
        }
    }   
}

class particle
{
    constructor()
    {
        this.brightness = 0;
        this.vel = random(1);
        this.dia = 3;
        this.x = 0;
        this.y = random(height);
        this.out = false;
    }

    update()
    {
        this.x += this.vel;
        if(this.x >= width)
            this.out = true;
    }

    plot()
    {
        noStroke();
        fill(255);
        circle(this.x, this.y, this.dia);
    }  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
1 голос
/ 28 апреля 2020

Поскольку вы удаляете элементы из массива, вам нужно перебрать его в обратном порядке:

function draw() {
    background(0);
    for(let i = n - 1; i >= 0; i--) {
        if(P[i].out == true) {
            P.splice(i, 1);
            n--;
        }

        P[i].update();     
        P[i].plot();
        console.log(P.length)
    }   
}
...