How to put damping and friction to a bouncing ball? - java

I just made a code with a bouncing ball. It works fine but, it doesn't slow down. What I want is to put a fricition (20%) and every time when the ball bounces on the edge, it should slow down (0.2%) till it stops and turn black.
My Code:
float posX = 300;
float posY = 200;
float speedY= 2;
float speedX = 5;
float ballsize = 25;
float damping = 0.2;
color red = color(255,0,0);
color green = color(0,255,0);
color black = color(0);
color ballcolor;
void setup() {
size(600, 400);
background(191);
surface.setTitle("ball");
surface.setLocation((displayWidth-width)>>1, (displayHeight-height)>>1);
}
void draw() {
background(191);
posX = posX + speedX;
posY = posY + speedY;
if (posX > width) {
speedX = speedX* -1;
ballcolor = (ballcolor == red ? green : red);
}
if (posX < 0) {
speedX = speedX* -1;
ballcolor = (ballcolor == red ? green : red);
}
if (posY > height) {
speedY= speedY* -1;
ballcolor = (ballcolor == red ? green : red);
}
if (posY < 0) {
speedY= speedY* -1;
ballcolor = (ballcolor == red ? green : red);
}
if (abs(speedY) < 0.1 && abs(speedX) < 0.1) {
speedX = 0;
speedY = 0;
}
fill(ballcolor);
ellipse(posX, posY, ballsize, ballsize);
}

Related

Ball Collision - Collide with paddle

