Processing 3.0: Accelerating pong ball not correctly bouncing - processing

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?

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!

Trying to make a ball bounce on the screen in processing using classes

I am working on making a single ball bounce all over the screen but I have an issue with making the ball bounce the bounce() function is responsible for making the ball bounce but I run into an array out of bounds exception despite only going through 1 element in the array. I have provided the code below. This code utilizes 2 classes (Ball_Usage and Ball).
Ball_Usage code:
Ball ball1;
void setup(){
size(500,500);
ball1 = new Ball();
}
void draw(){
background(255);
ball1.bounce();
}
Ball:
class Ball{
float [] xPos = {};
float [] yPos = {};
float [] dia = {};
float [] xSpeed = {};
float [] ySpeed = {};
Ball(){
}
Ball(float x, float y, float argDia){
xPos = append(xPos, x);
yPos = append(yPos, y);
dia = append(dia, argDia);
}
void bounce(){
for(int i=0; i<1; i++){
ellipse(xPos[i], yPos[i], 50, 50);
xPos[i] += xSpeed[i];
yPos[i] += ySpeed[i];
if(xPos[i]<0 || xPos[i]>=width){
xSpeed[i] = -xSpeed[i];
}
if(yPos[i]<0 || yPos[i]>=height){
ySpeed[i] = -ySpeed[i];
}
}
}
}
I believe the confusion comes from the fact that your class has two constructors:
an empty constructor (that takes no arguments): Ball()
a constructor with position and argDia (guessing diameter ?) arguments: Ball(float x, float y, float argDia)
In setup() you call the empty constructor:
ball1 = new Ball();
This means the five float arrays still have a length of 0, hence the out of bounds exception.
Even if you call the position + diameter version of the constructor, the xSpeed, ySpeed arrays will still have length 0.
You could fix this by initialising the two two arrays as well as using this version of the constructor:
Ball ball1;
void setup() {
size(500, 500);
//ball1 = new Ball();
ball1 = new Ball(250, 250, 50);
}
void draw() {
background(255);
ball1.bounce();
}
class Ball {
float [] xPos = {};
float [] yPos = {};
float [] dia = {};
float [] xSpeed = {};
float [] ySpeed = {};
Ball() {
}
Ball(float x, float y, float argDia) {
xPos = append(xPos, x);
yPos = append(yPos, y);
dia = append(dia, argDia);
xSpeed = append(xSpeed, random(-1, 1));
ySpeed = append(ySpeed, random(-1, 1));
}
void bounce() {
for (int i=0; i<1; i++) {
ellipse(xPos[i], yPos[i], 50, 50);
xPos[i] += xSpeed[i];
yPos[i] += ySpeed[i];
if (xPos[i]<0 || xPos[i]>=width) {
xSpeed[i] = -xSpeed[i];
}
if (yPos[i]<0 || yPos[i]>=height) {
ySpeed[i] = -ySpeed[i];
}
}
}
}
This will work, however there is still a bit of confusion: why use the arrays at all if you're only looping once for the first element ? It makes the arrays and for loop mostly redundant.
You might choose to keep if you plan to change the diameter over time (which in your code is hardcoded to 50), maybe positions and velocities and render a changing history of a ball.
If you don't, you could simply use float properties instead of arrays:
Ball ball1;
void setup() {
size(500, 500);
ball1 = new Ball();
}
void draw() {
background(255);
ball1.bounce();
}
class Ball {
float xPos;
float yPos;
float diameter = 50;
float xSpeed;
float ySpeed;
Ball() {
xPos = width / 2;
yPos = height / 2;
xSpeed = random(-1, 1);
ySpeed = random(-1, 1);
}
void bounce() {
ellipse(xPos, yPos, diameter, diameter);
xPos += xSpeed;
yPos += ySpeed;
if (xPos < 0 || xPos >= width) {
xSpeed = -xSpeed;
}
if (yPos < 0 || yPos >= height) {
ySpeed = -ySpeed;
}
}
}
This looks more similar to the Bounce Processing Example.
You can at a later stage make an array of Ball objects.
Additionally it's worth formatting code as it saves you time reading/scrolling through it and visually it's easier to scan the structure of the program (how each part fits in) and therefore makes it easier to debug/run mentally. It takes no effort as you can simply press Ctrl+T on Windows/Linux or CMD+T on OSX. On the long run this will pay off, especially as programs get longer and more complex as you spend more time reading code than writing code. It's a good habit to pickup early while learning to code. Have fun!

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.

