NOOB LOST, don't know single classes or non-single classes or even classes.

How do I get the invaders to move symmetrically down the y-axis? Also has anyone ever found they cannot use more than one javascript file with their index.html? If so did you correct the problem and how? I tried more than one javascript file in two editors and it did not work. I can only use one javascript file. I'm a NOOB. I'm a NOOB. Since I am a NOOBNOOB, it probably is something like I shouldn't have a setup function in the second file or something. Being a NOOB, I have no idea. All I know is it doesn't work. I tried running it in the python server localhost:8000 and it didn't work.

Anyways, does anyone know how to make the invaders go down the y-axis symmetrically in the code below? I'm a NOOB.

NOOB alert, I know nothing!!!

var invaders = [];

   function setup() {
     createCanvas(windowWidth, windowHeight);
     colorMode(HSB);
     for (var i = 0; i < 10; i++) {
     invaders[i] = new Invader(i * 60, 50);
     }
   }

  function draw() {
     background(60, 100, 100);

   var edge = false;
     for (var i = 0; i < invaders.length; i++) {
    invaders[i].display();
    invaders[i].move();
    if (invaders[i].x > width || invaders[i].x < 0) {
    edge = true;
    }
  }

  if (edge) {
    for (var i = 0; i < invaders.length; i++) {
      invaders[i].shiftDown();
    }
  }
}

function Invader(x, y) {
  this.x = x;
  this.y = y;
  this.xdir = 3;
  this.diameter = 50;
  this.display = function() {
    strokeWeight(2);
    stroke(0, 100, 100);
    noFill();
    ellipse(this.x, this.y, this.diameter, this.diameter);
    ellipse(this.x, this.y * 2.2, this.diameter, this.diameter);
    ellipse(this.x, this.y * 3.4, this.diameter, this.diameter);
    ellipse(this.x, this.y * 4.6, this.diameter, this.diameter);
    ellipse(this.x, this.y * 5.8, this.diameter, this.diameter);

  }

  this.shiftDown = function() {
    this.xdir *= -1;
    this.y += this.diameter;
 }

  this.move = function() {
    this.x = (this.x + this.xdir);
  }
}
Tagged:

