Trying to slow down ellipses in a small space

Hello everyone!

I’m trying to make it so the “fireflies” in my code, while in the cup, move slower.
So far, the fireflies bounce off the walls, and once the player presses ‘g’, a cup is grabbed, and if the cup makes contact with a firefly, the firefly goes in the cup and bounces around in there, until released when the player pressed ‘p’.
However, while the fireflies are in the cup, they bounce around really fast. I’ve been trying to make it so they slow down (or even go the speed they are while outside the cup) but I can’t seem to do it.
I’ve tried to slow them by lowering the speed they move while in the cup, however, this either just doesn’t work, or only slows them after ‘p’ is pressed. I listed below some code I’ve tried.

I appreciate all the help I could get! Thank you in advance!

``````
ArrayList <Fireflies> firefly;
float fireflies = 15; //num of fireflies
float cx = 200; //sitting cup position x
float cy = 200; //sitting cup position y
float cupW = 100; //cup width
float cupH = 135; //cup height

boolean inCup = false;

void setup() {
size(600, 600);
background(0);
firefly = new ArrayList <Fireflies>();

for (int f = 0; f < fireflies; f++) {
}
}

void draw() {
background(0);

//fireflies
for (int f = 0; f < fireflies; f++) {
firefly.get(f).display();
}
}

class Fireflies {

float size = random(1, 20);
float xpos = random(0, width);
float ypos = random(0, height);
float xspeed = 1;
float yspeed = 1;
float xdir = random(-1, 1);
float ydir = random(-1, 1);

Fireflies() {
}

void update() {
xpos = xpos + (xspeed * xdir);
ypos = ypos + (yspeed * ydir);
}

void checkInCup() {
if (inCup == true) { //changes the position of the fireflies to inside the cup
xpos = random(cx, cx + cupW) + (xspeed * xdir);
ypos = random(cy, cy + cupH) + (yspeed * ydir);

//I tried to slow them down by incrementing the speed in small amounts- this didn't stop them
//while inside the jar

//xpos = random(cx, cx + cupW) + (xspeed/16* xdir/16);
//ypos = random(cy, cy + cupH) + (yspeed/16 * ydir/16);
}
}

void checkEdges() {
if (inCup == false) {//if not in cup, bounces off sides of wall
if (xpos > width-size || xpos < size) {
xdir *=  -1 ;
}
if (ypos > height-size || ypos < size) {
ydir *= -1;
} else if (inCup == true) { //if in cup, bounces off sides of cup
if (xpos > cx-size || xpos < cx) {
xdir *= -1;
//I also tried to slow them down here by making xdir a smaller number
//xdir *= -.001
//this also didn't slow them down in the cup
}
if (ypos > cy-size || ypos < cy) {
ydir *= -1;
}
}
}
}

void display() {
update();
checkEdges();
checkInCup();

//draw fireflies
for (int f = 0; f < 1; f++) {
fill(100, 100, 0);
circle(xpos, ypos, size);
}

//grab cup
if (key == 'g') {
cx = mouseX;
cy = mouseY;
if (xpos > cx && ypos > cy) {
inCup = true;
//if the x&y pos. of the fireflies collide w/ the cup's x&y,
//the fireflies go in the cup
//i know this collision detection is... bad but it's not my focus right now :/
}
}

//put cup down
if (key == 'p') {
cx = 200;
cy = 200;
inCup = false;
}

//cup
fill(0, 230, 255, 50);
rect(cx, cy, cupW, cupH);
}
}

``````

there is a few points to be criticized here

(this is only my personal opinion)

Remark 1

I think this:

``````boolean inCup = false;
``````

must be INSIDE the class, because it’s an individual property of each firefly and therefore cannot be
globally.

Remark 2

Check whether the firefly is really inside the cup:

``````    if (xpos > cupX &&
ypos > cupY &&
xpos < cupX+cupW &&   // you didn't have this line
ypos < cupY+cupH) {    // you didn't have this line
inCup = true;
} else {
inCup = false;       // you didn't have this line
}
``````

Remark 3

In display() inside the class you have

``````    //draw fireflies
for (int f = 0; f < 1; f++) {
fill(100, 100, 0);
circle(xpos, ypos, size);
}
``````

doesn’t make sense.

In the class we only look at ONE firefly.

We have just

``````      fill(100, 100, 0);
circle(xpos, ypos, size);
``````

(we do the for-loop in draw(), not here)

Remark 4

The class should be single purpose.

So you shouldn’t draw the cup inside the
class!!!

(also you display the cup every time you show a firefly, which is far too often. Just move these lines to draw())

