So I have a sketch that contains hundreds of different-sized rectangles, saved in an array list, when I put my mouse on them they get pushed away, but when I move away and let them go back to position they go back and stutter in their position, they never go back to being still. This caused me so much frustration!!
Help?!
EDIT:
Well, this problem happens when a lot of squares are moved together, i'll put as little code as I can..
When this class gets initialized with an image, it places squares based on the image's colors.
class Picture extends PApplet {
int w, h;
PApplet parent;
PImage image;
PImage originalImage;
boolean started = false;
Frame frame;
int resolution = 18;
ArrayList<Square> sqrs = new ArrayList<Square>();
ArrayList<GravityPoint> points = new ArrayList<GravityPoint>();
boolean original = false;
Picture(PApplet _parent, PImage _img) {
super();
parent = _parent;
setImage(_img);
runSketch(new String[]{"Picture"}, this);
started = true;
frame = ((SmoothCanvas)getSurface().getNative()).getFrame();
}
void settings() {
size(w, h);
}
void setup() {
background(0);
sqrs.clear();
points.clear();
for (int i = 0; i < image.width; i += resolution)
for (int j = 0; j < image.height; j += resolution) {
Square sq = new Square(new PVector(i, j), (int) random(3, 15), getGraphics());
sq.setColor(image.get(i, j));
sqrs.add(sq);
points.add(new GravityPoint(sq.pos.copy()));
sqrs.get(sqrs.size() - 1).point = points.get(points.size() - 1);
}
}
void draw() {
background(0);
background(0);
if (original) image(originalImage, 0, 0);
else {
for (Square sq : sqrs) {
sq.update();
sq.show(null);
}
}
}
void mouseMoved() {
int radius = 100;
for (Square sq : sqrs) {
PVector mousePos = new PVector(mouseX, mouseY);
float distance = sq.pos.dist(mousePos);
if (distance <= radius) {
PVector force = mousePos.copy().sub(sq.pos.copy()).mult(-1 * map(distance, 0, radius, 5, 1));
sq.applyForce(force);
}
}
}
void mousePressed() {
if (mouseButton == RIGHT) frame.dispose();
if (mouseButton == LEFT) original = !original;
}
void keyPressed() {
int temp = resolution;
if (keyCode == DOWN) resolution++;
else if (keyCode == UP) resolution--;
else return;
resolution = constrain(resolution, 1, 18);
if (temp == resolution) return;
image = originalImage;
originalImage = originalImage.copy();
setup();
}
void setImage(PImage image_) {
image = image_;
int dw = parent.displayWidth;
int dh = parent.displayHeight;
if (image.width > dw) image.resize(dw, 0);
if (image.height > dh) image.resize(0, dh);
w = image.width;
h = image.height;
if (started) surface.setSize(w, h);
originalImage = image.copy();
}
}
This is the square class
class Square {
PVector pos = new PVector(0, 0);
PVector vel = new PVector(0, 0);
PVector acc = new PVector(0, 0);
PVector grv = new PVector(0, 0);
int size = 5;
GravityPoint point;
color col;
color coll;
PGraphics graphics;
Square(PVector p, int s, PGraphics gra) {
graphics = gra;
pos = p.copy();
size = s;
}
void show(PGraphics gr) {
PGraphics graphics;
if (gr != null)
graphics = gr;
else
graphics = this.graphics;
graphics.beginDraw();
graphics.pushStyle();
smooth();
graphics.rectMode(CENTER);
if (col == coll) graphics.colorMode(HSB, 255, 255, 255);
else graphics.colorMode(RGB, 255, 255, 255);
color c = color(map(pos.x, 30, width-30, 100, 255), 255, 255);
graphics.stroke(col == coll ? c : col);
graphics.strokeWeight(0.5);
graphics.noFill();
graphics.rect(pos.x, pos.y, size, size);
//graphics.shape(shape);
graphics.popStyle();
graphics.endDraw();
}
Square setColor(color _col) {
col = _col;
return this;
}
void update() {
if (point != null) applyForce(point.getVector(this).mult(4));
vel.add(acc);
vel.add(grv);
vel.limit(5);
pos.add(vel);
if (point == null) vel.mult(0);
acc.mult(0);
if (point != null && pos.dist(point.pos) < size/2) {
vel.mult(0);
acc.mult(0);
}
}
void applyForce(PVector force) {
acc.add(force);
}
}
And this class is responsible of pulling the rectangles back into place
class GravityPoint{
PVector pos;
GravityPoint(PVector p){
pos = p.copy();
}
PVector getVector(Square sq){
return pos.copy().sub(sq.pos);
}
Square closest(ArrayList<Square> sqrs){
if(sqrs.size() <= 0) return null;
float distance = Float.MAX_VALUE;
Square closest = null;
for(Square sq : sqrs)
if(sq.point == null && sq.pos.dist(pos) < distance){
distance = sq.pos.dist(pos);
closest = sq;
}
return closest;
}
}
EDIT 2:
This code I think replicates the same problem happening in my main program, not 100% sure, I would much appreciate it if you try helping me with my main sketch! <3
(Put the mouse on the square then move it away)
PVector pos;
PVector vel;
PVector acc;
PVector point;
void setup() {
size(500, 500);
pos = new PVector(width/2, height/2);
point = new PVector(width/2, height/2);
vel = new PVector(0, 0);
acc = new PVector(0, 0);
}
void draw() {
background(255);
PVector mouse = new PVector(mouseX, mouseY);
if (mouse.dist(pos) <= 50)
acc.add(mouse.copy().sub(pos).mult(-1));
acc.add(point.copy().sub(pos).mult(3));
vel.add(acc);
vel.limit(4);
pos.add(vel);
acc.mult(0);
rectMode(CENTER);
rect(pos.x, pos.y, 30, 30);
}