I'm trying to make a ball switch it's Y-Direction when it collides with the restrictions of the paddle. It is most likely a simple answer. Help would be appreciated. Thank you.
I labeled a couple of things to help.
public class GamePanel extends JPanel implements MouseMotionListener {
int Playerx;
int width;
int height;
// Ball Size
float radius = 20;
float diameter = radius * 2;
// Center of Call
float X = radius + 25;
float Y = radius + 10;
// Direction
float dx = 12;
float dy = 12;
GamePanel(){
setPreferredSize(new Dimension(1440, 900));
setFocusable(true);
setBackground(Color.BLACK);
addMouseMotionListener(this);
Thread thread = new Thread() {
public void run() {
while (true) {
width = getWidth();
height = getHeight();
X = X + dx ;
Y = Y + dy;
if (X - radius < 0) {
dx = -dx;
X = radius;
} else if (X + radius > width) {
dx = -dx;
X = width - radius;
}
if (Y - radius < 0) {
dy = -dy;
Y = radius;
}else if (Y + radius > height) {
dy = -dy;
Y = height - radius;
}
if(X-radius>=Playerx && X-radius <- Playerx + 100 && Y+radius>=800 && Y+radius<=810){
dy = -dy;
Y = height - radius;
}//Statement Above is the issue area
repaint();
try {
Thread.sleep(25);
} catch (InterruptedException ex) {
}
}
}
};
thread.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
if(Playerx<=50 && Playerx>= 0){g.fillOval(10,800,100,10);}
if(Playerx>50 && Playerx<1390){g.fillOval(Playerx-50,800,100,10);}
if(Playerx>=1390 && Playerx<1440){g.fillOval(1340,800,100,10);}
g.setColor(Color.BLUE);
g.fillOval((int)(X-radius), (int)(Y-radius), (int)diameter, (int)diameter);
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
Playerx = e.getX();
repaint();
}
}
I've tried setting different restrictions and different Y-Directions but it doesn't seem to work. The Ball goes straight through the paddle as if it's not there.
I managed to fix it.
I realized that my Playerx was in the middle of the paddle making everything offset 50.
float X = radius;
float Y = radius;
and
public void run() {
while (true) {
counter++;
width = getWidth();
height = getHeight();
X = X + dx ;
Y = Y + dy;
if (X - radius < 0) {
dx = -dx;
X = radius;
} else if (X + radius > width) {
dx = -dx;
X = width - radius;
}
if (Y - radius < 0) {
dy = -dy;
Y = radius;
}else if (Y + radius > height) {
dy = -dy;
Y = height - radius;
}if(X > Playerx-50 && X < Playerx+50 && Y+radius > paddleHeight && Y < 715){
dy = -dy;
Y = paddleHeight - radius;
}

How can I make two objects of the same class bounce when colliding?

I made a bouncing ball code, and so far as the bouncing itself the code works perfectly. I then created a second ball, and it also does what it's supposed to do. However, when I try to use an if condition to make the two balls bounce off one another as well as the edges, it doesn't work. Either they don't move or they just don't collide, and go through each other. This code was made in processing. Can anyone help me make ball1 and ball2 collide?
Moving ball1;
Moving ball2;
void setup(){
size(600,600);
ball1 = new Moving();
ball2 = new Moving();
}
void draw(){
background(255);
ball1.move();
ball1.display();
ball1.bounce();
ball2.move();
ball2.display();
ball2.bounce();
ball1.clash();
ball2.clash();
}
class Moving {
float speed = 7;
float x = random(0, width);
float y= random(0, height);
float xdirection = 1;
float ydirection = 1;
float ball_size = 50;
float radius = ball_size/2;
Moving() {
}
void move() {
x = x + (xdirection * speed);
y = y + (ydirection* speed);
}
void display() {
noStroke();
fill(50, 0, 50);
circle(x, y, ball_size);
}
void bounce() {
if ((x >= width - radius) || (x <= radius)) {
xdirection = xdirection * -1;
}
if ((y >= height - radius)|| (y<=radius)) {
ydirection = ydirection * -1;
}
}
void clash() {
if ((ball1.y+radius == ball2.y+radius) && (ball1.x+radius == ball2.x+radius)) {
ball1.ydirection = ball1.ydirection * -1;
ball2.ydirection = ball2.ydirection * -1;
ball1.xdirection = ball1.xdirection * -1;
ball2.xdirection = ball2.xdirection * -1;
x = x + (xdirection * speed);
y = y + (ydirection* speed);
if (ball1.x+radius == ball2.x+radius) {
xdirection = xdirection * -1;
}
}
}
}

Collision Problems in Processing

So I'm trying to make a platformer game and I'm just starting to work on collision. Right now the collisions very glitchy and only works if its on the side of a rectangle and not the top (this makes more sense if you run the code). I'm wondering how I can get the collision to be cleaner and overall less glitchy.
float x = 100;
float y = 100;
float vy = 0;
float vx = 0;
boolean rightCollision = false;
boolean leftCollision = false;
void setup(){
size(700, 500);
}
void draw(){
background(0);
fill(255);
rect(x, y, 50, 50);
y += vy;
vy += .3;
x += vx;
vx -= vx * 0.07;
if(y > 400){
vy = 0;
y = 400;
}
if(left){
x -= 1;
vx -= .5;
}
if(right){
x += 1;
vx += .5;
}
if(touching(x, y, 50, 50, 400, 325, 100, 500) && keyCode == RIGHT){
rightCollision = true;
}
else{
rightCollision = false;
}
if(rightCollision){
vx -= 2;
}
if(touching(x, y, 50, 50, 400, 325, 100, 500) && keyCode == LEFT){
leftCollision = true;
}
else{
leftCollision = false;
}
if(leftCollision){
vx += 2;
}
fill(167);
noStroke();
rect(0, 450, 1000, 50);
rect(400, 325, 100, 500);
}
boolean left = false;
boolean right = false;
void keyPressed(){
if(keyCode == RIGHT || key == 'd'){
right = true;
}
if(keyCode == LEFT || key == 'a'){
left = true;
}
if(keyCode == UP || key == 'w'){
if(y == 400){
vy -= 10;
}
}
}
void keyReleased(){
if(keyCode == RIGHT || key == 'd'){
right = false;
}
if(keyCode == LEFT || key == 'a'){
left = false;
}
}
boolean touching(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2){
return x1 + w1 >= x2 && x2 + w2 >= x1 && y1 + h1 >= y2 && y2 + h2 >= y1;
}
You need to detect the collision when the player is moving (vx != 0, vy != 0), not just when the key is pressed.
Set the movement to 0 and limit the player's position when a collision is detected:
int pw = 50, ph = 50;
int ox = 400, oy = 325, ow = 100, oh = 400;
topCollision = touching(x, y, pw, ph, ox, oy, ow, oh) && vy > 0.0 && y < oy;
if (topCollision){
vy = 0;
y = oy-ph;
}
rightCollision = touching(x, y, pw, ph, ox, oy, ow, oh) && vx < 0.0;
if (rightCollision){
vx = 0;
x = ox+ow;
}
leftCollision = touching(x, y, pw, ph, ox, oy, ow, oh) && vx > 0.0;
if (leftCollision) {
vx = 0;
x = ox-pw;
}
Use > instread of >= for the collision detection:
boolean touching(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2){
return x1 + w1 > x2 && x2 + w2 > x1 && y1 + h1 > y2 && y2 + h2 > y1;
}

Why do these rectangles sometimes show that they are colliding even though they are not?

When I run the code it generates 16 rectangles with a random size, random position, and a random color. It is then supposed to turn white if it is colliding with another rectangle. Most of the time it works fine but every so often rectangles turn white when they are not colliding with anything.
Main
int boxCount = 16;
Box[] boxes = new Box[boxCount];
void setup(){
size(500, 500);
for(int i = 0; i < boxCount; i++){
boxes[i] = new Box(random(50, width - 50), random(50, height - 50), random(20, 50), random(20, 50), color(random(0, 255), random(0, 255), random(0, 255)));
}
}
void draw(){
for(int i = 0; i < boxCount; i++){
boxes[i].create();
for(int x = 0; x < boxCount; x++){
if(boxes[i] != boxes[x]){
boxes[i].collide(boxes[x]);
}
}
}
}
Class
class Box{
float x;
float y;
float w;
float h;
color c;
Box(float _x, float _y, float _w, float _h, color _c){
x = _x;
y = _y;
w = _w;
h = _h;
c = _c;
}
void create(){
fill(c);
rect(x, y, w, h);
}
void collide(Box o){
float right = x + (w / 2);
float left = x - (w / 2);
float top = y - (h / 2);
float bottom = y + (h / 2);
float oRight = o.x + (o.w / 2);
float oLeft = o.x - (o.w / 2);
float oTop = o.y - (o.h / 2);
float oBottom = o.y + (o.h / 2);
if(right > oLeft && left < oRight && bottom > oTop && top < oBottom){
c = color(255, 255, 255);
}
}
}
rect doesn't draw a rectangle around center point, by default the rectangle is drawn at a top left position (x, y) with a size (with, height).
You've 2 possibilities to solve the issue:
Either change the collision detection method:
class Box{
// [...]
void collide(Box o){
if(x < o.x+o.w && o.x < x+w && y < o.y+o.h && o.y < y+h){
c = color(255, 255, 255);
}
}
}
Or set the CENTER rectMode(), which will cause the rectangle to be drawn as you expect it:
class Box{
// [...]
void create(){
fill(c);
rectMode(CENTER);
rect(x, y, w, h);
}
// [...]
}

Change color on every 3rd bounce

I'm using Processing;
I have a ball that bounces when it hits the border and changes its color to random. Now I need this ball to change its color on every third bounce. Can't figure out how to do it.
Here is my current code:
float xPos;// x-position
float vx;// speed in x-direction
float yPos;// y-position
float vy;// speed in y-direction
float r;
float g;
float b;
void setup()
{
size(400, 300);
fill(255, 177, 8);
textSize(48);
// Initialise xPos to center of sketch
xPos = width / 2;
// Set speed in x-direction to -2 (moving left)
vx = -2;
yPos = height / 2;
vy = -1;
}
void draw()
{
r = random(255);
b = random(255);
g = random(255);
background(64);
yPos = yPos + vy;
// Change x-position on each redraw
xPos = xPos + vx;
ellipse(xPos, yPos, 50, 50);
if (xPos <= 0)
{
vx = 2;
fill(r, g, b);
} else if (xPos >= 400)
{
vx = -2;
fill(r, g, b);
}
if (yPos <= 0)
{
vy = 1;
fill(r, g, b);
} else if (yPos >= 300)
{
vy = -1;
fill(r, g, b);
}
}
It is quite easy. You maintain a counter which counts the amount of bounces. Therefore you increase the counter by one after every bounce. If it reaches 3 you change the color. After that you reset the counter and repeat.
Therefore add this member variable to your class (like you already did with xPos and others):
private int bounceCounter = 0;
which introduces the variable bounceCounter initially holding 0 as value.
Here is the modified draw method with highlighted changes and comments:
void draw() {
// New color to use if ball bounces
r = random(255);
b = random(255);
g = random(255);
background(64);
yPos = yPos + vy;
// Change x-position on each redraw
xPos = xPos + vx;
ellipse(xPos, yPos, 50, 50);
// Variable indicating whether the ball bounced or not
boolean bounced = false;
// Out of bounds: left
if (xPos <= 0) {
vx = 2;
bounced = true;
// Out of bounds: right
} else if (xPos >= 400) {
vx = -2;
bounced = true;
}
// Out of bounds: bottom
if (yPos <= 0) {
vy = 1;
bounced = true;
// Out of bounds: top
} else if (yPos >= 300) {
vy = -1;
bounced = true;
}
// React to bounce if bounced
if (bounced) {
// Increase bounce-counter by one
bounceCounter++;
// Third bounce occurred
if (bounceCounter == 3) {
// Change the color
fill(r, g, b);
// Reset the counter
bounceCounter = 0;
}
}
}

Categories

Resources