``````    //grab cup
if (key == 'g') {
cx = mouseX;
cy = mouseY;
if (xpos > cx && ypos > cy) {
inCup = true;
//if the x&y pos. of the fireflies collide w/ the cup's x&y,
//the fireflies go in the cup
//i know this collision detection is... bad but it's not my focus right now :/
}
}

//put cup down
if (key == 'p') {
cx = 200;
cy = 200;
inCup = false;
}

//cup
fill(0, 230, 255, 50);
rect(cx, cy, cupW, cupH);
}
``````

My version

``````
// class name singular (represents ONE firefly only; list name plural: represents many fireflies
ArrayList <Firefly> fireflies;

// better name here:
float firefliesNumber = 15; //num of fireflies

// better names here:
float cupX = 200; //sitting cup position x
float cupY = 200; //sitting cup position y
float cupW = 100; //cup width
float cupH = 135; //cup height

void setup() {
size(600, 600);
background(0);

fireflies = new ArrayList <Firefly>();

for (int f = 0; f < firefliesNumber; f++) {
}//for
}//func

void draw() {
background(0);

//grab cup
if (key == 'g') {
cupX = mouseX;
cupY = mouseY;
}

//put cup down
if (key == 'p') {
cupX = 200;
cupY = 200;
}

//cup
fill(0, 230, 255, 50);
rect(cupX, cupY,
cupW, cupH);

//fireflies
for (int f = 0; f < firefliesNumber; f++) {
fireflies.get(f).display();
}//for
//
}//func

//====================================================================================

class Firefly {

float size = random(1, 20);
float xpos = random(0, width);
float ypos = random(0, height);
float xspeed = 1;
float yspeed = 1;
float xdir = random(-1, 1);
float ydir = random(-1, 1);

boolean inCup = false; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Firefly() {
// empty constructor
}

void update() {
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (! inCup) { // means == false
xpos = xpos + (xspeed * xdir);
ypos = ypos + (yspeed * ydir);
} else {
xpos = xpos + (xspeed * xdir * 0.51); // SLOW
ypos = ypos + (yspeed * ydir * 0.51);
}//else
}//method

void checkInCup() {
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (xpos > cupX &&
ypos > cupY &&
xpos < cupX+cupW &&
ypos < cupY+cupH) {
inCup = true;
} else {
inCup = false;
}
}//method

void checkEdges() {

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

if (! inCup) {
// if not in cup, bounces off sides of wall
if (xpos > width-size || xpos < size) {
xdir *=  -1;
}
if (ypos > height-size || ypos < size) {
ydir *= -1;
}
}
//--------

else {
// PREVIOULY: THIS CANNOT BE REACHED EVER !!!!!!!!!!!!!!!!!!!!!!!!!
// if in cup, bounces off sides of cup
if (xpos < cupX+size) {
xdir = abs (xdir);
//I also tried to slow them down here by making xdir a smaller number
//xdir *= -.001
//this also didn't slow them down in the cup
}
if (xpos > cupX+cupW) {
xdir = - abs (xdir);
}

if (ypos < cupY+size) {
ydir = abs (ydir);
}
if (ypos > cupY+cupH) {
ydir = -1 * abs (ydir);
}
}
//
}//method

void display() {
// MAIN FUNCTION OF THE CLASS
update();
checkEdges();
checkInCup();

//draw firefly
fill(100, 100, 0);
ellipse(xpos, ypos, size, size);
}//method
//
}//class
//

``````

I concentrated on doing this.

The firefly can enter the cup when it stands still. They are then trapped.

That’s also to do.

Okay, I might start crying. This is honestly fantastic, thank you so much! I tried it all and it works great!!

For the fireflies being released, I made a temporary fix, where the user presses ‘r’ and inCup is made false.

`````` void checkInCup() {

if (xpos > cupX &&
ypos > cupY &&
xpos < cupX+cupW &&
ypos < cupY+cupH) {
inCup = true;
} else {
inCup = false;
}//else

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> here is the change!
//release fireflies
if (key == 'r') {
inCup = false;
}
//
}//method
``````

I’m not sure if it belongs in the checkInCup() function, but it does achieve what I want. I also wonder if there is a way to keep the fireflies in the cup, and not have them leave as it moves? Sort of like keeping a lid on it, so the fireflies don’t escape when the cup is dragged.

Nonetheless, I truly appreciate the help. I’ve only been coding for about a year now, mostly self-taught, so I appreciate all the formatting critiques I can get. Thanks again!

1 Like

Remark

I would change your change to

``````    //release fireflies
if (keyPressed && key == 'r') {
inCup = false;
}
``````

so it’s not permanent (but only when you actual hold the key).

Remark

You can a make a 2nd class Cup. Just as a practice.
It would hold the cup data and some methods.

Remark

I show you a new for-loop:

This:

