Can't use a variable in another method in XNA - for-loop

I will explain in depth after. So here is my code, we have an Elevation[] variable and each Elevation gets a random number:
public void elevation()
{
for (x = (int)Width - 1; x >= 0; x--)
{
for (y = (int)Width - 1; y >= 0; y--)
{
y = rand.Next((int)MaxElevation); //random number for each y.
Elevation[x] = y; //each Elevation gets a random number.
}
}
}
After this I try to use this random number in the draw method like this:
public void Draw(SpriteBatch spriteBatch)
{
for (x = (int)Width - 1; x >= 0; x--)
{
spriteBatch.Draw(Pixel, new Rectangle((int)Position.X + x, (int)Position.Y - Elevation[x], 1, (int)Height), Color.White);
//HERE, I try to acces the random number for each Elevation (y value). But I get 0 everywhere.
}
}
How can I acces this random number?
If I do that:
public void Draw(SpriteBatch spriteBatch)
{
for (x = (int)Width - 1; x >= 0; x--)
{
for (y = (int)Width - 1; y >= 0; y--)
{
y = rand.Next((int)MaxElevation);
spriteBatch.Draw(Pixel, new Rectangle((int)Position.X + x, (int)Position.Y - Elevation[y], 1, (int)Height), Color.White);
}
}
}
I will be able to acces the random numbers, but it will update every frame and the random numbers will change. So I need to calculate them once and then use them.
Here is all the code:
namespace procedural_2dterrain
{
class Terrain
{
Texture2D Pixel;
Vector2 Position;
Random rand;
int[] Elevation;
float MaxElevation;
float MinElevation;
float Width;
float Height;
int x;
int y;
public void Initialize( ContentManager Content, float maxElevation, float minElevation, float width, float height, Vector2 position)
{
Pixel = Content.Load<Texture2D>("pixel");
rand = new Random();
Elevation = new int[(int)width];
MaxElevation = maxElevation;
MinElevation = minElevation;
Width = width;
Height = height;
Position = position;
elevation();
}
public void Update()
{
}
public void elevation()
{
for (x = (int)Width - 1; x >= 0; x--)
{
for (y = (int)Width - 1; y >= 0; y--)
{
y = rand.Next((int)MaxElevation);
Elevation[x] = y;
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
for (x = (int)Width - 1; x >= 0; x--)
{
spriteBatch.Draw(Pixel, new Rectangle((int)Position.X + x, (int)Position.Y - Elevation[x], 1, (int)Height), Color.White);
}
}
}
}

The problem is with your elevation() method. You are using y as your inner loop indexer and also assigning a value to it within the loop. So the loop starts, y is assigned a random value. As it continues the loop, it is decremented and then tested for being >=0. The only time this loop will exit is if y is assigned the random number of 0. So that is why all your Elevation are zero.
I am a little confused as to why you think you need an inner loop. Try:
public void elevation()
{
for (x = (int)Width - 1; x >= 0; x--)
{
Elevation[x] = rand.Next((int)MaxElevation);
}
}

Related

Simulation stops after certain UI elements are used

Im working on a project in processing, and I'm having some difficulty with this super annoying bug. All the code is pasted below, 4 class files.
Whenever the "Simulation speed" slider is moved up and then moved back down, the simulation will stop giving no errors. Same thing with the "Auto" button. I have no idea why this is occurring and I've gone through my code following the variables and I don't see anything wrong.
Help!
noisedemo file
int tableHeight = 20;
int tableWidth = 20;
float prismWidth = 10;
float tableTopx = 260;
float tableTopy = 200;
int k = 0;
int simulationSpeed;
int frameCounter;
Prism[][] prisms = new Prism[tableWidth][tableHeight];
//Declare the sliders
Slider simulationSpeedSlider = new Slider(10, 20, 100, 30, "Simulation Speed");
Slider noiseOctaveSlider = new Slider(10, 50, 100, 4, "Noise Ocatave");
Slider noiseScaleSlider = new Slider(10, 80, 100, 10, 10, "Noise Scale", true);
//Declare the buttons
Button autoScrollButton = new Button(400, 100, "Auto");
void setup(){
size(500, 500);
smooth();
pixelDensity(2);
frameRate(30);
noiseDetail((int)noiseOctaveSlider.sliderValue, noiseScaleSlider.sliderValue);
for(int i = 0; i < 20; i++){
for(int j = 0; j < 20; j++){
prisms[i][j] = new Prism(noise(i, j)*30+10, prismWidth);
prisms[i][j].setHeight(noise(i, j)*30+10);
}
}
}
float[] convertCoordinate(int xcoord, int ycoord, float xtop, float ytop, float pwidth){
float[] coord = new float[2];
coord[0] = (xtop + xcoord*cos(radians(40))*prismWidth - ycoord * cos(radians(40))*prismWidth)*0.95;
coord[1] = (ytop + ycoord*sin(radians(40))*prismWidth + xcoord * sin(radians(40))*prismWidth)*0.95;
return coord;
}
void updateHeight(){
for(int i = 0; i < tableWidth; i++){
for(int j = 0; j < tableHeight; j++){
prisms[i][j].drawPrism(convertCoordinate(i, j, tableTopx, tableTopy, prismWidth)[0], convertCoordinate(i, j, tableTopx, tableTopy, prismWidth)[1]);
}
}
}
void setHeight(){
for(int i = 0; i < tableWidth; i++){
for(int j = 0; j < tableHeight; j++){
prisms[i][j].setHeight(noise(i+k, j+k)*30+10);
}
}
}
void mouseClicked(){
if(autoScrollButton.isInRange()){
autoScrollButton.buttonActive = !autoScrollButton.buttonActive;
}
}
void draw(){
background(0, 150, 0);
noiseDetail((int)noiseScaleSlider.sliderValue, noiseScaleSlider.sliderValue);
simulationSpeedSlider.drawSlider();
simulationSpeed = (int)simulationSpeedSlider.sliderValue;
noiseOctaveSlider.drawSlider();
noiseScaleSlider.drawSlider();
autoScrollButton.drawButton();
if(frameCounter == simulationSpeed && autoScrollButton.buttonActive){
k++;
frameCounter = 0;
setHeight();
}
updateHeight();
frameCounter++;
}
button file
class Button{
boolean buttonActive = true;
float buttonX;
float buttonY;
float buttonWidth = 30;
float buttonHeight = 15;
String buttonLabel;
Button(float x, float y, String label){
buttonX = x;
buttonY = y;
buttonLabel = label;
}
void drawButton(){
if(!buttonActive){
fill(100);
rect(buttonX, buttonY, buttonWidth, buttonHeight, 5);
fill(255);
text(buttonLabel, buttonX + 4, buttonY + 10);
}else{
fill(200);
rect(buttonX, buttonY, buttonWidth, buttonHeight, 5);
fill(0);
text(buttonLabel, buttonX + 4, buttonY + 10);
}
}
boolean isInRange(){
if(mouseX > buttonX && mouseX < buttonX + buttonWidth && mouseY > buttonY && mouseY < buttonY + buttonHeight){
return true;
}
else{
return false;
}
}
}
prism file
class Prism{
float pheight;
float pwidth;
Prism(float tempheight, float tempwidth){
pheight = tempheight;
pwidth = tempwidth;
}
Prism(){
pheight = 10;
pwidth = 5;
}
void drawPrism(float x, float y){
noStroke();
fill(175);
quad(x, y, x - cos(radians(40))*pwidth, y - sin(radians(40))*pwidth, x - cos(radians(40))*pwidth, y - sin(radians(40))*pwidth - pheight, x, y - pheight);
fill(100);
quad(x, y, x + cos(radians(40))*pwidth, y - sin(radians(40))*pwidth, x + cos(radians(40))*pwidth, y - sin(radians(40))*pwidth - pheight, x, y - pheight);
fill(225);
quad(x, y - pheight, x - cos(radians(40))*pwidth, y - sin(radians(40))*pwidth - pheight, x, y - 2*sin(radians(40))*pwidth - pheight, x + cos(radians(40))*pwidth, y - sin(radians(40))*pwidth - pheight);
}
void setHeight(float tempheight){
pheight = tempheight;
}
}
slider file
class Slider{
float sliderLength;
float sliderX;
float sliderY;
float sliderWidth;
float handleWidth;
float sliderValue;
float sliderPos;
int sliderTotal;
boolean handleActive;
boolean isPrecise;
String sliderLabel;
//provide x and y position, length and the max value, the least amount of info
Slider(float x, float y, float slength, int total){
sliderX = x;
sliderY = y;
sliderLength = slength;
sliderWidth = 10;
handleWidth = sliderWidth*1.5;
sliderTotal = total;
sliderPos = sliderX + sliderWidth/2;
sliderLabel = "";
}
//provide x and y position, length and the max value AND a label
Slider(float x, float y, float slength, int total, String label){
sliderX = x;
sliderY = y;
sliderLength = slength;
sliderWidth = 10;
handleWidth = sliderWidth*1.5;
sliderTotal = total;
sliderPos = sliderX + sliderWidth/2;
sliderLabel = label;
}
//provide default values AND a label AND a width AND whether its precise
Slider(float x, float y, float slength, float swidth, int total, String label, boolean p){
sliderX = x;
sliderY = y;
sliderLength = slength;
sliderWidth = swidth;
handleWidth = sliderWidth*1.5;
sliderTotal = total;
sliderPos = sliderX + sliderWidth/2;
sliderLabel = label;
isPrecise = p;
}
void drawSlider(){
fill(255);
textSize(10);
text(sliderLabel, sliderX, sliderY - 5);
text(sliderValue, sliderX + sliderLength + 7, sliderY + sliderWidth/1.1);
fill(100);
rect(sliderX-1, sliderY, sliderLength+1, sliderWidth, 5);
fill(255);
ellipse(sliderPos, sliderY + (sliderWidth/2), handleWidth, handleWidth);
if(!isPrecise){
sliderValue = (int)((sliderPos - sliderX)/(sliderLength/sliderTotal));
}else if(isPrecise){
sliderValue = (sliderPos - sliderX)/(sliderLength/sliderTotal);
}
if(mouseX >= sliderX && mouseX <= sliderX+sliderLength + sliderX && mouseY >= sliderY - (handleWidth/2) && mouseY <= sliderY + (handleWidth/2) && mousePressed){
handleActive = true;
}
if(!mousePressed){
handleActive = false;
}
if(handleActive && sliderPos <= sliderX + sliderLength && sliderPos >= sliderX){
sliderPos = mouseX;
}
if(sliderPos > sliderX + sliderLength){
sliderPos = sliderX + sliderLength;
}
if(sliderPos < sliderX){
sliderPos = sliderX + 1;
}
}
}
Thank you! Sorry if the code is a little messy :)
In your main file, this block relies on the values of those two controls:
if(frameCounter == simulationSpeed && autoScrollButton.buttonActive){
k++;
frameCounter = 0;
setHeight();
}
When that gets skipped (because you changed simulationSpeed or buttonActive), your frameCounter gets out of sync with simulationSpeed so the block continues to get skipped.

Is there a way for me to distribute points so that they're more compact near a different set of points?

I want to make a Voronoi tiling which fits itself to some text in Processing 3.5.3. I've got the algorithm for standard Voronoi tiling implemented, but I initialise all points to just be randomly distributed across the window.
I've got a list of points which make up some letters, generated by the geomerative package. They're all in the standard (x, y) format.
I'm looking for a function which would take the text points and the window size into account and give me back a sort of distribution, or, better yet, a list of points already following that distribution.
My code:
import geomerative.*;
public class Point {
public RPoint p = new RPoint(0, 0);;
public color c;
public boolean isTextPt;
public Point(int _w, int _h, float[][] distribution) {
this.p.x = random(_w);
this.p.y = random(_h);
//this.c = color(random(100, 250), random(100, 250), random(100, 250));
this.c = color(map(p.x, 0, _w, 50, 160), map(p.y, 0, _h, 0, 150), 255);
this.isTextPt = false;
}
public Point(float _x, float _y) {
this.p.x = _x;
this.p.y = _y;
this.c = color(random(50, 160), random(100, 250), 255);
this.isTextPt = true;
}
}
int baseAmountOfCells = 50;
RShape shape;
RPoint[] textPts;
Point[] points;
void setup() {
RG.init(this);
shape = new RFont("RobotoMono-Medium.ttf", 140, RFont.CENTER).toShape("voronoi songs for worley days");
textPts = shape.getPoints();
fullScreen();
colorMode(HSB);
points = new Point[baseAmountOfCells + textPts.length];
for (int i = 0; i < baseAmountOfCells; i ++) {
points[i] = new Point(width, height);
}
for (int i = 0; i < textPts.length; i ++) {
points[baseAmountOfCells + i] = new Point(textPts[i].x / 2 + width / 2, textPts[i].y / 2 + height / 2);
}
println("Amount of text points: " + str(textPts.length));
}
void draw() {
loadPixels();
int index = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float record = width * height; //it can never be more than this
int recIndex = 0;
for (int i = 0; i < points.length; i++) {
float d = dist(x, y, points[i].p.x, points[i].p.y);
if (d < record) {
record = d;
recIndex = i;
}
}
Point pt = points[recIndex];
pixels[index] = color(pt.c);
index++;
}
}
updatePixels();
for (Point pt : points) {
if (pt.isTextPt) {
stroke(0);
strokeWeight(2);
point(pt.p.x, pt.p.y);
}
}
noLoop();
}

