How to draw a circle and then when keyPressed, draw another circle etc - processing

I am learning how to code in Processing 4.
I am trying to make a code where when keyPressed() is clicked, one circle is drawn then when the button is pressed again, the first circle remains and then a second circle is drawn but with extent increased by 10, then the key pressed for a final time (3) and the third circle is drawn with the extent increased by 3 then it stops producing more circles.
This is the code I have so far but I am confused on how to approach it. Right now, the first circle just increases in size and it doesn't draw a second one. How do I draw 3 circles, one once keyPressed()?
int sizeIncrease = 10;
int initialSize = 70;
void setup() {
size(500, 500);
}
void draw() {
background(0);
stroke(255,0,0);
strokeWeight(25);
fill(255);
pushMatrix();
translate(20, 50);
circle(width/2, height/2, initialSize);
popMatrix();
}
void keyPressed() {
initialSize += sizeIncrease;
}

Add a variable count. Increment the variable when a key is pressed and draw the circles in a for-loop:
int sizeIncrease = 10;
int initialSize = 70;
int count = 1;
void setup() {
size(500, 500);
}
void draw() {
background(0);
noFill();
stroke(255);
pushMatrix();
translate(20, 50);
for (int i = 0; i < count; i++) {
circle(width/2, height/2, initialSize + i*sizeIncrease);
}
popMatrix();
}
void keyPressed() {
count ++;
}

int sizeIncrease = 10;
int initialSize = 70;
int count = 1;
void setup() {
size(500, 500);
}
void draw() {
background(0);
noFill();
stroke(255);
pushMatrix();
translate(20, 50);
for (int i = 0; i < count; i++)
{
circle(width/2, height/2, initialSize + i*sizeIncrease);
**if(i == 1)
{
sizeIncrease = 3;
}**
}
popMatrix();
}
void keyPressed() {
count ++;
}

Related

object releases another smaller object?

Can anyone help me?
So, I'm supposed to have a ball that is moving horizontally, such that every time I press the mouse, a ball would get shoot vertically, then slows down due to friction. The vertical ball would stay in the old position but the player would reset.
How do I go about doing that without using classes?
Here my code so far:
boolean circleupdatetostop = true;
float x = 100;
float yshot = 880;
float speedshot = random(4,10);
float speedx = 6;
void setup() {
size(1280,960);
}
void draw() {
background(255);
stroke(0);
fill(0);
circle(x,880,80);
if (x > width || x < 0 ) {
speedx = speedx * -1;
}
if (circleupdatetostop) {
x = x + speedx;
}
if (circleupdatetostop == false) {
float locationx = x;
stroke(0);
fill(255,0,255);
circle(locationx,yshot,30);
yshot = yshot - speedshot;
}
}
void mousePressed () {
circleupdatetostop = !circleupdatetostop;
}
I'm not entirely sure if this is what you meant, but you could achieve shooting multiple balls by using ArrayList as well as processing's PVector to better handle the x and y coordinate pairs. If you wanted to look at classes, see this post.
import java.util.*;
// Whether the ball is moving or not
boolean circleupdatetostop = true;
// Information about the main_ball
PVector position = new PVector(100, 880);
PVector speed = new PVector(6, 0);
float diameter = 80;
// Information about the sot balls
ArrayList<PVector> balls_loc = new ArrayList<PVector>();
ArrayList<PVector> balls_speed = new ArrayList<PVector>();
float diameter_shot = 30;
float friction = 0.994;
void setup() {
size(1280, 960);
}
void draw() {
background(255);
stroke(0);
fill(0);
circle(position.x, position.y, diameter);
// Remember to consider the radius of the ball when bouncing off the edges
if (position.x + diameter/2 > width || position.x - diameter/2 < 0 ) {
speed.mult(-1);
}
if (circleupdatetostop) {
position.add(speed);
}
// Cycle through the list updating their speed and draw each ball
for (int i = 0; i<balls_loc.size(); i++) {
balls_speed.get(i).mult(friction+random(-0.05, 0.05));
balls_loc.get(i).add(balls_speed.get(i));
stroke(0);
fill(255, 0, 255);
circle(balls_loc.get(i).x, balls_loc.get(i).y, diameter_shot);
}
}
void mousePressed(){
// Add a new ball to be drawn
if(circleupdatetostop){
balls_loc.add(new PVector(position.x, position.y));
balls_speed.add(new PVector(0, random(-4, -10)));
}
circleupdatetostop = !circleupdatetostop;
}

How to execute a function only once in voice draw(); but still have it displayed for the whole animation

