TypeError: undefined is not an object (evaluating 'bunker.x')

Hello, does anyone know how I can get the computer to understand my bunker x, y variables? I would rather use other.x, other.y. other.r than bunker.x, bunker.y, and bunker.r but either way I'm lost.

var bunkers = [];
var b1;

function setup() {
      createCanvas(window.innerWidth, window.innerHeight);
      b1 = new Bubble(250, 200);
        for (var i = 0; i < 4; i++){
           bunkers[i] = new Bunker(i*294 + 247, height-140);
   }
}

function draw() {
      background(0);

      for (var i = 0; i < 4; i++){
            bunkers[i].show();
  }
      b1.update();
      b1.display();

      if (b1.intersects(bunkers[i])){
            bunkers[i].changeColor();
    }
}
function Bubble(x, y) {
      this.x = x;
      this.y = y;
      this.r = 48;
      this.col = color(255);
      this.changeColor = function() {
            this.col = color(random(255), random(255), random(255))

    }
      this.display = function() {
            stroke(255);
            fill(this.col);
            ellipse(this.x, this.y, this.r * 2, this.r * 2);

    }

       this.intersects = function(bunker) {
             var d = dist(this.x, this.y, bunker.x, bunker.y);
       if (d < this.r + bunker.r) {
                  return true;
        } else {
                  return false;

        }
 }

       this.update = function() {
            this.x = this.x + random(-5, 5);
            this.y = this.y + random(-5, 5);

    }

}

function Bunker(x, y) {
       this.x = x;
      this.y = y;
      this.r = 60;
       this.show = function(){
          push();
          translate(this.x-257, this.y-68);
          noStroke();
          fill(0, 100, 0);
          beginShape();
          vertex(200, 50);
          vertex(208, 50);
          vertex(208, 42);
          vertex(216, 42);
          vertex(216, 34);
          vertex(224, 34);
          vertex(224, 26);
          vertex(290, 26);
          vertex(290, 34);
          vertex(298, 34);
          vertex(298, 42);
          vertex(306, 42);
          vertex(306, 50);
          vertex(314, 50);
          vertex(314, 110);
          vertex(290, 110);
          vertex(290, 102);
          vertex(282, 102);
          vertex(282, 94);
          vertex(274, 94);
          vertex(274, 86);
          vertex(240, 86);
          vertex(240, 94);
          vertex(232, 94);
          vertex(232, 102);
          vertex(224, 102);
          vertex(224, 110);
          vertex(200, 110);
          endShape(CLOSE);
          pop();
   } 
}