How to make this ball spawn in the middle instead at the side? MonoGame in VisualStudio

Trying to create a simple breakout game, I've written all the code, except i dont understand why the ball is on the side of the screen boundaries instead of on top the paddle(player).
Breakout game, ball on side
class Ball
{
int Width => texture.Width;
int Height => texture.Height;
public Rectangle BoundingBox =>
new Rectangle((int)position.X, (int)position.Y, Width, Height);
Texture2D texture;
Vector2 position;
Vector2 speed;
public void SetStartBallPosition(Rectangle rec)
{
position.X = rec.X + (rec.Width - Width);
position.Y = rec.Y - Height;
if (Game1.RandomNumber.Next(0, 2) < 1)
{
speed = new Vector2(-200.0f, -200.0f);
}
else
{
speed = new Vector2(200.0f, -200.0f);
}
}
public void Draw(SpriteBatch sb)
{
sb.Draw(texture, position, Color.White);
}
public void Update(GameTime gt)
{
position += speed * (float)gt.ElapsedGameTime.TotalSeconds;
if (position.X + Width > Game1.ScreenBounds.Width)
speed.X *= -1;
position.X = Game1.ScreenBounds.Width - Width;
if (position.X < 0)
{
speed.X *= -1;
position.Y = 0;
}
if (position.Y < 0)
{
speed.Y *= -1;
position.Y = 0;
}
}
TL;DR.
My ball spawns at the side instead of middle.
Thanks for Help!
In the SetStartBallPosition(Rectangle rec), You've set the ball position at the full width of the boundary box, minus the full width of the ball:
position.X = rec.X + (rec.Width - Width);
Assuming that rec is empty, then in order to get the center, you need to divide both width's there in half. Like this:
position.X = rec.X + (rec.Width/2 - Width/2);
Be aware that when dividing, that they shouldn't have decimals.
Let me know if it works.

Can't figure out how to make circle in Processing

I am trying to make a circle with the following code. I just cant figure out what values I need to change in order to create it. Appreciate any help.
void setup() {
size(400, 400);
background(255,255,255);
}
void draw() {
float step=(2*PI)/120;
float theta_start=0;
float old_sx=map(theta_start,0,2*PI,4,width-4);
float old_sy1=map(sin(theta_start),-1,1,height-4,4);
float old_sy2=map(cos(theta_start),0,1*PI,1,width-2);
for(float theta=step;theta<=(2*PI)+step;theta+=step)
{
float screen_x=map(theta,0,2*PI,4,width-4);
float screen_y1=map(sin(theta),-1,1,height-4,4);
float screen_y2=map(cos(theta),0,1*PI,1,width-2);
//stroke(255,0,0);
//line(old_sx,old_sy1,screen_x,screen_y1);
//stroke(0,255,0);
// line(old_sx,old_sy2,screen_x,screen_y2);
stroke(0,0,255);
line(old_sy1,old_sy2,screen_y1,screen_y2);
old_sx=screen_x;
old_sy1=screen_y1;
old_sy2=screen_y2;
}
}
A circle with radius 1 can be defined as all points (x,y), that are located at
(sin(theta), cos(theta))
for all 0<=theta<2*PI.
In order to change the radius, simply alter it to
(radius * sin(theta), radius * cos(theta)).
Finally, if you want to change the center of the radius to a position (posX, posY), just add these:
(radius * sin(theta) + posX, radius * cos(theta) + posY)
void setup()
{
size(400, 400);
background(255,255,255);
}
void draw()
{
float step=(2*PI)/120;
int posX = width/2;
int posY = height/2;
float radius = 100;
int xOld=0, yOld=0;
for(float theta=0;theta<=(2*PI)+step;theta+=step)
{
stroke(0,0,255);
int x = int(radius*sin(theta) + posX);
int y = int(radius*cos(theta) + posY);
if(theta>0)
{
line(x,y,xOld,yOld);
}
xOld = x;
yOld = y;
}
}

Resources