0

I recently used P5 to make a Flappy bird like game and up until a day ago I used to define and call my objects for my game like this:

    function setup(){
    //**Define**
      cloud1 = new Cloud(random(100, windowHeight - 500), random(0.7, 1.3));
      cloud2 = new Cloud(random(100, windowHeight - 500), random(0.7, 1.3));
    };

    function draw(){
    //**Draw Clouds**
      cloud1.show();
      cloud2.show();
    };

This works fine, but when I tried to use a for loop in the following way:

    function setup(){
    //**Define**
      for(var i = 0; i < 5; i++) {
        cloud[i] = new Cloud(random(100, windowHeight - 500), random(0.7, 1.3));
      }
    }

    function draw
    //**Draw Clouds**
      for(var i = 0; i < 5; i++) {
        cloud[i].show();
      }
    }

The debugger says that my 'cloud' object isnt defined. I have used this kind of code in a very simmilar way before without any problems. Can anyone help me?

Sorry for my bad english.

3 Answers3

1
var cloud=[];//must be global
function setup(){
  for(var i = 0; i < 5; i++) {
    cloud[i] = new Cloud(random(100, windowHeight - 500), random(0.7, 1.3));
  }
}

function draw(){
  for(var i = 0; i < cloud.length; i++) {//better like this
    cloud[i].show();
  }
}

If it has to be accessible by two functions you need to place the variable in a higher scope, and you may iterate over cloud.length elements, as hardcoded values can be overseen when changing.

Also, in such a case (without beeing in P5)my preferred setup would be like this:

function setup(num){
  var cloud=[];
  for(var i = 0; i < num; i++) {
    cloud[i] = new Cloud(random(100, windowHeight - 500), random(0.7, 1.3));
  }
  cloud.show=function(){
      this.forEach(el=>el.show());
  };
  return cloud;
}

So you could do:

clouds=setup(5);
clouds.show();
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • I know you're just building off OP's code, but please note that `setup()` is a predefined P5.js function and should not take any arguments or return anything. – Kevin Workman May 23 '17 at 21:36
1

First off, let's talk about why this works:

function setup(){
   myVariable = 'hello';
}

function draw(){
   console.log(myVariable);
}

Here, you're using the assignment operator to assign a value to a variable.

This works because when you hit the myVariable = 'hello'; line, JavaScript is going to look for a variable named myVariable in enlarging scopes (first in the setup() function, then in the global scope). When it doesn't find a variable with that name, it creates a new one in the global scope. More info on that here.

Now, let's talk about why this doesn't work:

function setup(){
   myArray[0] = 'hello';
}

function draw(){
   console.log(myArray[0]);
}

Here, you're using the index operator to index into an array named myArray. However, that variable hasn't been created yet! You could create the array first:

function setup(){
   myArray = [];
   myArray[0] = 'hello';
}

function draw(){
   console.log(myArray[0]);
}

This will work for the same reason your first code worked. The myArray = [] line first looks for a variable named myArray, and then creates a new one when it can't find it.

However, all of the above is pretty hackish code, because it's relying on JavaScript to look through the various scopes. What if there's already a myVariable variable? You're now overwriting the value, which can lead to buggy behavior. At the very least, this is an unintended side effect, so it should be avoided.

Instead, what you want to do is declare the variable yourself, using the var keyword. Since you want to access the variable inside two functions, you'd want to do that outside of both functions, like this:

var myArray = [];

function setup(){
   myArray[0] = 'hello';
}

function draw(){
   console.log(myArray[0]);
}

Now this code creates a variable named myArray and sets it equal to an empty array. Then you can use the index operator on it to set an individual index, and you can access it in multiple functions. And even better, if there is a conflict with another variable, you'll get an error warning you about that.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
-2

You need to create the empty array before you can assign to elements of it.

It's also best to declare your variables before using them.

var cloud;

function setup(){
  //**Define**
  cloud = [];
  for(var i = 0; i < 5; i++) {
    cloud[i] = new Cloud(random(100, windowHeight - 500), random(0.7, 1.3));
  }
}

function draw
  //**Draw Clouds**
  for(var i = 0; i < 5; i++) {
    cloud[i].show();
  }
}
Barmar
  • 741,623
  • 53
  • 500
  • 612