Buggy bouncing balls

I was making a colliding ball sketch in Processing, and I encountered a weird bug. Despite having a condition for bouncing off of the walls, some balls get stuck to it. I can't find the source of error here. Can someone help? I also realise that there maybe few (a lot) bad coding practices, but I apologise beforehand.
I am posting the codes below.
1) Main : https://pastebin.com/hv0H14gZ
particle[] elec = new particle[5];
boolean record = false;
void setup(){
float x=0,y=0;
int i,j;
float diam = 100;
size(800,400);
//Initialising the particle objects
for (int k = 0; k < elec.length; k++){
x = random(width/10, width/1.2);
y = random(height/10, height/1.2);
elec[k] = new particle(x,y);
}
//Spawning at random places
for ( i = 0; i < elec.length; i++){
if (i!=0){
for ( j = 0; j < elec.length; j ++){
if (dist(x,y,elec[j].getX(),elec[j].getY()) <= diam){
x = random(width/10, width/1.2);
y = random(height/10, height/1.2);
j = -1;
}
}
}
elec[i] = new particle(x,y,diam,4,4,2);
}
}
void draw(){
background(0);
for (int i = 0; i < elec.length; i++){
elec[i].update(elec);
elec[i].move();
elec[i].bounce();
if(record){
saveFrame("collide_#####.png");
fill(255,0,0);
} else {
fill(0,255,0);
}
ellipse(width/1.01, height/1.01,5,5);
}
}
void keyPressed(){
if (key =='r' || key =='R'){
record = !record;
}
}
2) Classes : https://pastebin.com/Rt49sN9c
public class velocity{
float delx, dely;
//Constructor 1
public velocity(){}
//Constructor 2
public velocity(float delx, float dely){
this.delx = delx;
this.dely = dely;
}
//Mutators for xvelocity and y velocity
public float getdelx(){
return this.delx;
}
public float getdely(){
return this.dely;
}
//Accessors for xvelocity and y velocity
public void setdelx(float delx){
this.delx = delx;
}
public void setdely(float dely){
this.dely = dely;
}
}
public class particle{
private float xpos , ypos, delx , dely,size, decay, mass;
color colour;
//constructor 1
public particle(float x, float y){
this.xpos = x;
this.ypos = y;
}
//constructor 2
public particle(float xpos, float ypos, float size, float delx, float dely, float mass){
this.xpos = xpos;
this.ypos = ypos;
this.size = size;
this.delx = delx;
this.dely = dely;
this.mass = mass;
}
//Mutators for size, x velocity y velocity and velocity vector
public void setsize(float size){
this.size = size;
}
public void setDX(float delx){
this.delx = delx;
}
public void setDY(float dely){
this.dely = dely;
}
//Accessors for size, x position, y position, x velocity and y velocity
public float getsize(){
return this.size;
}
public float getX(){
return this.xpos;
}
public float getY(){
return this.ypos;
}
public float getDX(){
return this.delx;
}
public float getDY(){
return this.dely;
}
public float getmass(){
return this.mass;
}
public velocity getvel(){
velocity v = new velocity(this.getDX(), this.getDY());
return v;
}
//Functionality. Moving around, Bouncing off of walls, and basic display updates
public void move(){
this.xpos += this.delx;
this.ypos += this.dely;
}
public void bounce(){
if((this.xpos - this.size/2.0) < 0 || (this.xpos + this.size/2.0) > width){
this.setDX(this.getDX()*-1);
}
if((this.ypos - this.size/2.0) < 0 || (this.ypos + this.size/2.0) > height){
this.setDY(this.getDY()*-1);
}
}
public void update(particle[] elec){
for(int i =0; i< elec.length; i++){
if(this == elec[i]) continue;
if(dist(this.getX(),this.getY(),elec[i].getX(),elec[i].getY()) - this.getsize() <0){
collision(this, elec[i]);
//println(dist(this.getX(),this.getY(),elec[i].getX(),elec[i].getY()) - this.getsize()/2);
}
}
display();
}
public void display(){
stroke(0);
fill(119,240,153);
ellipse(this.xpos, this.ypos, this.size ,this.size);
}
}
velocity rotate(velocity v, float angle){
float x = v.getdelx()*cos(angle) - v.getdely()*sin(angle);
float y = v.getdelx()*sin(angle) + v.getdely()*cos(angle);
velocity vel = new velocity(x,y);
return vel;
}
void collision(particle p1, particle p2){
float xveldiff = p1.getDX()-p2.getDX();
float yveldiff = p1.getDY()-p2.getDY();
float xdist = p2.getX() - p1.getX();
float ydist = p2.getY() - p1.getY();
//Check for accidental overlaps of particles
if(xveldiff*xdist + yveldiff*ydist > 0){
float angle = -atan2(p2.getY() - p1.getY(), p2.getX() - p1.getY());
float m1 = p1.getmass();
float m2 = p2.getmass();
velocity u1 = rotate(p1.getvel(),angle);
velocity u2 = rotate(p2.getvel(),angle);
velocity v1 = new velocity(u1.getdelx() * (m1 - m2) / (m1 + m2) + u2.getdelx() * 2 * m2 / (m1 + m2), u1.getdely());
velocity v2 = new velocity(u2.getdelx() * (m1 - m2) / (m1 + m2) + u1.getdelx() * 2 * m2 / (m1 + m2), u2.getdely());
velocity vf1 = rotate(v1, -angle);
velocity vf2 = rotate(v2, -angle);
p1.setDX(vf1.getdelx());
p1.setDY(vf1.getdely());
p2.setDX(vf2.getdelx());
p2.setDY(vf2.getdely());
}
}
Nice animation, the issue is cased by the method bounce of class particle:
When the "ball" doesn't leave the wall in one step, then it sticks.
Note, if e.g the condition (this.xpos - this.size/2.0) < 0 is fulfilled twice, the the direction is inverted twice (this.getDX()*-1). This causes that the ball bounce into the wall continuously and leads to a trembling movement along the wall.
public void bounce(){
if((this.xpos - this.size/2.0) < 0 || (this.xpos + this.size/2.0) > width){
this.setDX(this.getDX()*-1);
}
if((this.ypos - this.size/2.0) < 0 || (this.ypos + this.size/2.0) > height){
this.setDY(this.getDY()*-1);
}
}
You have to ensure, the the direction (delx, dely) always points away from the wall, if the ball is to near to it:
public void bounce(){
if( this.xpos - this.size/2.0 < 0 ) {
this.setDX( Math.abs(this.getDX()) );
} else if( this.xpos + this.size/2.0 > width ) {
this.setDX( -Math.abs(this.getDX()) );
}
if( this.ypos - this.size/2.0 < 0 ) {
this.setDY( Math.abs(this.getDY()) );
} else if( this.ypos + this.size/2.0 > height ) {
this.setDY( -Math.abs(this.getDY()) );
}
}

