Question About Random Positioning

Hi there,

I'm completely new to this (I'm sure you old pros have heard this many times, and I apologize!), I'm just trying to do an assignment for a programming class which is required for my degree programme. The assignment involves making 20 shapes appear in random positions on the screen, and then when you click anywhere, they go to new random positions.

Wanting to be all impressive, I of course made this harder than it has to be. I made a skull, which is a collection of several 2D primitive shapes, using the code from chapter 8 of the book "Getting Started With Processing" as an example. (The code uses translate(), pushMatrix() and popMatrix() to draw owls).

So this is what I wrote...

void setup () {
  size(500, 500);
  background(0);
  smooth();
}

void draw() {
  int posX, posY;
  posX = int(random(width-70));
  posY = int(random(height-80));
  background(0);
  noStroke();

  for (int i=0; i<20; i=i+1) {
    skull(posX,posY);
  }
 }

void skull (int x, int y) {
  pushMatrix();
  translate(x,y);

  fill(255);
  ellipse(35,35,70,70);
  rect(17,65,36,15);

  fill(0);
  ellipse(18,35,17,25);
  ellipse(52,35,17,25);  

  triangle(27,51,32,51,32,61);
  triangle(38,51,43,51,38,61);

  rect(23,65,3,15);
  rect(33,65,3,15);
  rect(43,65,3,15);
  popMatrix();
}

So the code works so far as spitting out skulls in random positions on the screen, but they don't stop. They should stop when there are 20 skulls on the screen. I've probably made some silly mistake, but I can't figure it out, so I would be super super appreciative of your help!!

While I'm at it, I might as well ask; what would be the best way to take the next step and make the skulls change to new random positions whenever the mouse is clicked?

By the way, I'm on Mac OSX 10.6.8 and I'm running Processing 2.0.3.

Thank you so much!

Answers

  • edited November 2013 Answer ✓

    The problem is caused because you are not familiar with how Processing works.

    When a sketch starts it first executes the instructions in setup(). As the name suggests this is used to create / initialise anything that we might want to use e.g. load images, initialise variables etc.

    There are two possibilities after setup() is finished. If there is no draw() method then the sketch stops, but if there is a draw method then then program execution goes into an infinite loop (stops when the sketch window is closed). During each iteration of the loop (~60 times per second) the draw() method is executed, after that the display is updated and you can see what has been drawn during draw().

    So your draw method is being executed 60 times/second so lets see what it does.

    Line

    8 declares two local variables, posX and posY (only available inside the draw method)

    9 & 10 will calculate random values and store them in these variables

    11 clears the display to black

    12 switches off the drawing lines /shape edges

    14-16 this is the interesting bit because it draws 20 skulls, BUT since posX and posY never change inside the loop they are ALL drawn in the same position.

    Each skull you see on the screen is in fact 20 skulls drawn in the same position and the flickering is the draw method being executed 60 times a second.

    In the code below I have simply moved lines 9 & 10 inside the for loop so that each skull has a random position. I have also used frameRate1) to set the loop to one iteraction per second. If you run the program you will see 20 random skulls changing position every second.

    Good luck with your assignment.

    void setup () {
      size(500, 500);
      background(0);
      smooth();
      frameRate(1);
    }
    
    void draw() {
      int posX, posY;
      background(0);
      noStroke();
    
      for (int i=0; i<20; i=i+1) {
        posX = int(random(width-70));
        posY = int(random(height-80));
        skull(posX, posY);
      }
    }
    
    void skull (int x, int y) {
      pushMatrix();
      translate(x, y);
    
      fill(255);
      ellipse(35, 35, 70, 70);
      rect(17, 65, 36, 15);
    
      fill(0);
      ellipse(18, 35, 17, 25);
      ellipse(52, 35, 17, 25); 
    
      triangle(27, 51, 32, 51, 32, 61);
      triangle(38, 51, 43, 51, 38, 61);
    
      rect(23, 65, 3, 15);
      rect(33, 65, 3, 15);
      rect(43, 65, 3, 15);
      popMatrix();
    }
    
  • edited November 2013 Answer ✓

    You can use noLoop() to halt draw(). Then put redraw() inside mousePressed() to go for 1 draw() round! >:/

    // forum.processing.org/two/discussion/1042/
    // question-about-random-positioning
    
    void setup () {
      size(500, 500);
      noLoop();
    
      smooth(4);
      noStroke();
    }
    
    void mousePressed() {
      redraw();
    }
    
    void keyPressed() {
      redraw();
    }
    
    void draw() {
      clear();
    
      for (int i=0; i!=20; ++i)
        skull((int) random(width-70), (int) random(height-80));
    }
    
    void skull(int x, int y) {
      translate(x, y);
    
      fill(-1);
      ellipse(35, 35, 70, 70);
      rect(17, 65, 36, 15);
    
      fill(0);
      ellipse(18, 35, 17, 25);
      ellipse(52, 35, 17, 25);  
    
      triangle(27, 51, 32, 51, 32, 61);
      triangle(38, 51, 43, 51, 38, 61);
    
      rect(23, 65, 3, 15);
      rect(33, 65, 3, 15);
      rect(43, 65, 3, 15);
    
      resetMatrix();
    }
    
  • Thank you so much to both of you! I've got it working with you guys' help. It is very much appreciated!!

Sign In or Register to comment.