Answers

  • edited March 2017

    ... to understand my Bunker's x, y, r variables?

    • Word variable is the most generic term to refer to those labeled limited portions of memory.
    • But when a variable belongs to an object in JS, they have a more specific term: property.
    • In the same vein, functions are also called methods when they belong to an object.
    • And constructor or class, when they're utilized to create an instance object.
    • In your code, b1 is a variable which stores the reference to an instantiated object of constructor or class Bubble: b1 = new Bubble(250, 200);
    • From that b1 variable, we can access all of the members of the instantiated object, i.e. properties & methods, via the . dot operator.
    • From what I understand from your request, you wanna change something like if (d < this.r + bunker.r) { to if (d < this.r + other.r) { inside Bubble::intersects() method, right?
    • Given bunker is merely a parameter (a variable declared inside a function's parens), you just need to rename it to other: function (bunker) { to function (other) {.
    • Now you can access properties x, y, r and call all of its methods from parameter named other rather than its previous name bunker. <:-P
  • Hi GoTo, this isn't my real code. What I'm having problems with is I can't seem to get any objects to recognize the bunker object(s). I'm trying to get hit detection... but the other objects just roll over the bunkers without hit detection. Could it be something to do with the translate method? Does the computer know where the bunkers are? The error says: undefined is not an object (evaluating 'bunker.x') but bunker is an object isn't it?

  • edited March 2017 Answer ✓

    Could it be something to do with the translate() method?

    • If you rely on any p5's method which changes its canvas' matrix, you're making things much harder to check collisions. #:-S
    • My advise is to simply quit using any of them if you can! :-\"

    ... but bunker is an object, isn't it?

    • Inside Bubble::intersects(bunker) method, bunker is its parameter.
    • As a parameter, it expects to receive an argument value passed to it when it's invoked.
    • This is the statement which invokes it: if (b1.intersects(bunkers[i])) {.
    • I can see you're relying on variable i in order to get a Bunker object from bunkers[] array, and pass it as an argument to Bubble::intersects(bunker) method via variable b1.
    • However, that statement is outside the for ( ; ; ) {} loop in which i is its variable iterator! :-O
    • Another bug is Bunker doesn't have any method called changeColor()! However Bubble does! 8-}
    • And also a quirk: Bunker got method show(). While in Bubble it's called display()! =P~
    • You should be more consistent about naming your methods. :-B
    • Assuming now Bunker got a changeColor() method as well, here's a much safer approach to iterate over the bunkers[] array, and access each of its stored Bunker object references: *-:)

    for (const b of bunkers) {
      b.show();
      b1.intersects(b) && b.changeColor();
    }
    
  • "If you rely on any p5's method which changes its canvas' matrix, you're making things much harder to check collisions."

    I think I should learn how not to use the translate method. I've noticed that with canvas no one seems to make horses et cetera, not in tutorial videos anyways... Is there some other way for p5 to make designs like the space invader aliens et cetera without using the translate method? I think the pVector maybe?

    Thank you,

  • When not using translate(), coords. (x=0, y=0) is the top-left pixel of the canvas.

  • Yes, the thing is I'm lost because I don't know how to move the objects around without the translate. I'm totally knew. I'm going to have to try to understand it. Whatever that means...

  • edited March 2017

    You move your "sprites" around by changing their x & y properties.
    Let's have some base class called Actor w/ the most common properties for location, dimension, velocity & color:

    class Actor {
      constructor(x, y, w, h, sx, sy, c) {
        this.x = x, this.y = y;
        this.w = w, this.h = h;
        this.vx = sx, this.vy = sy;
        this.c = c;
      }
    }
    

    Now let's have a class Alien which extends from Actor, adding display(), update() & victory() methods to it:

    class Alien extends Actor {
      constructor(x, y, w, h, sx, sy, c) {
        super(...arguments);
      }
    
      display() {
        rect(this.x, this.y, this.w, this.h);
      }
    
      update() {
        this.x += this.vx, this.y += this.vy;
        this.x > width  - this.w && (this.vx *= -1);
        this.y > height - this.h && this.victory();
      }
    
      victory() {
        print('Your planet has been invaded by ' + this);
        noLoop();
      }
    }
    

    Of course you can have other classes inheriting from the base class Actor if that makes sense too.
    Then implement their own particular methods or other properties in addition to parent Actor's.
    BtW, learn more about JS classes at the links below: :bz

    1. https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class
    2. https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
  • edited March 2017

    You know what I'd love to know? Can I pick this bunker object up and move it around on my canvas? It may be simple for some people but I have no idea on how to do it? Is it simple? I was hoping to make my own designs rather than use sprites.

    function bunker(x, y){ 
        this.x = x;
        this.y = y;
        push();
        noStroke();
        fill(0, 100, 0); 
        beginShape();
        vertex(200, 50);
        vertex(208, 50);
        vertex(208, 42);
        vertex(216, 42);
        vertex(216, 34);
        vertex(224, 34);
        vertex(224, 26);
        vertex(290, 26);
        vertex(290, 34);
        vertex(298, 34);
        vertex(298, 42);
        vertex(306, 42);
        vertex(306, 50);
        vertex(314, 50);
        vertex(314, 110);
        vertex(290, 110);
        vertex(290, 102);
        vertex(282, 102);
        vertex(282, 94);
        vertex(274, 94);
        vertex(274, 86);
        vertex(240, 86);
        vertex(240, 94);
        vertex(232, 94);
        vertex(232, 102);
        vertex(224, 102);
        vertex(224, 110);
        vertex(200, 110);
        endShape(CLOSE);
        pop(); 
    }
    
  • edited March 2017 Answer ✓

    A more practical approach would be to render all of those vertex() inside a p5.Graphics created via createGraphics() w/ just enough width & height to fit in the whole "sprite": *-:)

    1. http://p5js.org/reference/#/p5.Graphics
    2. http://p5js.org/reference/#/p5/createGraphics

    Once created, just display it into canvas via image(): http://p5js.org/reference/#/p5/image

  • Answer ✓

    Here's a silly space invader made outta rect(), but written in Java Mode:
    http://studio.ProcessingTogether.com/sp/pad/export/ro.9Iaf6privOouM/latest

    After turning it into a p5.Image or p5.Graphics, you can move it around via image(). :-h

Sign In or Register to comment.