Getting text to appear in front of row of boxes - Processing - processing

Still just learning... So my goal is for the sketch to have the font appear in front of the boxes. I understand why it is behind the row of boxes. It is because the loop immediately goes to the next box and layers it over the font. However, because the variables are defined locally.... I don't really know what else to do...The loop is also crucial for updating purposes.
// Considerations: How to determine if point lies within a rectangle? \
// Hover over rectangle and trigger event
int numOfIndices = 50;
float[][] indexes = new float[numOfIndices][2];
public void setup()
{
frameRate(60);
size(600, 600);
strokeWeight(1);
int offset = width/numOfIndices;
for (int i = 0; i < numOfIndices; i++) {
indexes[i][0] = i*offset + offset/2; // X Coordinate
indexes[i][1] = height/2; // Y Coordinate
}
}
public void draw()
{
background(255);
// loop over each rectangle per frame
for (int i = 0; i < numOfIndices; i++) {
float widthRect = 5;
float heightRect = 20;
// A
float topLeftX = indexes[i][0] - widthRect/2;
float topLeftY = height/2 + heightRect/2;
// C
float bottomRightX = indexes[i][0] + widthRect/2;
float bottomRightY = height/2 - heightRect/2;
if (
mouseX > topLeftX &&
mouseX < bottomRightX &&
mouseY > bottomRightY &&
mouseY < topLeftY
) {
// Inside rectangle. Do something.
stroke(100);
fill(100);
//text(i, indexes[i][0], indexes[i][1]);
} else {
// Not inside rectangle. Do something else.
stroke(200);
fill(200);
}
rectMode(CENTER);
rect(
indexes[i][0], // X
indexes[i][1], // Y
widthRect, // width
heightRect, // height
20 // radi for corners (rounded)
);
if (
mouseX > topLeftX &&
mouseX < bottomRightX &&
mouseY > bottomRightY &&
mouseY < topLeftY
) {
// Inside rectangle. Do something.
textSize(26);
text(i, indexes[i][0], indexes[i][1]);
}
}
}

There are some different ways of doing it. One is as simple as reversing the for loop as follows:
for (int i = numOfIndices-1; i >= 0; i--)
That way the rectangles will be rendered from right to left. It's not a great solution, it will only work in this case because the text location is at the rectangles' right.
A better way is to render all the rectangles and only then render the text. That's quite usual when dealing with UI stuff. That will become:
// Considerations: How to determine if point lies within a rectangle? \
// Hover over rectangle and trigger event
int numOfIndices = 50;
float[][] indexes = new float[numOfIndices][2];
public void setup()
{
frameRate(60);
size(600, 600);
strokeWeight(1);
int offset = width/numOfIndices;
for (int i = 0; i < numOfIndices; i++) {
indexes[i][0] = i*offset + offset/2; // X Coordinate
indexes[i][1] = height/2; // Y Coordinate
}
}
public void draw()
{
background(255);
float widthRect = 5;
float heightRect = 20;
// loop over each rectangle per frame
for (int i = 0; i < numOfIndices; i++) {
// A
float topLeftX = indexes[i][0] - widthRect/2;
float topLeftY = height/2 + heightRect/2;
// C
float bottomRightX = indexes[i][0] + widthRect/2;
float bottomRightY = height/2 - heightRect/2;
if (
mouseX > topLeftX &&
mouseX < bottomRightX &&
mouseY > bottomRightY &&
mouseY < topLeftY
) {
// Inside rectangle. Do something.
stroke(100);
fill(100);
//text(i, indexes[i][0], indexes[i][1]);
} else {
// Not inside rectangle. Do something else.
stroke(200);
fill(200);
}
rectMode(CENTER);
rect(
indexes[i][0], // X
indexes[i][1], // Y
widthRect, // width
heightRect, // height
20 // radi for corners (rounded)
);
}
stroke(100);
fill(100);
for (int i = 0; i < numOfIndices; i++) {
// A
float topLeftX = indexes[i][0] - widthRect/2;
float topLeftY = height/2 + heightRect/2;
// C
float bottomRightX = indexes[i][0] + widthRect/2;
float bottomRightY = height/2 - heightRect/2;
if (
mouseX > topLeftX &&
mouseX < bottomRightX &&
mouseY > bottomRightY &&
mouseY < topLeftY
) {
// Inside rectangle. Do something.
textSize(26);
text(i, indexes[i][0], indexes[i][1]);
}
}
}