``````  for (int f = 0; f < firefliesNumber; f++) {
``````

can be

``````   for (Firefly currentFirefly : fireflies) {
``````

No `.get(....)` needed anymore. Nice.

(This is not possible in setup(), only in draw())

Remark

Actually in the class when saying

` if (xpos < cupX+size) {` etc.

we want

` if (xpos < cupX+size/2) {`

because size is the diameter, not the radius for ellipse() command. Check reference for ellipse() command and ellipseMode().

New version

Check this out.

You can drag and drop the cup now with the mouse (check variable `drag`). No g/p keys needed anymore!

During drag, the fireflies inside the cup are moved together with the cup.

Release with r.

Warm regards,

Chrisir

``````// class name singular (represents ONE firefly only; list name plural: represents many fireflies
ArrayList <Firefly> fireflies;

// better name here:
float firefliesNumber = 15; //num of fireflies

// better names here:
float cupX = 200; //sitting cup position x
float cupY = 200; //sitting cup position y
float cupW = 100; //cup width
float cupH = 135; //cup height

boolean drag = false;
PVector offset=new PVector(0, 0);

// ----------------------------------------------------------------------------

void setup() {
size(600, 600);
background(0);

fireflies = new ArrayList <Firefly>();

for (int f = 0; f < firefliesNumber; f++) {
}//for
}//func

void draw() {
background(0);

// keys
checkKeys();

//cup
fill(0, 230, 255, 50);
noStroke();
if (drag)
stroke(211);
rect(cupX, cupY,
cupW, cupH);
// reset
noStroke();

float x1=0, y1=0;
if (drag) {
// DRAG cup
x1=mouseX-pmouseX;
y1=mouseY-pmouseY;
cupX = mouseX-offset.x;
cupY = mouseY-offset.y;
}

//fireflies
for (Firefly currentFirefly : fireflies) {
if (drag&&currentFirefly.inCup) {
currentFirefly.xpos+=x1;
currentFirefly.ypos+=y1;
}
currentFirefly.display();
}//for
//
}//func

// ----------------------------------------------------------------------------

void checkKeys() {
//  you can delete this
if (! keyPressed)
return;

if (key == 'g') {
//grab cup
cupX = mouseX;
cupY = mouseY;
} else if (key == 'p') {
//put cup down
cupX = 200;
cupY = 200;
}
}

void mousePressed() {
if (mouseX > cupX &&
mouseY > cupY &&
mouseX < cupX+cupW &&
mouseY < cupY+cupH) {
drag = true;
offset.set(mouseX-cupX,
mouseY-cupY);
}
}

void mouseReleased() {
drag=false;
}

//==================================================================

class Firefly {

float size = random(2, 20);

// location
float xpos = random(0, width);
float ypos = random(0, height);

// speed (gets changed in the constructor. Here we avoid that a value is 0 or close to 0)
float xdir = random(0.32, 1.1);
float ydir = random(0.32, 1.1);

boolean inCup = false;

Firefly() {
// constructor

if (random(1)<0.5)
xdir*=-1;
if (random(1)<0.5)
ydir*=-1;
}

void update() {
// move
if (! inCup) {
xpos = xpos + (xdir); // fast
ypos = ypos + (ydir);
} else {
xpos = xpos + (xdir * 0.31); // SLOW
ypos = ypos + (ydir * 0.31);
}//else
}//method

void checkInCup() {
// set inCup field
if (xpos > cupX &&
ypos > cupY &&
xpos < cupX+cupW &&
ypos < cupY+cupH) {
inCup = true;
} else {
inCup = false;
}

//release fireflies
if (keyPressed && key == 'r') {
inCup = false;
}
//
}//method

void checkEdges() {
//
if (! inCup) {
// if not in cup, bounces off sides of wall
if (xpos > width-size/2 ) {
xdir =  -1 * abs(xdir);
}
if (xpos < size/2) {
xdir =  abs(xdir);
}

if (ypos > height-size/2) {
ydir = -1 * abs(ydir);
}
if (ypos < size/2) {
ydir = abs(ydir);
}
}//if

//--------

else {
// if in cup, bounces off sides of cup
if (xpos < cupX+size/2) {
xdir = abs (xdir);
}
if (xpos > cupX+cupW-size/2) {
xdir = - abs (xdir);
}

if (ypos < cupY+size/2) {
ydir = abs (ydir);
}
if (ypos > cupY+cupH-size/2) {
ydir = -1 * abs (ydir);
}
}
//
}//method

void display() {
// MAIN FUNCTION OF THE CLASS
update();
checkEdges();
checkInCup();

//draw firefly
fill(100, 100, 0);
ellipse(xpos, ypos, size, size);
}//method
//
}//class
//
``````