I'm struggling with something here.
Basically I made an animation with several functions. I want the functions to be animated, except for one that I want to be still.
If I specify noLoop, then nothing gets animated, if I tell the function to run a set number of times, then after that number it stops being displayed. What I want is to have it run once but then be still displayed.
Do you guys have any idea of how I could do that ?
Here is the code :
int r1,r2,r3 = 0;
int i1, i2,i3;
void setup(){
size(800,800);
background(255,0);
//noLoop();
}
void draw(){
background(255,0);
rosace();
croix();
sillon1();
sillon2();
}
void rosace(){
for (i1 = 0;i1<230; i1++){
rectMode(CENTER);
noFill();
stroke(20);
strokeWeight(1);
pushMatrix();
translate(width/2,height/2);
translate(400,400);
rotate(radians(r1));
rect(0,0,400,400);
r1 +=1;
//println(r);
popMatrix();
println("rosace ex");
}
}
void croix(){
pushMatrix();
strokeWeight(2);
stroke(0);
translate(width/2, height/2);
rotate(radians(45));
line(-10,0,10,0);
line(0,-10,0,10);
popMatrix();
}
void sillon1(){
for (i2 =0; i2<360; i2++){
pushMatrix();
translate(width/2,height/2);
strokeWeight(int(random(0,7)));
rotate(radians(r2));
point(-330,0);
popMatrix();
r2 +=1;
}
}
void sillon2(){
for (i2 =0; i2<2000; i2++){
pushMatrix();
translate(width/2,height/2);
strokeWeight(int(random(1,3)));
rotate(radians(r2));
point(-360,0+(random(-2,2)));
popMatrix();
r2 +=1;
}
}
The void rosace(); is the one that I'd like to be non-animated.
The problem is that you're storing r1 as a global variable. This means that it keeps it's value after every iteration.
Instead, make it a local variable:
void rosace() {
int r1 = 0;
for (i1 = 0; i1<230; i1++) {
rectMode(CENTER);
noFill();
stroke(20);
strokeWeight(1);
pushMatrix();
translate(width/2, height/2);
translate(400, 400);
rotate(radians(r1));
rect(0, 0, 400, 400);
r1 +=1;
popMatrix();
println("rosace ex");
}
}
You can't just keep a part of the scene, when animations are drawn on top of it. You have to draw the entire scene in every frame. Ensure that rosace draws the same in every frame.
Just set r1 = 0 in every frame, then the algorithm in rosace generates the same rectangles in every frame:
void rosace(){
r1 = 0;
for (i1 = 0;i1<230; i1++){
// [...]
}
}

Processing P3D Animation leaving artifacts behind

I am trying to make a spinning cube in Processing's P3D with this code:
int sizes = 500;
int rotation = 0;
void setup() {
size(500, 500, P3D);
}
void draw() {
lights();
translate(sizes/2, sizes/2, 0);
rotateY(rotation * (PI/180));
rotateX(rotation * (PI/180));
background(0);
box(sizes/2);
rotation = (rotation + 1);
}
When I run it the cube does spin as I wanted, but there are strange 'artifacts' (for lack of a better name) left behind its edges.
What causes this issue, and can it be solved?
I tried this and it worked. Maybe instead of using backround(0), set every pixel to black like the background function does manually.
int sizes = 500;
int rotation = 0;
void setup() {
size(500, 500, P3D);
}
void draw() {
fill(255);
lights();
translate(sizes/2, sizes/2, 0);
rotateY(rotation * (PI/180));
rotateX(rotation * (PI/180));
loadPixels();
for(int i = 0; i < pixels.length; i++) pixels[i] = color(0);
box(sizes/2);
rotation = (rotation + 1);
}

Stop background from refreshing?

