Coordinate loop in Processing - image

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.

Related

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.

Random() happening only once

I have this for() loop where I am randomizing the selection of slices of a picture, to display 16 slices of an image in a random order.
I'm picking those slices from an array and I have a variable that picks up what slice is going to be selected in the array.
The problem being that I'd think that the random function would be triggered for every frame, but it's triggered only once.
Here's the code :
void setup() {
size(720,720);
slices = new PImage[16];
slices[0] = loadImage("1.png");
slices[1] = loadImage("2.png");
slices[2] = loadImage("3.png");
slices[3] = loadImage("4.png");
slices[4] = loadImage("5.png");
slices[5] = loadImage("6.png");
slices[6] = loadImage("7.png");
slices[7] = loadImage("8.png");
slices[8] = loadImage("9.png");
slices[9] = loadImage("10.png");
slices[10] = loadImage("11.png");
slices[11] = loadImage("12.png");
slices[12] = loadImage("13.png");
slices[13] = loadImage("14.png");
slices[14] = loadImage("15.png");
slices[15] = loadImage("16.png");
frameRate(1);
}
void draw() {
for (int a = 0; a < 16; a++){
int rand = int(random(slices.length));
image(slices[rand],x,y,size,size);
x += size;
if (a % 4 == 3){
y += size;
x = 0;
}
}
It's dispalying the randomized slices only once and then I end up with a fix image. What I'd like to have is random slices appearing at every frame.
Thanks for your help !
You have 2 problems in your code.
First, you may not want to choose a random index.
This is because the same image could be chosen twice.
Instead, you could shuffle the array before drawing the images, like this:
for (int i = slices.length; i > 1; i--) {
//choose a random index for the i-th element to be swapped with
int j = (int)random(i);
//swap them
PImage temp = slices[j];
slices[j] = slices[i-1];
slices[i-1] = temp;
}
Second, the index is chosen on every frame, and the images are drawn, too, but you can't see it, because your code never resets y back to 0, meaning that they are below the screen.
You can fix this by adding
y = 0;
to the top or bottom of your draw().
Could it be because you've forgot to clear the screen (e.g. calling background()) (meaning once you've drawn an image it will stay rendered) ?
You could also make use of the for loop in setup to avoid repeating yourself:
int numSlices = 16;
PImage[] slices = new PImage[numSlices];
float x, y;
float size = 180;
void setup() {
size(720, 720);
for(int i = 0 ; i < numSlices; i++){
slices[i] = loadImage((i+1) + ".png");
}
frameRate(1);
}
void draw() {
background(255);
for (int a = 0; a < numSlices; a++) {
int rand = int(random(numSlices));
image(slices[rand], x, y, size, size);
x += size;
if (a % 4 == 3) {
y += size;
x = 0;
}
}
y = 0;
}
Additionally you could easily format your code (via CMD+T on OSX or Ctrl+T on Windows/Linux)
Update Kamakura (+1) correctly pointing out y not being reset to 0.
As a distraction I though't point you to IntList's shuffle() method:
int numSlices = 16;
PImage[] slices = new PImage[numSlices];
float x, y;
float size = 180;
IntList indices = new IntList();
void setup() {
size(720, 720);
for(int i = 0 ; i < numSlices; i++){
slices[i] = loadImage((i+1) + ".png");
indices.append(i);
}
frameRate(1);
}
void draw() {
background(255);
// shuffle list
indices.shuffle();
// reset y
y = 0;
for (int a = 0; a < numSlices; a++) {
int rand = indices.get(a);
image(slices[rand], x, y, size, size);
x += size;
if (a % 4 == 3) {
y += size;
x = 0;
}
}
}
Extra reason to play with it, other than a learning experience is that fact that it will be unlikely to get the same random index repeated.
Regarding splicing/shuffling, here's a modified version of the Load and Display example:
/**
* Load and Display
*
* Images can be loaded and displayed to the screen at their actual size
* or any other size.
*/
PImage img; // Declare variable "a" of type PImage
// shuffled image
PImage imgShuffled;
// list of indices to shuffle
IntList shuffleIndices = new IntList();
// configure image slicing rows/columns
int rows = 4;
int cols = 4;
// total sections
int numSections = rows * cols;
// image section dimensions
int sectionWidth;
int sectionHeight;
void setup() {
size(640, 360);
frameRate(1);
// The image file must be in the data folder of the current sketch
// to load successfully
img = loadImage("https://processing.org/examples/moonwalk.jpg"); // Load the image into the program
// calculate section dimensions
sectionWidth = img.width / cols;
sectionHeight = img.height / rows;
// allocate a separate image to copy shuffled pixels into
imgShuffled = createImage(img.width, img.height, RGB);
// populate image section indices
for(int i = 0 ; i < numSections; i++){
shuffleIndices.append(i);
}
}
void shuffleImage(){
// shuffle the list
shuffleIndices.shuffle();
// Ta-da!
println(shuffleIndices);
// loop through each section
for(int i = 0 ; i < numSections; i++){
// index to row, col conversion
int srcCol = i % cols;
int srcRow = i / cols;
// convert to pixel coordinates to copy from
int srcX = srcCol * sectionWidth;
int srcY = srcRow * sectionHeight;
// get random / shuffled index
int index = shuffleIndices.get(i);
// same row, col, to pixel conversion to copy to
int dstCol = index % cols;
int dstRow = index / cols;
int dstX = dstCol * sectionWidth;
int dstY = dstRow * sectionHeight;
// copy from original image to shuffled pixel coordinates
imgShuffled.copy(img,srcX,srcY,sectionWidth,sectionHeight,dstX,dstY,sectionWidth,sectionHeight);
}
}
void draw() {
shuffleImage();
// Displays the image at its actual size at point (0,0)
image(imgShuffled, 0, 0);
}

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 - Loops - amount of circles decrease

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;
}

how to make staggered array out of a for loop javafx

Can I get some help with this project I am trying to make a 9x9 of ellipsis in javafx. I have the code for the ellipsis but I can't figure out the logic to make the following happen.
Example of what I am looking for
I have used the regular for loop that just gives me 9x9. ellipsis stacked on top of one another
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
so what do I have to do to this for loop, to make it look like the picture above
any help would be great thanks.
Just determine the horizontal/vertical offset of the circles.
Every other row contains one more circle and starts half of the offset further to the left than the smaller rows.
final double fieldWidth = 50;
final double fieldHeight = 50;
final double radius = 20;
Pane parent = new Pane();
boolean bigRow = true;
final int rows = 9;
final int columns = 9;
for (int y = 0; y < rows; y++, bigRow = !bigRow) {
double offsetX = bigRow ? fieldWidth / 2 : fieldWidth;
double offsetY = fieldHeight * y + fieldHeight / 2;
for (int x = 0, size = bigRow ? columns : columns - 1; x < size; x++) {
Circle c = new Circle(offsetX + x * fieldWidth, offsetY, radius, Color.TRANSPARENT);
c.setStroke(Color.BLACK);
parent.getChildren().add(c);
}
}

Resources