简体   繁体   中英

Function not recognized as a function?

I'm in deep water at the moment. Not sure I know what I'm doing, Anyway. I'm trying to make a map for my snake game: At the moment I'm trying to add a wall but it wont work! This is the code: https://editor.p5js.org/JensHaglof/sketches/YwtUO8992

Or written out:

wallCount = 0
var walls = []
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
walls.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
function setup() {
  createCanvas(400, 400);

  for (let i = 0; i < 20; i++){
    for (let j = 0 ; j < 20 ; j++){
      if (walls[i][j] == 1){
        walls[i][j] = new Wall(walls[i]*20, walls[j]*20);
        wallCount = wallCount + 1
      }
      }
}
}

function Wall(x, y){
  this.x = x;
  this.y = y;
  rect(this.x, this.y, 20, 20);

  this.display = function(){
  fill(255, 255, 0);
  rect(this.x, this.y, 20, 20);
  }
}

function draw() {

  background(0);
  for (let i = 0 ; i < wallCount ; i++){
    for (let j = 0 ; j < wallCount ; j++){
    walls[i][j].display();
  }
  }

}

I get an error "TypeError: walls[i][j].display is not a function (sketch: line 52)"

I have no clue where to begin. I'm trying so many things but it's like I'm shooting in the dark. Anyone knows what's wrong? /Jens

You are only initializing the spots where 1 s are in your array, but your code expects the entire 2D array to contain instances of Wall .

Without understanding what you are doing, you need to check whether each object is an instance of wall

if (walls[i][j] instanceof Wall) {
  walls[i][j].display();
}

The problem is that you are trying to get the walls from the walls array which also contains zeros (bad naming). Based on your design, the first wall is not guaranteed to be at [0][0]

You should either create a separate array just for the walls:

var wallList = [];
var walls = [];

function setup() {
  createCanvas(400, 400);

  for (let i = 0; i < walls.length; i++) {
    for (let j = 0; j < walls.length; j++) {
      if (walls[i][j] == 1) {
        walls[i][j] = new Wall(walls[i] * 20, walls[j] * 20);
        wallList.push(walls[i][j]);
      }
    }
  }
}

function Wall(x, y) {
  this.x = x;
  this.y = y;
  rect(this.x, this.y, 20, 20);

  this.display = function() {
    fill(255, 255, 0);
    rect(this.x, this.y, 20, 20);
  }
}

function draw() {
  background(0);
  for (let i = 0; i < wallList.length; i++) {
    wallList[i][j].display();
  }
}

Or you should check loop through all the items and check if each one is a wall before continuing:

var walls = [];

function setup() {
  createCanvas(400, 400);

  for (let i = 0; i < walls.length; i++) {
    for (let j = 0; j < walls.length; j++) {
      if (walls[i][j] == 1) {
        walls[i][j] = new Wall(walls[i] * 20, walls[j] * 20);
      }
    }
  }
}

function Wall(x, y) {
  this.x = x;
  this.y = y;
  rect(this.x, this.y, 20, 20);

  this.display = function() {
    fill(255, 255, 0);
    rect(this.x, this.y, 20, 20);
  }
}

function draw() {
  background(0);
  for (let i = 0; i < walls.length; i++) {
    for (let j = 0; j < walls.length; j++) {
      if(walls[i][j] instanceof Wall) walls[i][j].display();
    }
  }
}

Not a solution to your problem, but something you should do nevertheless. Refactor this function

function Wall(x, y){
  this.x = x;
  this.y = y;
  rect(this.x, this.y, 20, 20);

  this.display = function(){
  fill(255, 255, 0);
  rect(this.x, this.y, 20, 20);
  }
}

into

function Wall(x, y){
  this.x = x;
  this.y = y;
  rect(this.x, this.y, 20, 20);
}

Wall.prototype.display = function() {
  fill(255, 255, 0);
  rect(this.x, this.y, 20, 20);
}

In your original code, avery call of the Wall constructor will create a new independent (even though identical to every other one) display function, which performance-wise is just bad. Use the function prototype instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM