How can I change the movement of the ball on pressing any keys from the keyboard in processing? - processing

Below is the code I am working with in processing. I want the code to be edited to change the movement of the ellipse on the canvas on pressing any key from the keyboard.
float circleX = 0;
float circleY = 0;
float xSpeed = 2.5;
float ySpeed = 2;
void setup() {
size(500, 500);
}
void draw() {
background(0,200,0);
circleX += xSpeed;
if (circleX < 0 || circleX > width) {
xSpeed *= -1;
}
circleY += ySpeed;
if (circleY < 0 || circleY > height) {
ySpeed *= -1;
}
ellipse(circleX, circleY, 100, 100);
}

You can use the in-built keyPressed function to handle user input, so after your original code, you could add this:
void keyPressed() {
switch (keyCode) { // the keyCode variable is used to identify which non-ASCII key was pressed
case LEFT:
xSpeed -= 0.1;
break;
case RIGHT:
xSpeed += 0.1;
break;
case UP:
ySpeed -= 0.1;
break;
case DOWN:
ySpeed += 0.1;
break;
default: // default is used when none of these are pressed, so in this case it is when any key is pressed
// this depends on what you want to do, but in this case I am just inverting the speed, so replace as you see fit
xSpeed *= -1;
ySpeed *= -1;
}
}
Hope this helps!

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!

Processing 3.0: Accelerating pong ball not correctly bouncing

I'm learning Processing and am making modified version of pong game in processing 3. I have 2 balls simultaneously instead of just 1.
Also, one ball accelerates while the other ball slows down as the program runs.
My accelerating ball is working fine, it bounces around and increases speed. But, my slowing down ball is not working correct. The slowing ball moves in a very small area and does not even go close to the borders to bounce off. Help would be appreciated. Thanks.`
float ballXPosition;
float ballYPosition;
float ballTwoXPos;
float ballTwoYPos;
float xDirection;
float ballTwoXDir;
float yDirection;
float ballTwoYDir;
float radius = 12;
float xSpeed;
float ySpeed;
float ballTwoXSpeed;
float ballTwoYSpeed;
float MAX_SPEED = 15;
float MIN_SPEED = 0.2;
void setup()
{
size(600,600);
stroke(3);
background(255,255,255);
ballXPosition = width/2 + random(60);
ballTwoXPos= width/2 + random(60);
ballYPosition = height/2 + random(60);
ballTwoYPos = height/2 + random(60);
xDirection = random(1,3);
ballTwoXDir = random(1,3);
yDirection = random(1,3);
ballTwoYDir = random(1,3);
xSpeed = MIN_SPEED;
ySpeed = MIN_SPEED;
ballTwoXSpeed = MAX_SPEED;
ballTwoYSpeed = MAX_SPEED;
}
void createAcceleratingBall(float xpos, float ypos, float xstretch, float ystretch)
{
fill(255,0,0);
ellipse(xpos, ypos, xstretch, ystretch);
}
void createSlowingBall(float xpos, float ypos, float xstretch, float ystretch)
{
fill(0,0,255);
ellipse(xpos, ypos, xstretch, ystretch);
}
boolean isSpeedMax(float speed)
{
return speed > MAX_SPEED;
}
boolean isSpeedMin(float speed)
{
return speed < MIN_SPEED;
}
boolean isBallAtXBorder(float xpos)
{
if(xpos < radius || xpos > width - radius)
return true;
else
return false;
}
boolean isBallAtYBorder(float ypos)
{
if(ypos < radius || ypos > height - radius)
return true;
else
return false;
}
void draw()
{
background(255);
ballXPosition = ballXPosition + (xDirection * xSpeed);
ballTwoXPos = ballTwoXPos + (ballTwoXDir * ballTwoXSpeed);
ballYPosition = ballYPosition + (yDirection * ySpeed);
ballTwoYPos = ballTwoYPos + (ballTwoYDir * ballTwoYSpeed);
if(!isSpeedMax(xSpeed))
xSpeed *= 1.005;
if(!isSpeedMax(ySpeed))
ySpeed *= 1.003;
if(!isSpeedMin(ballTwoXSpeed))
ballTwoXSpeed = ballTwoXSpeed / 1.005;
if(!isSpeedMin(ballTwoYSpeed))
ballTwoYSpeed = ballTwoYSpeed / 1.003;
if(isBallAtXBorder(ballXPosition))
xDirection *= -1;
if(isBallAtYBorder(ballYPosition))
yDirection *= -1;
if(isBallAtXBorder(ballTwoXDir))
ballTwoXDir *= -1;
if(isBallAtYBorder(ballTwoYDir))
ballTwoYDir *= -1;
createAcceleratingBall(ballXPosition, ballYPosition, 2*radius, 2*radius);
createSlowingBall(ballTwoXPos, ballTwoYPos, 2.5*radius, 2.5*radius);
}
I think you have the wrong variables being tested for the slowing ball in the isBallAtXBorder and isBallAtYBorder functions. You're testing ballTwoXDir and ballTwoYDir - should you not be testing ballTwoXPos and ballTwoYPos?

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