Answers

  • Let's address your questions one at a time.

    How do I get the invaders to move symmetrically down the y-axis?

    We'll get back to this.

    Also has anyone ever found they cannot use more than one javascript file with their index.html?

    It's never been a problem. You don't need more than one file though.

    If so did you correct the problem and how?

    Did you add the new tab using the buttons in the Processing IDE? That or Ctrl+Shift+N should work too.

    I tried more than one javascript file in two editors and it did not work. I can only use one javascript file. It probably is something like I shouldn't have a setup function in the second file or something.

    Yes, that does sound like a problem. Even if you have multiple files (tabs) of code, you only need one setup() function. This is because all your tabs of code are really just broken up into tabs for you to keep track of things easier. In reality, all the code from every tab ends up at the same level, so you wouldn't want to define setup() twice!

    Anyways, does anyone know how to make the invaders go down the y-axis symmetrically in the code below?

    Ah, there's that first question again. Okay.

    So, what is an invader?

    Here's your code that defines an invader:

    function Invader(x, y) {
      this.x = x;
      this.y = y;
      this.xdir = 3;
      this.diameter = 50;
      this.display = function() {
        strokeWeight(2);
        stroke(0, 100, 100);
        noFill();
        ellipse(this.x, this.y, this.diameter, this.diameter);
        ellipse(this.x, this.y * 2.2, this.diameter, this.diameter);
        ellipse(this.x, this.y * 3.4, this.diameter, this.diameter);
        ellipse(this.x, this.y * 4.6, this.diameter, this.diameter);
        ellipse(this.x, this.y * 5.8, this.diameter, this.diameter);
      }
    
      this.shiftDown = function() {
        this.xdir *= -1;
        this.y += this.diameter;
      }
    
      this.move = function() {
        this.x = (this.x + this.xdir);
      }
    }
    

    We can see that an invader is an object that has the following variables:

    x: probably the x position of this object

    y: probably the y position of this object

    xdir: probably the direction this object is moving

    diameter: how big this object is

  • Your invader object also has three methods:

    move(): looks like it's updating the x position, that is, this is what moves the invader to the left or right

    shiftDown(): this looks like the function that is called when it's time for an invader to move down and change directions (probably gets called when an invader hits the end of the screen).

    display: Ah, here's the real meat of your object. This is the function that DRAWS the invader. So, one invader is a circle, right? WRONG! for some reason, ONE invader is drawing FIVE circles! That doesn't seem right! Shouldn't there be a difference between an invader and a COLUMN of invaders?

  • edited February 2017

    Also, look at WHERE the second, third, fourth, and fifth circles are being drawn - they're moved down by some MULTIPLES of the y position!

    Think about it. If the invader's first circle is at y=0, where are there rest of the circles? They'd all be at y=0 too (and would overlap)! That CAN'T be right!

  • edited February 2017 Answer ✓

    Let's fix the code so that each invader only draws ONE circle.

    var invaders = [];
    
    function setup() {
      createCanvas(windowWidth, windowHeight);
      colorMode(HSB);
      for (var i = 0; i < 10; i++) {
        invaders[i] = new Invader(i * 60, 50);
      }
    }
    
    function draw() {
      background(60, 100, 100);
    
      var edge = false;
      for (var i = 0; 
      i < invaders.length; 
      i++) {
        invaders[i].display();
        invaders[i].move();
        if (invaders[i].x > width || invaders[i].x < 0) {
          edge = true;
        }
      }
    
      if (edge) {
        for (var i = 0; i < invaders.length; i++) {
          invaders[i].shiftDown();
        }
      }
    }
    
    function Invader(x, y) {
      this.x = x;
      this.y = y;
      this.xdir = 3;
      this.diameter = 50;
      this.display = function() {
        strokeWeight(2);
        stroke(0, 100, 100);
        noFill();
        ellipse(this.x, this.y, this.diameter, this.diameter);
        //ellipse(this.x, this.y * 2.2, this.diameter, this.diameter);
        //ellipse(this.x, this.y * 3.4, this.diameter, this.diameter);
        //ellipse(this.x, this.y * 4.6, this.diameter, this.diameter);
        //ellipse(this.x, this.y * 5.8, this.diameter, this.diameter);
      }
    
      this.shiftDown = function() {
        this.xdir *= -1;
        this.y += this.diameter;
      }
    
      this.move = function() {
        this.x = (this.x + this.xdir);
      }
    }
    

    Okay. This looks good, except now we've lost a bunch of circles! Why? Well, each invader now only ever draws ONE circle. If we want those other circles back, we should add more invaders (and thus more circles)!

  • Here is the for loop that is adding your invaders:

      for (var i = 0; i < 10; i++) {
        invaders[i] = new Invader(i * 60, 50);
      }
    

    That's it. It adds 10 invaders in one row.

    Maybe you should add a second loop so that you add, say, 5 rows, instead of just one row.

    TRY THIS YOURSELF NOW. POST YOUR ATTEMPT AT IT FOR MORE HELP.

  • GOTCHAS:

    The invader's position is going to have to depend on the ROW it is in now too!

    Which invader are you adding? The index to the invaders array will have to increase for EACH invader! (You might need a new variable...)

  • Thanks Tf. I'm going to have to take a break for a bit. Later I'll go over your code and try to understand it. How do you learn this stuff?

  • Answer ✓

    Practice practice practice.

  • so are you saying this is garbage:

    //ellipse(this.x, this.y * 2.2, this.diameter, this.diameter);
    //ellipse(this.x, this.y * 3.4, this.diameter, this.diameter);
    //ellipse(this.x, this.y * 4.6, this.diameter, this.diameter);
    //ellipse(this.x, this.y * 5.8, this.diameter, this.diameter);
    

    Also I don't get this: "So, one invader is a circle, right? WRONG! for some reason, ONE invader is drawing FIVE circles!"

    I can't remember what I did? I just would get stuck, do something and move on.

    I have "invaders" and "new Invader"

    where are the five circles?

    How are "invaders" and "new Invader" different?

    What I mean is where are the circles and can I get them in a variable?

    I can't even remember what I did.

    "One invader is five circles?"

    can't I just tell the var invaders to go down the y-axis some how? That is if the circles are even in the var invaders. Are they?

    feeling stupid

  • var invaders = [];
    
    function setup() {
      createCanvas(windowWidth, windowHeight);
      colorMode(HSB);
    
      // CREATE ONE INVADER
      invaders[0] = new Invader(0 * 60, 50);
     }
    
    function draw() {
      background(60, 100, 100);
    
      //DRAW JUST ONE INVADER
      invaders[0].display();
    
    }
    
    function Invader(x, y) {
      this.x = x;
      this.y = y;
      this.xdir = 3;
      this.diameter = 50;
      this.display = function() {
    
        // FORGET ALL OTHER MOVEMENT
        // DRAW THE INVADER WHERE THE MOUSE IS
        this.x = mouseX;
        this.y = mouseY;
    
        strokeWeight(2);
        stroke(0, 100, 100);
        noFill();
        ellipse(this.x, this.y, this.diameter, this.diameter);
        ellipse(this.x, this.y * 2.2, this.diameter, this.diameter);
        ellipse(this.x, this.y * 3.4, this.diameter, this.diameter);
        ellipse(this.x, this.y * 4.6, this.diameter, this.diameter);
        ellipse(this.x, this.y * 5.8, this.diameter, this.diameter);
      }
    }
    

    Run this. I've stripped your code down to a bare minimum to try to demonstrate what the problem is. In this sketch, there is only one invader, and it is drawn where the mouse is. But even though there is just one invader, 5 circles are still drawn because your Invader object is represented visually by five circles.

    This is probably not what you want. You really one each invader to be represented by only ONE circle:

    var invaders = [];
    
    function setup() {
      createCanvas(windowWidth, windowHeight);
      colorMode(HSB);
    
      // CREATE ONE INVADER
      invaders[0] = new Invader(0 * 60, 50);
     }
    
    function draw() {
      background(60, 100, 100);
    
      //DRAW JUST ONE INVADER
      invaders[0].display();
    
    }
    
    function Invader(x, y) {
      this.x = x;
      this.y = y;
      this.xdir = 3;
      this.diameter = 50;
      this.display = function() {
    
        // FORGET ALL OTHER MOVEMENT
        // DRAW THE INVADER WHERE THE MOUSE IS
        this.x = mouseX;
        this.y = mouseY;
    
        strokeWeight(2);
        stroke(0, 100, 100);
        noFill();
        ellipse(this.x, this.y, this.diameter, this.diameter);
    
      }
    }
    
  • Okay, look, you're obviously confused. Maybe a lesson on classes would help.

    Let's say I want a sketch with a randomly placed red square in it. Here is such a sketch:

    var randomX, randomY;
    
    function setup() {
      createCanvas(windowWidth, windowHeight);
      randomX = random(0,width-20);
      randomY = random(0,height-20);
    }
    
    function draw() {
      background(0);
      fill(255,0,0);
      rect(randomX, randomY, 20, 20);
    }
    

    Now let's say I want two randomly placed squares. Okay, easy enough. Here is that sketch:

    var randomX0, randomY0;
    var randomX1, randomY1;
    
    function setup() {
      createCanvas(windowWidth, windowHeight);
      randomX0 = random(0,width-20);
      randomY0 = random(0,height-20);
      randomX1 = random(0,width-20);
      randomY1 = random(0,height-20);
    }
    
    function draw() {
      background(0);
      fill(255,0,0);
      rect(randomX0, randomY0, 20, 20);
      rect(randomX1, randomY1, 20, 20);
    }
    

    Now let's say I want 10000 randomly placed squares. I could do this:

    var randomX0, randomY0;
    var randomX1, randomY1;
    var randomX2, randomY2;
    var randomX3, randomY3;
    var randomX4, randomY4;
    var randomX5, randomY5;
    var randomX6, randomY6;
    var randomX7, randomY7;
    var randomX8, randomY8;
    var randomX9, randomY9;
    /// AND SO ON....
    

    BUT THAT WOULD BE STUPID. Instead, I would use two ARRAYs and some LOOPs:

    var randomXs = [];
    var randomYs = [];
    
    function setup() {
      createCanvas(windowWidth, windowHeight);
      for( var i = 0; i < 10000; i++){
      randomXs[i] = random(0,width-20);
      randomYs[i] = random(0,height-20);
      }
    }
    
    function draw() {
      background(0);
      fill(255,0,0);
      for( var i = 0; i < randomXs.length; i++){
        rect(randomXs[i], randomYs[i], 20, 20);
      }
    }
    
  • Hi Tf. What I did was follow along on this video:

    I'm in over my head. I appreciate your help... Maybe later when I'm not frustrated, I'll try and rewrite it all. Maybe just use a for loop to draw the circles and stay away from the constructor. Maybe I'll switch to html5 canvas.

    If I create one object, I see that as being trouble for me as I need a bunch. I'm an idiot.

    Again thanks for your help. When I feel less stupid, I'll look over your code and rewrite my failed attempt.

  • edited February 2017 Answer ✓

    Now what if I want each square to have a different color?

    Easy enough. I just need to add a new array for the random colors:

    var randomXs = [];
    var randomYs = [];
    var randomCs = [];
    
    
    function setup() {
      createCanvas(windowWidth, windowHeight);
      for ( var i = 0; i < 10000; i++) {
        randomXs[i] = random(0, width-20);
        randomYs[i] = random(0, height-20);
        randomCs[i] = color( random(255), random(255), random(255) );
      }
    }
    
    function draw() {
      background(0);
      fill(255, 0, 0);
      for ( var i = 0; i < randomXs.length; i++) {
        fill(randomCs[i]);
        rect(randomXs[i], randomYs[i], 20, 20);
      }
    }
    

    Now what if I want them to rotate at different speeds? And move in different directions? With different velocities? And different accelerations? And also some of them should be triangles. And some should be circles. And 1000 of them should be stars. And I want half of them to change to a different color after a random amount of time. And Half of those that are changing color should do so instantly, the other half should do so gradually.

    Holy shit, that would be a lot of work to add all that at once. But you could do it with enough arrays to keep track of everything:

    var randomXs = [];
    var randomYs = [];
    var randomCs = [];
    var randomRs = [];
    var randomVXs = [];
    var randomVYs = [];
    var randomAXs = [];
    var randomAYs = [];
    var random_is_triangle = [];
    var random_is_circle = [];
    var random_is_star = [];
    var random_changes_color = [];
    var random_changes_color_instantly = [];
    var random_new_goal_color = [];
    var random_old_color = [];
    var random_color_current_transition_time = [];
    var random_color_max_transition_time = [];
    /// AND SO ON...
    

    BUT THIS WOULD ALSO BE STUPID.

  • Answer ✓

    Instead, I could group all the information about one random thing together. So instead of it being in many arrays, it is all contained in one object. Like so:

    function RandomThing() {
      var x = random(0, width-20);
      var y = random(0, height-20);
      var c = color( random(255), random(255), random(255) );
    
      this.display = function() {
        fill(c);
        rect(x, y, 20, 20);
      }
    }
    
    var randomThings = [];
    
    function setup() {
      createCanvas(windowWidth, windowHeight);
      for ( var i = 0; i < 10000; i++) {
        randomThings[i] = new RandomThing();
      }
    }
    
    function draw() {
      background(0);
      for ( var i = 0; i < randomThings.length; i++) {
        randomThings[i].display();
      }
    }
    

    Now if I want to change the behavior of a RandomThing, I can do so in one place. Also, notice that all of those silly arrays have turned into a single array of my new type of object.

  • edited February 2017

    From: https://forum.Processing.org/two/discussion/20907/invaders-rows-moving-down-the-y-axis

    What I did was follow along on this video:

    Now the mystery about presenting a code w/ a class in it, and at the same time claiming of not knowing anything, is finally solved! 8-}

    That's a challenge video, not exactly an introduction to basic programming! #-o

    Indeed, @Shiffman has many series of videos & writings about programming w/ Processing and computing art generation. :)>-

    If you wanna know about programming using p5.js library, you should 1st watch his introduction tutorial serie: :-B
    https://www.youtube.com/playlist?list=PLRqwX-V7Uu6Zy51Q-x9tMWIv9cueOFTFA

    BtW, here's the source solution for the Space Invaders code challenge in p5.js: :>
    https://GitHub.com/CodingTrain/Rainbow-Code/tree/master/challenges/CC_05_Space_invaders_p5.js

  • Of course, things need not be placed randomly.

    function Invader(x, y) {
      this.x = x;
      this.y = y;
      this.c = color( random(255), random(255), random(255) );
    
      this.display = function() {
        fill(this.c);
        ellipse(this.x, this.y, 50, 50);
      }
    }
    
    var invaders = [];
    
    function setup() {
      createCanvas(windowWidth, windowHeight);
      for ( var i = 0; i < 10; i++) {
        invaders[i] = new Invader( 50 + 60 * i, 50);
      }
    }
    
    function draw() {
      background(0);
      for ( var i = 0; i < invaders.length; i++) {
        invaders[i].display();
      }
    }
    
  • Nor do you need limit yourself to one row of them:

    function Invader(x, y) {
      this.x = x;
      this.y = y;
      this.c = color( random(255), random(255), random(255) );
    
      this.display = function() {
        fill(this.c);
        ellipse(this.x, this.y, 50, 50);
      }
    }
    
    var invaders = [];
    
    function setup() {
      createCanvas(windowWidth, windowHeight);
      t = 0;
      for ( var i = 0; i < 10; i++) {
        for ( var j = 0; j < 5; j++) {
          invaders[t++] = new Invader( 50 + 60 * i, 50 + 60 * j);
        }
      }
    }
    
    function draw() {
      background(0);
      for ( var i = 0; i < invaders.length; i++) {
        invaders[i].display();
      }
    }
    
  • This should help a lot, thanks.

    Don't you need the word this.x and this.y in your code below, like in the second line of code just below var x = should it be this.x ?

    Is that RandomThing() a constructor or a class?

     function RandomThing() {
      var x = random(0, width-20);
      var y = random(0, height-20);
      var c = color( random(255), random(255), random(255) );
    
      this.display = function() {
        fill(c);
        rect(x, y, 20, 20);
      }
    }
    

    Then in your last code in your last post:

    function setup() {
      createCanvas(windowWidth, windowHeight);
      t = 0;
      for ( var i = 0; i < 10; i++) {
        for ( var j = 0; j < 5; j++) {
          invaders[t++] = new Invader( 50 + 60 * i, 50 + 60 * j);
     }
    }
    

    why do you use t=0; why not invaders[i] instead of [t++] or invaders[i,j]. Maybe it is a place holder as you have an i and a j.

    I guess what I should do is go write a few of these constructors and make them do a bunch of stuff with variables in the constructor. Then use a for loop and an array to create a bunch of them?

    In a sense you make an object with the constructor and then grab it with a for loop and an array, right?

    I'll have to keep going over this code until I can do it in my sleep.

    I have been reluctant to look at constructors on youtube because I was worried it would be different outside the canvas... but I think that's what I will do.

    Thank you, :-h

  • Not invaders[i] anymore, because I can no longer use the position in a row for an invader as the index into the array of invaders. This is because the invades in the next row share the same position in the row, but need to be a new index.

    Basically you're numbering the invaders like this:

    00 01 02 03 04 05 06 07 08 09
    10 11 12 13 14 15 16 17 18 19
    20 21 22 23 24 25 26 27 28 29
    30 31 32 33 34 35 36 37 38 39
    //etc
    

    These are the numbers that the variable t uses. So for 5 rows of 10 invaders, you're going to need indexes 0 to 49, right? You can't just use 0 to 9 five times, because you'd be overwriting the invaders from previous rows when you create ones for the later rows.

Sign In or Register to comment.