Array is only displaying 1 object instead of the full amount of variables

I'm new to coding (as I'm sure you might be able to tell). The program runs and generates 1 Tubble, but the additional objects don't show.
Here's my class:
class Tubble {
float x;
float y;
float diameter;
float yspeed;
float tempD = random(2,86);
Tubble() {
x = random(width);
y = height-60;
diameter = tempD;
yspeed = random(0.1, 3);
}
void ascend() {
y -= yspeed;
x = x + random(-2, 2);
}
void dis() {
stroke(0);
fill(127, 100);
ellipse(x, y, diameter, diameter);
}
void top() {
if (y < -diameter/2) {
y = height+diameter/2;
}
}
}
Class
class Particle {
float x, y;
float r;
float speed = 2.2;
int direction = 1;
PImage pbubbles;
Particle(float x_, float y_, float r_) {
x = x_;
y = y_;
r = r_;
}
void display() {
stroke(#F5D7D7);
strokeWeight(2.2);
noFill();
ellipse(x, y, r*2, r*2);
}
boolean overlaps(Particle other) {
float d = dist(x, y, other.x, other.y);
if (d < r + other.r) {
return true;
} else {
return false;
}
}
void move() { //testing
x += (speed * direction);
if ((x > (width - r)) || (x < r)) {
direction *= -1;
}
}
void updown() {
y += (speed * direction);
if ((y > (height - r)) || (y < r)) {
direction *= -1;
}
}
}
Main sketch:
Tubble[] tubbles = new Tubble [126];
PImage bubbles;
Particle p1;
Particle p2;
Particle p3;
Particle p4;
Particle p5;
float x,y;
float speed;
int total = 0;
int i;
//int direction = 1;
void setup() {
size(800, 925);
bubbles = loadImage("purple_bubbles.png");
p1 = new Particle (100, 100, 50);
p2 = new Particle (500, 200, 100);
p3 = new Particle (600, 600, 82);
p4 = new Particle (height/2, width/2, 200);
p5 = new Particle ((height/3), (width/3), 20);
for (int i = 0; i < tubbles.length; i++); {
tubbles[i] = new Tubble();
}
}
void mousePressed() {
total = total + 1;
}
void keyPressed() {
total = total - 1;
}
void draw() {
image(bubbles, 0, 0, 800, 925);
//background(0);
for (int i = 0; i < tubbles.length; i++); {
tubbles[i].ascend();
tubbles[i].dis();
tubbles[i].top();
}
if ((p2.overlaps(p1)) && (p2.overlaps(p4))) {
background(#BF55AB, 25);
}
if ((p3.overlaps(p2)) && (p3.overlaps(p4))) {
background(#506381, 80);
}
p2.x = mouseX;
p3.y = mouseY;
p1.display();
p2.display();
p3.display();
p4.display();
p5.display();
p4.move();
p5.updown();
// for (int i = 0; i < tubbles.length; i++); {
// tubbles[i].dis();
// tubbles[i].ascend();
// tubbles[i].top();
// }
}
There are extra semicolons in the lines
for (int i = 0; i < tubbles.length; i++); {
for (int i = 0; i < tubbles.length; i++); {
// for (int i = 0; i < tubbles.length; i++); {
It make the for loop do virtually nothing.
Then the block after the for loop will read the global variable i and do the action only once.
Remove the semicolons like this to put the block in the loop.
for (int i = 0; i < tubbles.length; i++) {
for (int i = 0; i < tubbles.length; i++) {
// for (int i = 0; i < tubbles.length; i++) {

why do the circles disappear from the screen?

Processing code as below, one quick question: why do the circles disappear from the screen when my mouse is playing with them? i've already add the boundary check however it does not seem to work. why???
int maxCircle = 200;
float minDistance=30;
float distance1;
float distance2;
Circle [] circles= new Circle[maxCircle];
void setup() {
size(800,800);
smooth();
for(int i=0;i<maxCircle;i++){
circles[i] = new Circle(random(width),random(height),random(2,20));
}
}
void draw() {
background(255,255);
for(int i=0;i<maxCircle;i++) {
circles[i].update(width,height);
for (int j=0; j<maxCircle; j++) {
distance1 = dist(circles[i].x,circles[i].y,circles[j].x,circles[j].y);
if ( distance1 < minDistance ) {
stroke(0,10);
noFill();
line(circles[i].x,circles[i].y,circles[j].x,circles[j].y);
}
}
circles[i].display();
}
}
void mouseMoved() {
for(int i = 0; i<maxCircle;i++) {
distance2 = dist(mouseX,mouseY,circles[i].x,circles[i].y);
circles[i].x-=(mouseX-circles[i].x)/distance2;
circles[i].y-=(mouseX-circles[i].y)/distance2;
if(circles[i].x<circles[i].r || circles[i].x>width-circles[i].r) {
circles[i].vx*=-1;
};
if(circles[i].y<circles[i].r || circles[i].y> height-circles[i].r) {
circles[i].vy*=-1;
}
}
}
class Circle {
float x,y,vx,vy,r,speed;
Circle(float tempx, float tempy, float tempr) {
x=tempx;
y=tempy;
vx=random(-1,1);
vy=random(-1,1);
r=tempr;
}
void update(int w,int h) {
x+=vx;
y+=vy;
if(x<r || x>w-r) {
vx*=-1;
}
if(y<r || y>h-r) {
vy*=-1;
}
}
void display() {
fill(0,50);
noStroke();
ellipse(x,y,r,r);
}
}
Oh i found the solution:
int maxCircle = 200;
float minDistance = 20;
Circle [] circles = new Circle[maxCircle];
void setup() {
size(800, 800);
smooth();
for (int i = 0; i < maxCircle; i++) {
circles[i] = new Circle();
}
}
void draw() {
background(255, 255);
for (int i = 0; i < maxCircle; i++) {
circles[i].update();
noFill();
for (int j = 0; j < maxCircle; j++) {
if (i == j)
continue;
float distance = dist(circles[i].x, circles[i].y, circles[j].x, circles[j].y);
if (distance < minDistance) {
stroke(0, 20);
line(circles[i].x, circles[i].y, circles[j].x, circles[j].y);
}
}
circles[i].display();
}
}
void mouseMoved() {
for (int i = 0; i < maxCircle; i++) {
float distance = dist(mouseX, mouseY, circles[i].x, circles[i].y);
circles[i].x -= (mouseX - circles[i].x) / distance;
circles[i].y -= (mouseX - circles[i].y) / distance;
circles[i].checkBounds();
}
}
class Circle {
float x, y, vx, vy, r, speed;
Circle() {
vx = random(-1, 1);
vy = random(-1, 1);
r = random(1, 10); // See below
x = random(r, width - r);
y = random(r, height - r);
}
void checkBounds() {
if (x < r || x > width - r) {
vx *= -1;
if (x < r) {
x = r;
} else {
x = width - r;
}
}
if (y <= r || y >= height - r) {
vy *= -1;
if (y < r) {
y = r;
} else {
y = width - r;
}
}
}
void update() {
x += vx;
y += vy;
checkBounds();
}
void display() {
fill(0, 50);
noStroke();
ellipse(x, y, r * 2, r * 2);
}
}
in your update() method, when you calculate a new coordinate with your vector, you are potentially setting the coordinate offscreen. I have added 4 conditional statements that reset the value to the bounds of the screen if it exceeds it.
void update(int w,int h) {
x+=vx;
y+=vy;
if(x<r || x>w-r) {
vx*=-1;
if (x>w-r) x = w-r;
if (x<r) x = r;
}
if(y<r || y>h-r) {
vy*=-1;
if (y>h-r) y = h-r;
if (y<r) y = r;
}
}

Resources