Processing - Loops - amount of circles decrease - for-loop

Here is a grid of crosses in circles currently 5x5. I'm attempting to get a row of 5, followed by a row of 4 underneath, then 3, then 2 etc. I've tried changing the for loops and the values but nothing is working. Do I need to use rows and columns?
int x=20;
int y=30;
size(100,100); //set size of canvas screen
for(int i=0; i<5 ; i++)
{
for (int j=0; j<5; j++)
{
x=x+10; //add 10 to value stored in variable x
ellipse(x,y,10,10);
line (x-5,y,x+5,y);
line (x,y-5,x,y+5);
}
x=20;
y=y+10;
}
Thank you!

Like I said in your last post, the best thing you can do is to get out a piece of graph paper and a pencil and draw out a few examples. Do this until you find a pattern, and you can use that in your for loops. Shameless self-promotion: I've written a tutorial on for loops in Processing available here.
Another thing you might try is separating each row into its own for loop. Don't worry about nested for loops right now; just get it working with 5 individual for loops, one for each row. When you have that working, you'll be able to look for patterns that you can use to condense the whole thing into one nested for loop.
One more thing you might do is separate drawing a row of circles into its own function, which might be defined like this:
void drawRow(float circleY, int circleCount){
Then you'd put your inner for loop inside this function. Now that you have this, you can write another for loop that calls this function.

The trick is to reduce the number of circles drawn in the OUTER FOR LOOP. Compare with something I did :)
size(500, 500);
background(255);
int gridSize = 15;
int nTimes = gridSize;
int num = 1; //number the circles
float circleD = (width/gridSize);
float w = (width/gridSize)/2;
float h = (height/gridSize)/2;
float hOffset = h;
float wOffset = w;
int count = 1;
for(int i = 0; i < nTimes; i++){
for(int j = 1; j <= gridSize; j++){ //horizontal
if(count %2 == 1){
fill(0, 0, 255);
}
else{
fill(255, 0, 0);
}
ellipse(wOffset, hOffset, circleD, circleD);
fill(14);
textSize(circleD/6);
textAlign(CENTER, CENTER);
text(num, wOffset, hOffset);
num++;
wOffset += circleD;
}
gridSize -= 1;
wOffset = w;
hOffset += circleD;
count += 1;
}

Related

Letting a loop run back and forth in Processing