I am trying to get my gif to do something similar to this gif.
I have been able to get the line to draw, and the 'planets' to orbit, but can't figure out how to keep the line connecting the two circles, like the gif does.
Here's the basic code:
int x = 500;
int y = 500;
int radius = y/2;
int cX = x/2;
int cY = y/2;
String text1;
int lg_xBall;
int lg_yBall;
int sm_xBall;
int sm_yBall;
void setup() {
size(x, y);
smooth();
colorMode(RGB);
}
void draw() {
background(0);
stroke(255);
float t = millis()/1000.0f;
drawSmBallOrbit(100);
drawLgBallOrbit(100);
moveSmBall(t);
moveLgBall(t);
sun();
// showMouse();
connectingLines();
}
void drawCircle() { // This will draw a simple circle
stroke(1);
// x1=a+r*cos t, y1=b+r*sin t
ellipse(x/2, y/2, x/2, y/2);
}
void drawLines() { // This will draw lines from the center of the circle.
stroke(1);
line(x/2, y/2, radius/2, radius); // line from 6 to center
line(x/2, y/2, x/2, y/4); // line from 12 to center
for (int i = 0; i <= 5; i+=2.5) {
float x1 = x/2+radius/2*cos(i);
float y1 = y/2+radius/2*sin(i);
line(x/2, y/2, x1, y1);
}
}
void moveSmBall(float ky) { // This will create, and move, a small 'planet'
pushStyle();
stroke(100);
sm_xBall = (int)(cX+radius*cos(ky));
sm_yBall = (int)(cY+radius*sin(ky));
fill(190, 0, 0);
// background(0);
ellipse(sm_xBall, sm_yBall, 10, 10);
popStyle();
}
void drawSmBallOrbit(float opacity) {
pushStyle();
stroke(255, opacity);
strokeWeight(1);
noFill();
ellipse(x/2, y/2, cX+radius, cY+radius);
popStyle();
}
void moveLgBall(float kx) {
kx = kx/.7;
pushStyle();
lg_xBall = (int)(cX+radius*cos(kx)*.6);
lg_yBall = (int)(cY+radius*sin(kx)*.6);
fill(0, 0, 230);
ellipse(lg_xBall, lg_yBall, 30, 30);
popStyle();
}
void drawLgBallOrbit(float opacity) {
pushStyle();
stroke(255, opacity);
strokeWeight(1);
noFill();
ellipse(x/2, y/2, (cX+radius)*.6, (cY+radius)*.6);
popStyle();
}
void sun() {
pushStyle();
fill(250, 250, 0);
ellipse(cX, cY, 40, 40);
popStyle();
}
void connectingLines() {
line(sm_xBall, sm_yBall, lg_xBall, lg_yBall);
}
void showMouse() {
text("X: " + mouseX, x/2, y/2-30);
text("Y: " + mouseY, x/2, y/2-50);
}
Thanks for any help/advice!
The problem is that you're calling background() during every frame, which will clear away anything you've already drawn.
So you either need to stop calling background(), or you need to redraw the old lines every frame.
If you simply move the call to background() out of your draw() function and into your setup() function, you're about 50% there already:
void setup() {
size(x, y);
smooth();
colorMode(RGB);
background(0);
}
void draw() {
// background(0);
stroke(255);
float t = millis()/1000.0f;
drawSmBallOrbit(100);
drawLgBallOrbit(100);
moveSmBall(t);
moveLgBall(t);
sun();
// showMouse();
connectingLines();
}
However, the original animation does not show the previous positions of the ellipses. So you need to clear away the previous frame by calling the background() function, and then redraw previous line positions. You'd do that by having an ArrayList that holds those previous positions.
Here's a simple example that uses an ArrayList to redraw anywhere the mouse has been:
ArrayList<PVector> points = new ArrayList<PVector>();
void setup() {
size(500, 500);
}
void draw() {
background(0);
stroke(255);
points.add(new PVector(mouseX, mouseY));
for(PVector p : points){
ellipse(p.x, p.y, 10, 10);
}
}
You would need to do something very similar, but you'd have to keep track of two points at a time instead of one, since you're tracking two ellipses and not just the mouse position.

Making a fading trail in processing

I have a circle that is moving across the screen, what i need is to be able to make that circle leave a line behind it that fades after a second or so. I'm using Processing.
Can't speak for its efficiency but I imagine one way to do it would be to keep the old positions in an ArrayList? You can then draw lines between each point, as long as you push the current position each frame and remove the least recent. Hope it helps!
PVector circlePosition;
ArrayList<PVector> circleTrail;
int trailSize = 10;
void setup() {
size(500, 500);
circlePosition = new PVector(width*0.5, width*0.5);
circleTrail = new ArrayList<PVector>();
}
void draw() {
background(255);
int trailLength;
circlePosition = new PVector(mouseX, mouseY);
circleTrail.add(circlePosition);
trailLength = circleTrail.size() - 2;
println(trailLength);
for (int i = 0; i < trailLength; i++) {
PVector currentTrail = circleTrail.get(i);
PVector previousTrail = circleTrail.get(i + 1);
stroke(0, 255*i/trailLength);
line(
currentTrail.x, currentTrail.y,
previousTrail.x, previousTrail.y
);
}
ellipse(circlePosition.x, circlePosition.y, 10, 10);
if (trailLength >= trailSize) {
circleTrail.remove(0);
}
}
I also can't speak to the efficiency of my method, but the way I've done it is by drawing a rectangle over your entire sketch each time with an also set to a low value (like 25 or so). This results in the objects from previous draw() cycles looking 'faded'. For example:
int i = 0;
void setup(){
size(500,500);
smooth();
noStroke();
background(255);
}
void draw(){
fill(255,25);
rect(0,0,width,height);
fill(0);
ellipse(width/2 + i,height/2 + i,50,50);
delay(100);
i+=10;
}

Resources