I have a project that creates an array list of balls (ellipses). When I press my mouse down (left button) and hold it an ellipse follows my mouse. When I let go the ellipse is placed on the screen where my mouse was.
I wanna be able to right click and hold over an ellipse (any random one) and have it following my mouse again like previous. and again if I let go of the mouse button, it should be placed back on the screen where my mouse is currently positioned.
I am struggling to understand how I can find the x y position of the ellipse that is already on the screen and remove the ellipse from the list and have it follow my mouse again.
Any suggestion let me know-
Here is my main class
ArrayList<Ball> ballList = new ArrayList<Ball>();boolean touching;
void setup() {
size(600, 600);
}
void draw() {
background(150);
// if the mouse button is held down, set the ball's coordinates to the mouse coordinates
if (ballList.size() > 0 && mousePressed && mouseButton==LEFT) {
ballList.get(ballList.size() - 1).xPos = mouseX; // 'ballList.get(ballList.size() - 1)' is the java way to get the last item added to an arrayList
ballList.get(ballList.size() - 1).yPos = mouseY;
}
for (Ball b : ballList) {
b.drawBall();
}
}
// this method will trigger once every time the user press a mouse button
void mousePressed() {
if (mouseButton==LEFT) {
ballList.add(new Ball(mouseX, mouseY));
}
}
here is my ball class
class Ball {
float xPos, yPos;
Ball(float xPos, float yPos) {
this.xPos= xPos;
this. yPos= yPos;
}
void drawBall() {
ellipse(xPos, yPos, 50, 50);
println("X" + xPos + " Y:"+ yPos);
}
void moveBall(){
}
}
You can check if a ball is under the cursor by checking if the distance(dist()) between the ball's position and the mouse's position:
if(dist(ball.x, ball.y, mouseX, mouseY) < ball.radius){
println("mouse over ball");
}
Currently you're hardcoding the ball diameter (50), but you could easily add a radius property:
class Ball {
float xPos, yPos;
float diameter = 50;
float radius = diameter * 0.5;
Ball(float xPos, float yPos) {
this.xPos= xPos;
this. yPos= yPos;
}
void drawBall() {
ellipse(xPos, yPos, diameter, diameter);
}
}
The condition can be wrapped in a for loop to do the same check on every ball and into a function which either returns the first ball matching the condition or null (in case there is no ball under the cursor):
Ball getBall(float x, float y){
// for each ball
for(Ball ball : ballList){
// check if the x,y coordinates are inside any of the existing balls
if(dist(ball.xPos, ball.yPos, x, y) < ball.radius){
// return the 1st match
return ball;
}
}
// return null if nothing was found
return null;
}
You're already using classes and functions, but just in case the above syntax looks unfamiliar:
the Ball type at the begining of the function replaces void and it means the function must return an object of type Ball (as opposed to void)
the return keyword both exits the function but also returns the reference to the ball (if found, null otherwise)
To discern whether there's a selected ball or not (when switching between left and right click) you could use a Ball variable which initially is null, but gets assigned either then left click is pressed or right click is pressed and there's a mouse coordinates fall within the ball's position/radius.
Here's a modified version of your code using the above:
ArrayList<Ball> ballList = new ArrayList<Ball>();
// reference to selection
Ball selectedBall;
void setup() {
size(600, 600);
}
void draw() {
background(150);
// render all balls
for (Ball ball : ballList) {
ball.drawBall();
}
}
// this method will trigger once every time the user press a mouse button
void mousePressed() {
if (mouseButton == LEFT) {
// reset the selection to the newest ball
selectedBall = new Ball(mouseX, mouseY);
// append it to the list
ballList.add(selectedBall);
println("added new ball and updated selection", selectedBall);
}
if (mouseButton == RIGHT) {
// check if a ball is under the cursor, if so select it
selectedBall = getBall(mouseX, mouseY);
println("right click selection", selectedBall);
}
}
void mouseDragged() {
// update dragged ball coordinates if there is a previous selection
if (selectedBall != null) {
selectedBall.xPos = mouseX;
selectedBall.yPos = mouseY;
println("dagging selected ball", selectedBall);
}
}
void mouseReleased() {
// clear selection
selectedBall = null;
println("selection cleared");
}
Ball getBall(float x, float y) {
// for each ball
for (Ball ball : ballList) {
// check if the x,y coordinates are inside any of the existing balls
if ( dist(ball.xPos, ball.yPos, x, y) < ball.radius ) {
// return the 1st match (exits loop and function immediately)
return ball;
}
}
// return null if nothing was found
return null;
}
class Ball {
float xPos, yPos;
float diameter = 50;
float radius = diameter * 0.5;
Ball(float xPos, float yPos) {
this.xPos = xPos;
this.yPos = yPos;
}
void drawBall() {
ellipse(xPos, yPos, diameter, diameter);
}
// pretty print info
String toString(){
return "[Ball x=" + xPos + " y="+ yPos + "]";
}
}
I've removed a few unused variables, added toString() (so it displays info nicely using println()) and sprinkled a few optional println() statements so it's easier to see what's going as you test the code.
Final notes:
currently if you left click multiple times you can add mulitple overlapping balls. You can tweak the implementation to update the check if there's a ball there first and if so only add a new ball if there aren't any existing balls at that locations already
looping though every ball and checking distance (which uses sqrt()) can get computationally expensive for a large number of balls. At this stage code readability is more important, but in case you code develops into something a lot more complex you could used squared distance instead of dist() and use other optimisation techniques.
Update
Here's a tweaked version of the above sketch which only adds a new ball if there isn't one already at the mouse location (allowing mouse left only dragging):
ArrayList<Ball> ballList = new ArrayList<Ball>();
// reference to selection
Ball selectedBall;
void setup() {
size(600, 600);
}
void draw() {
background(150);
// render all balls
for (Ball ball : ballList) {
ball.drawBall();
}
}
// this method will trigger once every time the user press a mouse button
void mousePressed() {
// update selection
selectedBall = getBall(mouseX, mouseY);
// if there isn't a ball already, add one:
if (selectedBall == null) {
ballList.add(new Ball(mouseX, mouseY));
}
}
void mouseDragged() {
// update dragged ball coordinates if there is a previous selection
if (selectedBall != null) {
selectedBall.xPos = mouseX;
selectedBall.yPos = mouseY;
}
}
void mouseReleased() {
// clear selection
selectedBall = null;
}
Ball getBall(float x, float y) {
// for each ball
for (Ball ball : ballList) {
// check if the x,y coordinates are inside any of the existing balls
if ( dist(ball.xPos, ball.yPos, x, y) < ball.radius ) {
// return the 1st match (exits loop and function immediately)
return ball;
}
}
// return null if nothing was found
return null;
}
class Ball {
float xPos, yPos;
float diameter = 50;
float radius = diameter * 0.5;
Ball(float xPos, float yPos) {
this.xPos = xPos;
this.yPos = yPos;
}
void drawBall() {
ellipse(xPos, yPos, diameter, diameter);
}
// pretty print info
String toString(){
return "[Ball x=" + xPos + " y="+ yPos + "]";
}
}
If you want to pick the newly added ball immediately you can off course both add the new ball and update the selection:
ArrayList<Ball> ballList = new ArrayList<Ball>();
// reference to selection
Ball selectedBall;
void setup() {
size(600, 600);
}
void draw() {
background(150);
// render all balls
for (Ball ball : ballList) {
ball.drawBall();
}
}
// this method will trigger once every time the user press a mouse button
void mousePressed() {
// update selection
selectedBall = getBall(mouseX, mouseY);
// if there isn't a ball already, add one:
if (selectedBall == null) {
selectedBall = new Ball(mouseX, mouseY);
ballList.add(selectedBall);
}
}
void mouseDragged() {
// update dragged ball coordinates if there is a previous selection
if (selectedBall != null) {
selectedBall.xPos = mouseX;
selectedBall.yPos = mouseY;
}
}
void mouseReleased() {
// clear selection
selectedBall = null;
}
Ball getBall(float x, float y) {
// for each ball
for (Ball ball : ballList) {
// check if the x,y coordinates are inside any of the existing balls
if ( dist(ball.xPos, ball.yPos, x, y) < ball.radius ) {
// return the 1st match (exits loop and function immediately)
return ball;
}
}
// return null if nothing was found
return null;
}
class Ball {
float xPos, yPos;
float diameter = 50;
float radius = diameter * 0.5;
Ball(float xPos, float yPos) {
this.xPos = xPos;
this.yPos = yPos;
}
void drawBall() {
ellipse(xPos, yPos, diameter, diameter);
}
// pretty print info
String toString(){
return "[Ball x=" + xPos + " y="+ yPos + "]";
}
}
Related
I've finished a single rectangle code, but I'd like to know ways to make at least four rectangles change color while hovering the mouse over them. Any advice is much appreciated.
code is below:
int rectX, rectY;
int rectSize = 90;
color rectColor;
color baseColor;
boolean rectOver = false;
void setup() {
size(640, 360);
rectColor = color(0);
baseColor = color(102);
rectX = width/2;
rectY = height/2;
rectMode(CENTER);
}
void draw() {
update(mouseX, mouseY);
noStroke();
if (rectOver) {
rectColor = color(255);
}else
{
rectColor = color(0);
}
stroke(255);
fill(rectColor);
rect(rectX, rectY, rectSize, rectSize);
}
void update(int x, int y) {
if ( overRect(rectX, rectY, rectSize, rectSize) ) {
rectOver = true;}
else{rectOver = false;}
}
boolean overRect(int x, int y, int width, int height) {
if (mouseX >= x-width/2 && mouseX <= x+width/2 &&
mouseY >= y-height/2 && mouseY <= y+height/2) {
return true;
}
else {
return false;
}
}
First of all, you have to fix your overRect function since width and height are built-in variables, secondly what you need to do is to declare a rectangle class that will contain the x,y, width and height of your rectangle, plus two methods: one to check if the mouse if hovering (using your old method) and one to self draw the rectangle. Lastly, you need an array to store your rectangles. Here is the final code:
int rectX, rectY;
int rectSize = 90;
color rectColor;
color baseColor;
ArrayList<rectangle> list;
boolean rectOver = false;
class rectangle {
float x,y,w,h;
rectangle (float y, float x,float w, float h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
boolean checkInside() {
return overRect(x,y,w,h);
}
void selfDraw(){
if (this.checkInside()) {
rectColor = color(255);
}else
{
rectColor = color(0);
}
stroke(255);
fill(rectColor);
rect(x, y, w, h);
}
}
void setup() {
size(640, 360);
rectMode(CENTER);
list= new ArrayList<rectangle>();
list.add(new rectangle(40,40,50,60));
list.add(new rectangle(20,200,50,20));
list.add(new rectangle(300,200,50,50));
list.add(new rectangle(200,300,80,60));
}
void draw() {
for (int i = 0; i < list.size(); i++) {
list.get(i).selfDraw();
}
}
boolean overRect(float x, float y, float w, float h) {
if (mouseX >= x-w/2 && mouseX <= x+w/2 &&
mouseY >= y-h/2 && mouseY <= y+h/2) {
return true;
}
else {
return false;
}
}
Use inheritence. As in YOUSFI's answer, your nest net would be to build a rectangle class and write it's own mouse over function in there. Then, you can make an instance of that object in your main program and call it's mouseover function.
Instead of blindly copy pasting the code YOUSFI provided, my suggestion would be to read up on Object Oriented Programming or watch this introductory video series: https://www.youtube.com/watch?v=xG2Vbnv0wvg
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;
}
Trying to determine whether the mouse has been clicked within a certain ball and when it is clicked I want to display text that relates to that specific ball, this is what I have so far any help would be appreciated.
int rad = 60; // Width of the shape
float xpos1, ypos1; // Starting position of shape
float xspeed = 4; // Speed of the shape
float yspeed = 4; // Speed of the shape
int xdirection = 1; // Left or Right
int ydirection = 1; // Top to Bottom
boolean overBox1 = false;
void setup()
{
size(1200, 800);
noStroke();
frameRate(30);
ellipseMode(RADIUS);
// Set the starting position of the shape
xpos1 = width/2;
ypos1 = height/2;
}
void draw()
{
background(102);
circleone();
}
void circleone()
{
xpos1 = xpos1 + ( xspeed * xdirection );
ypos1 = ypos1 + ( yspeed * ydirection );
if (xpos1 > width-rad || xpos1 < rad) {
xdirection *= -1;
}
if (ypos1 > height-rad || ypos1 < rad) {
ydirection *= -1;
}
ellipse(xpos1, ypos1, rad, rad);
}
void mouseClick()
{
if (overCircle(xpos1,ypos1,rad)==true)
{
println("YO");
}
}
boolean overCircle(float x, float y, int radius) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) <radius) {
return true;
} else {
return false;
}
}
This logic seems overcomplicated:
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) <radius)
You could just use the dist() function instead:
return dist(x, y, mouseX, mouseY) < radius;
Then if you want to display some text when the ball is clicked, you're going to have to add more than a println() statement. You might set a boolean variable to true, and then in the draw() function you'd check that variable and draw something to the screen when it's true.
If you're trying to get many clickable balls on the screen, then you might think about creating classes that represent a ball and putting your logic in there.
But you haven't really asked a question. You've posted some code, haven't told us what you expect it to do, what it does instead, or how those two things are different. Stack Overflow isn't really designed for general "how do I do this" type questions. It's for more specific "I tried X, expected Y, but got Z instead" type questions. So you'll have much better luck if you post a MCVE instead of your entire project and ask a specific question about a specific line of code. Good luck.
I was wondering if there was a way to change the appearance of the "particles" to an image that I've created. I found this sketch in the processing library and I've been trying to figure out how can I upload birds that I've created into the sketch.
Would anyone care to help me figure out if it's even possible?
Thank you!
//https://processing.org/examples/flocking.html
Flock flock;
void setup() {
size(640, 360);
flock = new Flock();
// Add an initial set of boids into the system
for (int i = 0; i < 150; i++) {
flock.addBoid(new Boid(width/2,height/2));
}
}
void draw() {
background(50);
flock.run();
}
// Add a new boid into the System
void mousePressed() {
flock.addBoid(new Boid(mouseX,mouseY));
}
// The Flock (a list of Boid objects)
class Flock {
ArrayList<Boid> boids; // An ArrayList for all the boids
Flock() {
boids = new ArrayList<Boid>(); // Initialize the ArrayList
}
void run() {
for (Boid b : boids) {
b.run(boids); // Passing the entire list of boids to each boid individually
}
}
void addBoid(Boid b) {
boids.add(b);
}
}
// The Boid class
class Boid {
PVector location;
PVector velocity;
PVector acceleration;
float r;
float maxforce; // Maximum steering force
float maxspeed; // Maximum speed
Boid(float x, float y) {
acceleration = new PVector(0, 0);
// This is a new PVector method not yet implemented in JS
// velocity = PVector.random2D();
// Leaving the code temporarily this way so that this example runs in JS
float angle = random(TWO_PI);
velocity = new PVector(cos(angle), sin(angle));
location = new PVector(x, y);
r = 2.0;
maxspeed = 2;
maxforce = 0.03;
}
void run(ArrayList<Boid> boids) {
flock(boids);
update();
borders();
render();
}
void applyForce(PVector force) {
// We could add mass here if we want A = F / M
acceleration.add(force);
}
// We accumulate a new acceleration each time based on three rules
void flock(ArrayList<Boid> boids) {
PVector sep = separate(boids); // Separation
PVector ali = align(boids); // Alignment
PVector coh = cohesion(boids); // Cohesion
// Arbitrarily weight these forces
sep.mult(1.5);
ali.mult(1.0);
coh.mult(1.0);
// Add the force vectors to acceleration
applyForce(sep);
applyForce(ali);
applyForce(coh);
}
// Method to update location
void update() {
// Update velocity
velocity.add(acceleration);
// Limit speed
velocity.limit(maxspeed);
location.add(velocity);
// Reset accelertion to 0 each cycle
acceleration.mult(0);
}
// A method that calculates and applies a steering force towards a target
// STEER = DESIRED MINUS VELOCITY
PVector seek(PVector target) {
PVector desired = PVector.sub(target, location); // A vector pointing from the location to the target
// Scale to maximum speed
desired.normalize();
desired.mult(maxspeed);
// Above two lines of code below could be condensed with new PVector setMag() method
// Not using this method until Processing.js catches up
// desired.setMag(maxspeed);
// Steering = Desired minus Velocity
PVector steer = PVector.sub(desired, velocity);
steer.limit(maxforce); // Limit to maximum steering force
return steer;
}
void render() {
// Draw a triangle rotated in the direction of velocity
float theta = velocity.heading2D() + radians(90);
// heading2D() above is now heading() but leaving old syntax until Processing.js catches up
fill(200, 100);
stroke(255);
pushMatrix();
translate(location.x, location.y);
rotate(theta);
beginShape(TRIANGLES);
vertex(0, -r*2);
vertex(-r, r*2);
vertex(r, r*2);
endShape();
popMatrix();
}
// Wraparound
void borders() {
if (location.x < -r) location.x = width+r;
if (location.y < -r) location.y = height+r;
if (location.x > width+r) location.x = -r;
if (location.y > height+r) location.y = -r;
}
// Separation
// Method checks for nearby boids and steers away
PVector separate (ArrayList<Boid> boids) {
float desiredseparation = 25.0f;
PVector steer = new PVector(0, 0, 0);
int count = 0;
// For every boid in the system, check if it's too close
for (Boid other : boids) {
float d = PVector.dist(location, other.location);
// If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
if ((d > 0) && (d < desiredseparation)) {
// Calculate vector pointing away from neighbor
PVector diff = PVector.sub(location, other.location);
diff.normalize();
diff.div(d); // Weight by distance
steer.add(diff);
count++; // Keep track of how many
}
}
// Average -- divide by how many
if (count > 0) {
steer.div((float)count);
}
// As long as the vector is greater than 0
if (steer.mag() > 0) {
// First two lines of code below could be condensed with new PVector setMag() method
// Not using this method until Processing.js catches up
// steer.setMag(maxspeed);
// Implement Reynolds: Steering = Desired - Velocity
steer.normalize();
steer.mult(maxspeed);
steer.sub(velocity);
steer.limit(maxforce);
}
return steer;
}
// Alignment
// For every nearby boid in the system, calculate the average velocity
PVector align (ArrayList<Boid> boids) {
float neighbordist = 50;
PVector sum = new PVector(0, 0);
int count = 0;
for (Boid other : boids) {
float d = PVector.dist(location, other.location);
if ((d > 0) && (d < neighbordist)) {
sum.add(other.velocity);
count++;
}
}
if (count > 0) {
sum.div((float)count);
// First two lines of code below could be condensed with new PVector setMag() method
// Not using this method until Processing.js catches up
// sum.setMag(maxspeed);
// Implement Reynolds: Steering = Desired - Velocity
sum.normalize();
sum.mult(maxspeed);
PVector steer = PVector.sub(sum, velocity);
steer.limit(maxforce);
return steer;
}
else {
return new PVector(0, 0);
}
}
// Cohesion
// For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location
PVector cohesion (ArrayList<Boid> boids) {
float neighbordist = 50;
PVector sum = new PVector(0, 0); // Start with empty vector to accumulate all locations
int count = 0;
for (Boid other : boids) {
float d = PVector.dist(location, other.location);
if ((d > 0) && (d < neighbordist)) {
sum.add(other.location); // Add location
count++;
}
}
if (count > 0) {
sum.div(count);
return seek(sum); // Steer towards the location
}
else {
return new PVector(0, 0);
}
}
}
Take a look at the render() function in the Boid class:
void render() {
// Draw a triangle rotated in the direction of velocity
float theta = velocity.heading2D() + radians(90);
// heading2D() above is now heading() but leaving old syntax until Processing.js catches up
fill(200, 100);
stroke(255);
pushMatrix();
translate(location.x, location.y);
rotate(theta);
beginShape(TRIANGLES);
vertex(0, -r*2);
vertex(-r, r*2);
vertex(r, r*2);
endShape();
popMatrix();
}
This is the code that draws a single Boid. You could modify this code to draw an image instead. One way might be to just texture the existing triangle. You'd do this using the texture() function:
texture(yourImageHere);
vertex(0, -r*2);
vertex(-r, r*2);
vertex(r, r*2);
Or you could change the rendering to use a rectangle to show your image. Keep in mind that if you change the shape of the Boids, you might also need to change some of the values used in the flocking behavior to accommodate the new shapes.
I cant figure this out. I have a sketch with little rotating rectangles on it. They rotate on every draw(). However the previous rectangle remains visible. I tried moving background() around but it either gets rid of all the rectangles apart from one or it doesn't clear the screen. I would like to be able to clear all the rectangles after each draw.
Here is the code:
//Create array of objects
ArrayList<Circle> circles = new ArrayList<Circle>();
ArrayList<Connector> centrePoint = new ArrayList<Connector>();
void setup(){
size(800, 800);
frameRate(1);
rectMode(CENTER);
background(204);
for(int i = 1; i < 50; i++){
float r = random(100,height-100);
float s = random(100,width-100);
float t = 20;
float u = 20;
println("Print ellipse r and s " + r,s);
circles.add(new Circle(r,s,t,u,color(14,255,255),random(360),random(5),random(10)));
}
//Draw out all the circles from the array
for(Circle circle : circles){
circle.draw();
float connectStartX = circle.x1;
float connectStartY = circle.y1;
println("PrintconnectStartX and Y " + connectStartX,connectStartY);
for(Circle circleEnd : circles){
float connectEndX = (circleEnd.x1);
float connectEndY = (circleEnd.y1);
centrePoint.add(new Connector(connectStartX,connectStartY,connectEndX,connectEndY));
}
}
//For each ellipse, add the centre point of the ellipse to array
for(Connector connectUp : centrePoint){
println(connectUp.connectStartX ,connectUp.connectStartY ,connectUp.connectEndX ,connectUp.connectEndY);
stroke(100, 0, 0);
if (dist(connectUp.connectStartX ,connectUp.connectStartY ,connectUp.connectEndX ,connectUp.connectEndY) < 75){
connectUp.draw(connectUp.connectStartX ,connectUp.connectStartY ,connectUp.connectEndX ,connectUp.connectEndY);
}
}
//For the line weight it should equal the fat of the node it has come from ie
//for each circle, for each connectUp if the x==connectStartX and y==connectStartY then make the line strokeWeight==fat
for(Circle circle : circles){
for(Connector connectUp : centrePoint){
if (connectUp.connectStartX == circle.x1 & connectUp.connectStartY == circle.y1 & (dist(connectUp.connectStartX ,connectUp.connectStartY ,connectUp.connectEndX ,connectUp.connectEndY) < 75)){
print(" true "+ circle.fat);
float authority = circle.fat;
strokeWeight(authority*1.5);
connectUp.draw(connectUp.connectStartX ,connectUp.connectStartY ,connectUp.connectEndX ,connectUp.connectEndY);
}
}
}
}
void update(){
}
void draw() {
for(Circle circle : circles){
circle.rot =+0.02;
circle.draw();
circle.rot = random(-6,6);
}
}
//Need to connect each ellipse to all the other ellipses
class Connector {
public float connectStartX;
public float connectStartY;
public float connectEndX;
public float connectEndY;
public color cB;
public float thickness;
public Connector(float connectStartX, float connectStartY, float connectEndX, float connectEndY){
this.connectStartX = connectStartX;
this.connectStartY = connectStartY;
this.connectEndX = connectEndX;
this.connectEndY = connectEndY;
//this.cB = tempcB;
//this.thickness = thickness;
}
void draw(float connectStartX, float connectStartY, float connectEndX, float connectEndY){
line(connectStartX, connectStartY, connectEndX, connectEndY);
// float fat = random(255);
//fill(fat);
stroke(100, 0, 0);
}
}
class Circle{
public float x1;
public float y1;
public float x2;
public float y2;
public color cB;
public float rot;
public float fat = random(5);
public float fert = 0.1;
public Circle(float x1, float y1, float x2, float y2, color tempcB, float rot, float fat, float fert){
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.cB = tempcB;
//Tilt - I think this is done in radians
this.rot = rot;
//Authority -this is the fill
this.fat = fat;
//Fertility- this is a multiplier for the tilt
this.fert = fert;
}
void draw(){
pushMatrix();
translate(x1, y1);
fert = random(0.5);
rot = random(-6,6);
rotate(rot*fert);
translate(-x1, -y1);
//float fat = random(255);
fill(fat);
rect(x1, y1, 24, 36);
popMatrix();
}
}
You've got a few things going on in your code that I've seen in your previous posts. The way you're doing your drawing doesn't make a ton of sense, and I'll explain why.
Here's what most Processing sketches do:
Use the setup() function to setup any data structures you'll use in your program. Don't do any drawing from the setup() function.
Call background() every frame to clear out old frames.
Draw everything you want to be drawn in the frame in the draw() function.
Modify the data structures to change what you're drawing on the screen.
Your code is a bit too long for an MCVE, so here's a little example that handles the drawing in a more standard way:
ArrayList<PVector> circles = new ArrayList<PVector>();
void setup() {
size(500, 500);
ellipseMode(RADIUS);
//setup your data structures here
circles.add(new PVector(250, 250));
//don't do any drawing yet
}
void mousePressed() {
//modify the data structure whenever you want to change what's on the screen
circles.add(new PVector(mouseX, mouseY));
}
void keyPressed() {
//modify the data structure whenever you want to change what's on the screen
if (!circles.isEmpty()) {
circles.remove(0);
}
}
void draw() {
//call background every frame to clear out old frames
background(0);
//draw everything
for (PVector p : circles) {
ellipse(p.x, p.y, 20, 20);
}
}
Notice how this is different from what you're doing. Here's what you do:
You use the setup() function to setup your data structures, but then you draw the background and some of the objects to the screen.
You then don't call background() from draw(), so you're always stuck with whatever has already been drawn.
You then only draw a subset of what you want on the screen, so you can't redraw your whole scene.
You have to modify your code to no longer draw anything from setup(), to call the background() function every frame, and to draw everything you want on the screen every frame.
What you are doing is printing every single circle or line...ect. You need to have a timer that removes them every so often. If you do it too fast you get a strobe like look. So have a timer that removes the first rect from the array list every so often.