Currently I am trying to get a loop "running forth and back" in a Processing sketch. I can do it with mouseY for example – but I want to have it automatically: the rect(); should appear horizontally line by line… like 1, 1+next, 1+next+next and after 15 lines reverse! 15, 14, 13, 12,11,10,9…
With frameCount; I can let them run down as I want… but not yet back. So I read about boolean statements… and tried to get it in syntax… syntax seems ok… but I can not really get the right logic to make it work. Does someone have an Idea how to really write it in the correct way?
This is my Code so far:
int a;
int i;
int step = 60;
void setup() {
size(1080, 1080);
}
void draw() {
background(0);
for (a = 0; a < 15; a++) {
for (i = 0; i < 5; i++) {
fill(255, 255, 255);
rect(216*i,60*a,216,60);
}
}
}
This creates the pattern – all at once – I know for (a = 0; a < mouseY; a++) or for (a = 0; a < frameCount; a++) would make it work but I thought to make it automatically this needs to appear somewhere – but how?
a+=step;
if ( a > 15 || a < 0 ){
step = -step;
}
Thank you for any help
It will probably be easier is you don't try to change the way you increment the steps but rather how many rectangles you generate for each step. To make it more clear consider this code:
MAX_RECTANGLES = 15;
let frameCount = 0;
while (frameCount < 100) {
frameCount++;
step = frameCount % (MAX_RECTANGLES * 2);
nbRect = MAX_RECTANGLES - Math.abs(MAX_RECTANGLES - step);
console.log(step, nbRect);
}
The frameCount variable and the while loop are only recreating the p5js loop, what is interesting here are the step and nbRect variables:
MAX_RECTANGLES is the number of rectangles you want to show when you show them all. In our example we want to show 15 rectangles.
step will will vary between 0 and MAX_RECTANGLES * 2 in our example this will vary between 0 and 30.
And we will vary nbRect between 0 and 15 with the following rules:
If 0 <= step <= 15 then 0 <= nbRect <= 15
If 16 <= step <= 30 then 15 >= nbRect >= 0
Running the code might make it easier to understand. With this mechanism you transform an ever increasing value (frameCount) to a value varying between 0 and 15.
You can have a look at this p5js codepen which does what you want with the method I just described.
Thank you statox! So i wrote it into Processing like this:
int MAX_RECT = 18;
int step = 60;
void setup() {
size(1080, 1080);
frameRate(30);
}
void draw() {
background(0);
int step = (frameCount/2 % MAX_RECT) *2;
int nbRectangles = MAX_RECT - Math.abs(MAX_RECT - step);
for (int a = 0; a < nbRectangles; a++) {
for (int i = 0; i < 5; i++) {
fill(255, 255, 255);
rect(216 * i, 60 * a, 216, 60);
}
}
}
Is there a way not to redraw the first line of rects? I have to check out the Math.abs(); function – I am not yet familiar with this… :-(

Circles not appearing on Canvas

I'm trying to build a connect4 game with processing, following a tutorial.
What I have so far is here.
The tutorial is here.
I stopped at the 4:05 mark to check my code but I noticed something...I don't know why but circles should pop up when I click but they aren't....can someone help pls? Thanks.
Just in case, here's the code:
int h = 6;
int w = 7;
int bs = 100;
int[][] board = new int[h][w];
int player = 1;
void setup() {
size(700, 600);
ellipseMode(CORNER);
}
int nextSpace(int x){
for (int y = h - 1; y >= 0; y--) if (board[y][x] == 0) return y;
return -1;
}
void mousePressed(){
int x = mouseX / bs;
int y = nextSpace(x);
if (y >= 0){
board[y][x] = player;
player = player == 1 ? 2 : 1;
}
}
void draw() {
for (int j = 0; j < h; j++){
for (int i = 0; i < w; i++){
fill(255);
rect(i * bs, j * bs, bs, bs);
if (board[j][i] > 0){
fill(board[j][i] == 1 ? 255 : 0, board[j][i] == 2 ? 255 : 0, 0);
ellipse(i * bs, j * bs, bs, bs);
}
}
}
}
Next time you have this kind of issue try to use a systematic approach to define where is your bug:
Is your draw() function broken? To check that put something in your board and see if it shows. For example add board[1][1]=1 in your setup() and you'll see a circle appearing so the issue is not in draw()
So if you click on the screen does it update your board as expected? The first thing is to add a simple println("Clicked"); in mousePressed(). Now you see that your click event is working well since the string is shown each time you click, so it must be an issue with how you get your x and y.
Use println(x); and println(y); in mousePressed() to have an idea of your values. You will notice that you don't get integers for x you get decimal number.
And this is your issue: you can not access board[1.543] it doesn't make sense, so you need to keep only the integer part of mouseX / bs. To do that you can use int() like this:
int x = int(mouseX / bs);
And your sketch is now working fine.

How can I create a game where you have to avoid circles with your mouse that move around randomly

I don't know how to make the circles move. I also don't know how to make the game end when the mouse touches a circle.
I already have the circles drawn on screen
for(int i = 0; i < 30; i++){
int x = (int)random(100);
int y = (int)random(100);
ellipse(x,y,25,25);
}
It shows a screen with circles. I need them to move around and have the game end when the mouse touches them.
In order to solve this problem you need to store the values of x and y in two arrays.
Next you need to initialize the arrays with a for loop (like your code).
In the order to have a continuous movement of the circle we add a little step each loop with another for loop.
And then you can calculate the distance between the mouse and each circle.
int[] x;//creation of arrays
int[] y;
int size = 30;
int nbBalls = 20;
void setup() {
size(400, 400);
x = new int [nbBalls];
y = new int [nbBalls];
for(int i=0;i<nbBalls;i++){//initialisation
x[i] = (int)random(400);
y[i] = (int)random(400);
}
}
void draw()
{
background(51);
for(int i = 0; i < nbBalls; i ++)//draw
ellipse(x[i],y[i],size,size);
for(int i = 0; i < nbBalls; i ++) {//move
x[i] = x[i] + (int)random(5)-2;
y[i] = y[i] + (int)random(5)-2;
}
for(int i = 0; i < nbBalls; i ++)//collision test
if(dist(mouseX,mouseY,x[i],y[i])<size)
noLoop();
}

processing animation in loop

so its my first day using processing and i need a bit of help to start with this is my code, im doing the selection sort:
int[] numbers; // Declare array
int currentmin;
int exchange=0;
void setup() {
frameRate(0.1);
size(500,500);
numbers = new int[10]; // Create array with 10 cells
background(105);
for (int i = 0; i < numbers.length; i++) { // random numbers from 1 to 100
int r = int(random(1,100)); // create random numbers
for (int j=0; j<numbers.length; j++) { //make sure not duplications
if(numbers[j]==r)
{r=r+1;}
}
numbers[i]=r; //fill array with random numbers
println(r);
}
fill(255,0,0);
for (int i = 0; i < numbers.length; i++) { //draw rectangles
rect(i*40+10,400 ,35, -numbers[i]);
}
for (int j=0; j < numbers.length; j++){ //set pivot number
currentmin=numbers[j];
for (int i=j+1; i < numbers.length; i++){ //find lowest number in array
if (numbers[i] < currentmin) {
currentmin = numbers[i];
}
}
for ( int i=j; i<numbers.length;i++){ //swap pivot with lowest number
if ( numbers[i]==currentmin){
exchange=numbers[j];
numbers[j]=numbers[i];
numbers[i]=exchange;
//here
}
}
}
}
void draw() {
background(105);
for (int z = 0; z < numbers.length; z++) {
rect(z*40+10,400 ,35, -numbers[z]);
}
}
as you can see where i have the comment here im trying to make the thing animated and to see the rectangles change place on each iteration in the first loop, but its not working... any help ? i tried calling draw(); hopelessly but it didnt work... anyway i can get a help ?
This isn't exactly a trivial animation to execute. You should really start with something simpler.
But to answer your question, you wouldn't put your animation inside a for loop. Instead, you need to make it so the draw() function draws a single frame of the animation. Processing automatically calls the draw() function 60 times per second, so by changing what's drawn each time, you create an animation.
Shameless self-promotion: I wrote a tutorial on creating animations in Processing available here.

Coordinate loop in Processing

I wanted to make an image and I figured this was the quickest way. The idea is that there are rows with lines 5 pixels high, and every new row, the amount of pixels in between the lines are 1 pixel more than the previous row. It's been a while since I have used java and this is so far what I came up with
size(800,800);
int z = 2;
int w = 5;
int max = 800;
for(int y = 0;y<max;y++){
for(int x = 0;x<max;x=x+z){
point(x,y);
if(y%10 == 0)z++;
}
}
This code is not quite giving me what I expected, and I can't figure out why. any help would be appreciated
Wow, I feel dumb.
size(800,800);
int z = 2;
int w = 5;
int max = 800;
for(int y = 0;y<max;y++){
for(int x = 0;x<max;point(x,y)){
x=x+z;
}
if(y%5 == 0)z++;
}
all I had to do was move the if statement out of the second loop.

Resources