Search code examples
javascriptundefinedp5.js

Why does JavaScript defines the vector as vector and as undefined at the same time?


So, I've tried to define a class where a shape of a bird would show up, then move and leave a trail. This bird is made with the help of curveVertex, it moves according to Perlin noise and it should save data of previous positions into the 'history' array. But when I try to refer to an object in the array, the error comes up:

Uncaught TypeError: Cannot read properties of undefined (reading 'x')"

But when I check this object with the help of console.log, console shows it's numeric value and 'undefined' at the same time...

error image

class Bird {
  constructor(x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, xend, yend) {
    this.x0 = x0;
    this.y0 = y0;
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    this.x3 = x3;
    this.y3 = y3;
    this.x4 = x4;
    this.y4 = y4;
    this.x5 = x5;
    this.y5 = y5;
    this.xend = xend;
    this.yend = yend;

    this.history = [];

    this.t = 0;
  }

  update() {

    let r = noise(this.t + 5.2);
    let r2 = noise(this.t + 5.19);
    let r3 = noise(5 + this.t);
    let r5 = noise(5 + this.t);

    this.x0 = this.x0 + r;
    this.y0 = this.y0 + r;
    this.x1 = this.x1 + r2;
    this.y1 = this.y1 + r2;
    this.x2 = this.x2 + r3;
    this.y2 = this.y2 + r3;
    this.x3 = this.x3 + r;
    this.y3 = this.y3 + r;
    this.x4 = this.x4 + r5;
    this.y4 = this.y4 + r5;
    this.x5 = this.x5 + r;
    this.y5 = this.y5 + r;
    this.xend = this.xend + r;
    this.yend = this.yend + r;


    this.t += 0.005;

    let v0 = createVector(this.x0, this.y0);
    let v1 = createVector(this.x1, this.y1);
    let v2 = createVector(this.x2, this.y2);
    let v3 = createVector(this.x3, this.y3);
    let v4 = createVector(this.x4, this.y4);
    let v5 = createVector(this.x5, this.y5);
    let vend = createVector(this.xend, this.yend);

    this.history.push(v0, v1, v2, v3, v4, v5, vend);


    if (this.history.length > 700) {
      this.history.splice(0, 1);
    }


  }

  show() {
    strokeWeight(1);
    stroke(255);
    beginShape();
    for (let i = 0; i < this.history.length; i++) {
      let pos0 = this.history[i];
      let pos1 = this.history[i + 1];
      let pos2 = this.history[i + 2];
      let pos3 = this.history[i + 3];
      let pos4 = this.history[i + 4];
      let pos5 = this.history[i + 5];
      let posend = this.history[i + 6];

      console.log(posend); //                   **LINE 88**

      noFill();

      curveVertex(pos0.x, pos0.y);
      curveVertex(pos1.x, pos1.y);
      curveVertex(pos2.x, pos2.y);
      curveVertex(pos3.x, pos3.y);
      curveVertex(pos4.x, pos4.y);
      curveVertex(pos5.x, pos5.y);
      curveVertex(posend.x, posend.y);
      endShape();

    }


    beginShape();
    curveVertex(this.x0, this.y0);
    curveVertex(this.x1, this.y1);
    curveVertex(this.x2, this.y2);
    curveVertex(this.x3, this.y3);
    curveVertex(this.x4, this.y4);
    curveVertex(this.x5, this.y5);
    curveVertex(this.xend, this.yend);
    endShape();


  }
}

let bird;

function setup() {
  createCanvas(displayWidth, displayHeight);

  bird = new Bird(800, 560, 700, 350, 600, 250, 700, 300, 790, 240, 700, 350, 450, 500);

}

function draw() {
  background(70);
  bird.show();
  bird.update();
}

Solution

  • I think the problem is in your show function.

    You are trying to access a position in the array that doesn't exist.

    for (let i = 0; i < this.history.length; i++) {
                    let pos0 = this.history[i];
    // The below positions are out of bounds once i reaches this.history.length-1
                    let pos1 = this.history[i+1]; 
                    let pos2 = this.history[i+2];
                    let pos3 = this.history[i+3];
                    let pos4 = this.history[i+4];
                    let pos5 = this.history[i+5];
                    let posend = this.history[i+6];
    

    You can change the loop condition, making sure you don't access values that don't exist.

    for (let i = 0; i < this.history.length - 6; i++) {