Related

Processing - balls to blur for a moment when bounce off the edge of the screen

I'm looking for a way for the balls to blur when the approach the edge of the screen. they should transition back to sharp focus when they approach the centre.
Do you have any advice of how to achieve it?
Hope it makes sense!
ArrayList < Ball > list = new ArrayList();
void setup() {
fullScreen();
for (int iter = 0; iter < 7; iter++) //qty of balls on the screen
list.add(new Ball());
}
void draw() {
background(0);
for (Ball thisBall: list)
thisBall.render();
}
class Ball {
//1.Attributes
float xPos, yPos, xSpeed, ySpeed;
float size;
color colour;
//2.Constructor
Ball() {
xPos = width / 2;
yPos = height / 2;
xSpeed = random(-4, 4);
ySpeed = random(-4, 4);
size = random(700, 1000);
colour = color(random(0,255), random(0,255), random(0,255));
}
//3.Actions
void render() {
stroke(colour,100);
fill(colour, 100);
ellipse(xPos, yPos, size, size);
xPos += xSpeed;
yPos += ySpeed;
if (xPos < 0)
xSpeed *= -1;
if (xPos > width)
xSpeed *= -1;
if (yPos < 0)
ySpeed *= -1;
if (yPos > height)
ySpeed *= -1;
}
}
N
There are several ways to do this... although I feel like the "normal" ones won't be what you're looking for.
1
First, the obvious: there's a blur filter already available in Processing. But it blurs the whole image. You could still use it successfully by drawing the "blurred circles" first, blurring the image then drawing the sharp circles.
But There's two problems here: first I'm pretty sure that it won't be the result you're looking for. Second, that method is awfully costly. Unless you have a monster machine, it'll slow down.
2
You can draw an already blurred circle to a PImage and use it instead of the sharp circle when the blur conditions applies. While this approach would work, I still doubt that you're looking for this. I'm giving you some code in case you want to try it yourself (but only the Ball class, as the rest doesn't have to change):
class Ball {
//1.Attributes
PGraphics blurredCircle;
boolean blur;
float xPos, yPos, xSpeed, ySpeed, blurSize;
float size;
color colour;
//2.Constructor
Ball() {
blur = false;
blurSize = 200;
xPos = width / 2;
yPos = height / 2;
xSpeed = random(-4, 4);
ySpeed = random(-4, 4);
size = random(700, 1000);
colour = color(random(0, 255), random(0, 255), random(0, 255));
// drawing a blurred circle to memory
blurredCircle = createGraphics((int)(size+2*blurSize), (int)(size+2*blurSize), P2D);
blurredCircle.beginDraw();
blurredCircle.background(0, 0, 0, 0); // using transparency to avoid drawing a white rectangle around the circle
blurredCircle.stroke(colour, 100);
blurredCircle.fill(colour, 100);
blurredCircle.ellipseMode(CENTER);
blurredCircle.ellipse(blurredCircle.width/2, blurredCircle.height/2, size, size);
blurredCircle.filter(BLUR, blurSize);
blurredCircle.endDraw();
}
//3.Actions
void render() {
if (blur) {
imageMode(CENTER);
image(blurredCircle, xPos, yPos);
} else {
stroke(colour, 100);
fill(colour, 100);
ellipse(xPos, yPos, size, size);
}
UpdateSpeed();
UpdateBlur();
}
void UpdateSpeed() {
xPos += xSpeed;
yPos += ySpeed;
// direction
if (xPos < 0 || xPos > width) {
xSpeed *= -1;
}
if (yPos < 0 || yPos > height) {
ySpeed *= -1;
}
}
void UpdateBlur() {
int blurDistance = 50;
blur = xPos < 0 + blurDistance || xPos > width - blurDistance || yPos < 0 + blurDistance || yPos > height - blurDistance;
}
}
3
This one is kind of just me trying to get some interesting result. I drew a blurred circle to a PImage then adjusted the algorithm so there's a "core" circle which size never change with a "blurred" circle getting bigger as it gets near the border:
ArrayList < Ball > list = new ArrayList();
void setup() {
//fullScreen(P2D);
size(500, 500, P2D);
for (int iter = 0; iter < 5; iter++) //qty of balls on the screen
list.add(new Ball());
}
void draw() {
background(0);
// way better!
for (Ball thisBall : list)
thisBall.render();
}
class Ball {
//1.Attributes
PGraphics blurredCircle;
float xPos, yPos, xSpeed, ySpeed, blurSize, blur, blurDistance, maxBlurPercentIncrease;
float size;
color colour;
//2.Constructor
Ball() {
blur = 1;
blurSize = 200;
blurDistance = 200;
maxBlurPercentIncrease = 75;
xPos = width / 2;
yPos = height / 2;
xSpeed = random(-2, 2);
ySpeed = random(-2, 2);
size = random(200, 400);
colour = color(random(0, 255), random(0, 255), random(0, 255));
// drawing a blurred circle to memory
blurredCircle = createGraphics((int)(size+2*blurSize), (int)(size+2*blurSize), P2D);
blurredCircle.beginDraw();
blurredCircle.background(0, 0, 0, 0); // using transparency to avoid drawing a white rectangle around the circle
blurredCircle.noStroke();
blurredCircle.fill(colour, 100);
blurredCircle.ellipseMode(CENTER);
blurredCircle.ellipse(blurredCircle.width/2, blurredCircle.height/2, size, size);
blurredCircle.filter(BLUR, blurSize);
blurredCircle.endDraw();
}
//3.Actions
void render() {
UpdateBlur();
float currentSize = size * blur;
imageMode(CENTER);
image(blurredCircle, xPos, yPos, currentSize, currentSize);
noStroke();
fill(colour, 100);
ellipse(xPos, yPos, size/2, size/2);
fill(255);
UpdateSpeed();
}
void UpdateSpeed() {
xPos += xSpeed;
yPos += ySpeed;
// direction
if (xPos < 0 || xPos > width) {
xSpeed *= -1;
}
if (yPos < 0 || yPos > height) {
ySpeed *= -1;
}
}
void UpdateBlur() {
float[] values = { xPos, yPos, abs(xPos-width), abs(yPos-height) };
float min = min(values);
if (min == 0) {
min = 1;
}
blur = 1;
if (min < blurDistance) {
float adjustment = ((blurDistance-min)/blurDistance)*maxBlurPercentIncrease;
if (adjustment > 5) {
blur += adjustment/100;
}
}
}
}
I'm encouraging you to experiment along these lines as I imagine you have something precise in mind. Good luck!

How to zoom into Mandelbrot set by clicking

I managed to create the Mandelbrot set in processing but am struggling to implement a zoom. Here is my code:
float minvalX = -1.5;
float minvalY = -1.5;
float maxvalX = 1.5;
float maxvalY = 1.5;
float angle = 0;
float di,dj;
int xPixel,yPixel;
void setup(){
size(500,500);
pixelDensity(1);
colorMode(HSB, 360);
}
void draw() {
scale(zoom);
float maxLoops = 100;
loadPixels();
float equationOneOriginal;
float equationTwoOriginal;
for (xPixel = 0; xPixel < width ; xPixel++) {
for (yPixel = 0; yPixel < height ; yPixel++) {
float a = map(xPixel+di, 0,width, minvalX, maxvalX);
float b = map(yPixel+dj, 0,height, minvalY, maxvalY);
equationOneOriginal = a;
equationTwoOriginal = b;
float n = 1;
while (n < maxLoops) {
float equationOne = a*a - b*b; //First part of the equation
float equationTwo = 2 * a * b; //Second part of the equation
a = equationOne + equationOneOriginal;
b = equationTwo + equationTwoOriginal;
if (abs(a+b) > 16) {
break;
}
n++;
}
if (n == maxLoops) {
pixels[xPixel+yPixel*width] = color(0);
}
else {
pixels[xPixel+yPixel*width] = color(n-(int)(n/360)*n, 360, (int)map(n*6, 1, maxLoops, 0, 360));
}
}
}
updatePixels();
}
void mousePressed()
{
if (mouseButton == LEFT) {
di = di + mouseX - int(width/2);
dj = dj + mouseY - int(height/2);
minvalX += 0.1;
maxvalX -= 0.1;
minvalY += 0.1;
maxvalY -= 0.1;
}
}
It zooms into where my mouse is but eventually it goes towards the middle and gets stuck there. I know it is to do with minvalX, maxvalX, minvalY and maxvalY but I don't know what to do to these values to get it to always zoom towards my mouse.

Processing: How can I make multiple elements in a for() loop move to one location then return?

I have a grid of ellipses generated by two for() loops. What I'd like to do is have all of these ellipses ease into mouseX and mouseY when mousePressed == true, otherwise return to their position in the grid. How can I go about this? I've started with this template, which doesn't work as I can't figure out how affect the position of the ellipses, but the easing is set up.
float x;
float y;
float easeIn = 0.01;
float easeOut = 0.08;
float targetX;
float targetY;
void setup() {
size(700, 700);
pixelDensity(2);
background(255);
noStroke();
}
void draw() {
fill(255, 255, 255, 80);
rect(0, 0, width, height);
for (int i = 50; i < width-50; i += 30) {
for (int j = 50; j < height-50; j += 30) {
fill(0, 0, 0);
ellipse(i, j, 5, 5);
if (mousePressed == true) {
// go to mouseX
targetX = mouseX;
// ease in
float dx = targetX - x;
if (abs(dx) > 1) {
x += dx * easeIn;
}
//go to mouseY
targetY = mouseY;
// ease in
float dy = targetY - y;
if (abs(dy) > 1) {
y += dy * easeIn;
}
} else {
// return to grid
targetX = i;
// ease out
float dx = targetX - x;
if (abs(dx) > 1) {
x += dx * easeOut;
}
// return to grid
targetY = j;
// ease out
float dy = targetY - y;
if (abs(dy) > 1) {
y += dy * easeOut;
}
}
}
}
}
Any help would be greatly appreciated. I'm not sure in which order to do things/which elements should be contained in the loop.
Thanks!
You're going to have to keep track of a few things for each dot: its "home" position, its current position,its speed, etc.
The easiest way to do this would be to create a class that encapsulates all of that information for a single dot. Then you'd just need an ArrayList of instances of the class, and iterate over them to update or draw them.
Here's an example:
ArrayList<Dot> dots = new ArrayList<Dot>();
void setup() {
size(700, 700);
background(255);
noStroke();
//create your Dots
for (int i = 50; i < width-50; i += 30) {
for (int j = 50; j < height-50; j += 30) {
dots.add(new Dot(i, j));
}
}
}
void draw() {
background(255);
//iterate over your Dots and move and draw each
for (Dot dot : dots) {
dot.stepAndRender();
}
}
class Dot {
//the point to return to when the mouse is not pressed
float homeX;
float homeY;
//current position
float currentX;
float currentY;
public Dot(float homeX, float homeY) {
this.homeX = homeX;
this.homeY = homeY;
currentX = homeX;
currentY = homeY;
}
void stepAndRender() {
if (mousePressed) {
//use a weighted average to chase the mouse
//you could use whatever logic you want here
currentX = (mouseX+currentX*99)/100;
currentY = (mouseY+currentY*99)/100;
} else {
//use a weighted average to return home
//you could use whatever logic you want here
currentX = (homeX+currentX*99)/100;
currentY = (homeY+currentY*99)/100;
}
//draw the ellipse
fill(0, 0, 0);
ellipse(currentX, currentY, 5, 5);
}
}
Note that I'm just using a weighted average to determine the position of each ellipse, but you could change that to whatever you want. You could give each ellipse a different speed, or use your easing logic, whatever. But the idea is the same: encapsulate everything you need into a class, and then put the logic for one dot into that class.
I'd recommend getting this working for a single dot first, and then moving up to getting it working with multiple dots. Then if you have another question you can post the code for just a single dot instead of a bunch. Good luck.

Moving Paddle with mouse (Arkanoid)

I am having a slight problem. I'm creating a basic Arkanoid using processing but I can't figure out how to make the paddle move with my mouse. I have it currently set up to move on a click for this example.
void setup() {
size(400, 400);
rectMode(CENTER);
ellipseMode(CENTER);
}
void draw() {
background(#EFF8FB);
batMain();
ballMain();
}
float ballX = 200, ballY = 200;
float direction = PI * .3f;
byte speed = 4;
final static byte ballSize = 20;
final static color ballColor = #2EFE2E;
void ballMain() {
// Draw the ball
fill(ballColor);
ellipse(ballX, ballY, ballSize, ballSize);
ballX += speed * cos(direction);
ballY += speed * sin(direction);
walls();
if (direction > TWO_PI) direction -= TWO_PI;
else if (direction < -TWO_PI) direction += TWO_PI;
}
short a = 200;
final static color batColor = #5858FA;
void batMain() {
// Draw the bat
fill(batColor);
rect(a, 380, 60, 10);
noStroke();
if (mousePressed) {
// Right side of the screen
if (mouseX > width>>1) a += 4;
// Other side of the screen
else a -= 4;
}
if (ballY + 10 > 375 && ballY + 10 < 385 && ballX + 10 > a - 30 && ballX - 10 < a + 30) {
if (ballX + 10 > a - 30 && ballX < a - 15) { // Left part
direction = TWO_PI - direction;
++speed;
}
else if (ballX - 10 < a + 30 && ballX < a + 15) {
direction = TWO_PI - direction;
++speed;
}
else {
direction = TWO_PI - direction;
speed = 4;
}
}
}
void walls() {
if (ballX < 10) {
ballX = 11;
direction = PI - direction;
}
if (ballX > 390) {
ballX = 389;
direction = PI - direction;
}
if (ballY < 10) {
ballY = 11;
direction = TWO_PI - direction;
}
if (ballY > 390) {
ballY = 389;
direction = TWO_PI - direction;
}
}
You already have the logic here:
if (mousePressed) {
// Right side of the screen
if (mouseX > width>>1) a += 4;
// Other side of the screen
else a -= 4;
}
If you want the paddle to follow the mouse even when you aren't pressing it, just get rid of that outer if statement:
// Right side of the screen
if (mouseX > width>>1){
a += 4;
}
// Other side of the screen
else{
a -= 4;
}
Or if you want the paddle to be at the mouse's position, just use that directly:
a = mouseX;

Animation using multiple ellipses and controlled using keyPressed

The code I have here is an animation that shows one circle that moves the way I'd like it to. I'd like to have 10 circles and I assume I use a loop or possibly an array but I'm not quite sure how to do that. At the same time, I want to make it so that at first the animation doesn't move but starts moving when I press a specific key and stops when I press the same key.
color a = color(random(255), random(255), random(255), random(125, 250));
float dia = random(60, 80);
float x;
float y;
float speedX = random(-3, 3);
float speedY = random(-3, 3);
void setup() {
background(255);
size(400, 200);
x = random(dia/2, width-dia/2);
y = random(dia/2, height-dia/2);
}
void draw() {
background(255);
noStroke();
fill(a);
ellipse(x, y, dia, dia);
x = x + speedX;
y = y + speedY;
if(speedX > 0 && x >= width - dia/2) {
speedX = speedX * -1;
}
if(speedX < 0 && x <= dia/2) {
speedX = speedX * -1;
}
if(speedY > 0 && y >= height - dia/2) {
speedY = speedY * -1;
}
if(speedY < 0 && y <= dia/2) {
speedY = speedY * -1;
}
}
You can get multiple circles by encapsulating the data you need to draw a circle into a class. It might look something like this:
Circle c;
void setup() {
size(400, 200);
c = new Circle();
}
void draw() {
background(255);
c.draw();
}
class Circle {
color a = color(random(255), random(255), random(255), random(125, 250));
float dia = random(60, 80);
float x = random(dia/2, width-dia/2);
float y = random(dia/2, height-dia/2);
float speedX = random(-3, 3);
float speedY = random(-3, 3);
void draw() {
noStroke();
fill(a);
ellipse(x, y, dia, dia);
x = x + speedX;
y = y + speedY;
if (speedX > 0 && x >= width - dia/2) {
speedX = speedX * -1;
}
if (speedX < 0 && x <= dia/2) {
speedX = speedX * -1;
}
if (speedY > 0 && y >= height - dia/2) {
speedY = speedY * -1;
}
if (speedY < 0 && y <= dia/2) {
speedY = speedY * -1;
}
}
}
Then to get multiple circles, you'd just create multiple instances of your Circle class and add them to an ArrayList:
ArrayList<Circle> circles = new ArrayList<Circle>();
void setup() {
size(400, 200);
for (int i = 0; i < 5; i++) {
circles.add(new Circle());
}
}
void draw() {
background(255);
for (Circle c : circles) {
c.draw();
}
}
For the user interaction, have a look at the event methods like mousePressed() or keyPressed(). The Processing reference should be your first stop. Good luck.

Resources