Why can't I remove and draw the same java object? - java

I try to do homework, and I write breakout game. Now,I write the basic function of this game finish.but I want to increase Bonus When ball crash the bonusbricks,I write method to check them and get the color form object that ball crash.
} else if(color == Color.BLACK){
double xBonus = ball.getX() +20;
double yBonus = ball.getY() +20;
remove(ball);
ball = new GOval(xBonus, yBonus, BALL_RADIUS+20, BALL_RADIUS+20);
ball.setFilled(true);
ball.setFillColor(Color.RED);
add(ball);
GObject collider = getCollidingObject();
I use collider to detect the object that ball crash
but when the ball crash the bonus brick. The ball has increase size but collider is detect new ball object to be the bricks and bounce ball though game edge.
Please help me .. Sorry,for my wrong grammatically.

I believe you want to use * 20 on your ball.getX and ball.getY assignments.
It sounds like the new ball object is not in the same instance as the original game panel. You should make sure you are accepting the new ball object in the same instance on the panel that the game is played.
If you show some more of your code I may be able to be more specific.

Related

Collision detection in game of pong corner cases causing issues

I have made a game of pong and everything about it is working so far. I did the collisions against the paddles to the ball and it can correctly bounce them away unless it hits the corners.
This is a video of what happens when the ball hits the corner of one of the paddles.
https://drive.google.com/file/d/1nyRzsp5tn5Qvst7kVjtlr_rDNH98avbA/view?usp=sharing
Essentially what you can see happen in the video is the ball hits the the paddle on the left at the corner and it doesn't bounce back it just traverses the paddle downwards and then keeps going and they get a point. Here is my code for the collision testing
public void collision() {
this.width = (float) getBounds().width;
this.height = (float) getBounds().height;
for (int i = 0; i < handler.objects.size(); i++) {
if (handler.objects.get(i).getId() == ID.ball) {
GameObject current = handler.objects.get(i);
if (getBounds().intersects(current.getBounds())) {
current.setVx(current.getVx() * -1);
}
}
}
}
getBounds is an overridden method that just returns a rectangle for both the ball(which is a circle) and the paddle
I am happy to provide more of my code if necessary.
Any help on this would be great, thanks!
You are swapping the velocity direction each time you are hitting the paddle, even when you are still touching the paddle in the next frame. The solution is to swap the velocity direction only when the ball is heading towards the paddle, not when (already) going away. The pseudo code can look like this:
if (GeometryUtil.isDirectionGoingDown(direction)) {
if (GeometryUtil.isBallHittingHorizontalLine(
newPosition,
Ball.RADIUS,
paddleTopLeft,
paddleTopRight)) {
direction = calculateNewDirectionAfterHittingPaddle(
direction,
paddlePosition,
newPosition);
ball.setDirection(direction);
}
}
Here the GeometryUtil.isDirectionGoingDown() method is checking if the ball is actually going down. That way the new direction is only set when this condition returned true. When the direction has been swapped in one frame, the next frame will not swap the direction again because GeometryUtil.isDirectionGoingDown() will return false then.

Java Brickbreaker paddle collision detection

I am trying to make a brickbreaker game and I have run into some issues when it comes to collision detection. If you have ever played brick breaker you know that on the paddle, if the ball is moving to the left and you hit the left side of the top, then it continues moving right. Although, if you hit it on the right side in this case, then the ball changes directions. And also if you hit it on the sides of the paddle, it bounces off on the Y axis. Since I have no idea how to do the top part of the paddle, I can't show you the code because I don't have any :) This is the code that I am using for the sides:
Rectangle rect1 = new Rectangle((int) paddleDir, 570, imsLoader.getImage("paddle1").getWidth(), imsLoader.getImage("paddle1").getHeight());
Rectangle rect2 = new Rectangle((int) ballX, (int) ballY, imsLoader.getImage("ball").getWidth(), imsLoader.getImage("ball").getHeight());
if (rect1.intersects(rect2))
{
if (rect1.x == rect2.getMaxX() || rect1.getMaxX() == rect2.x)
{
ballVX = -ballVX;
clipsLoader.play("pattleHit", false);
}
else
{
ballVY = -ballVY;
ballY += 0.05;
clipsLoader.play("pattleHit", false);
}
}
What happens is that the ball when gets hit on the side, just goes right through the paddle going all over the place and when it reaches the other end either goes up or down!
You have to make the ball bounce, right?
Let's look at an example. Think the top square as the ball (I can't draw that nice). When the ball collides from left, it should move right and if it's from right, then go left.
You can achieve this with a simple thing. Don't change the horizontal velocity but instead reverse the vertical one.
if (ball.getBounds().intersects(paddle.getBounds()))
{
ball.setVy(-ball.getVy());
}
Easy right!
Now let's figure out how to do bounce effect on bricks.
This is a scenario when ball hits the brick. The red area is the intersection. Now notice it carefully.
If the intersection width is greater than the intersection height, the ball has hit in the bottom or vertical sides of the brick.
If the intersection height is greater that the intersection width, then it is a horizontal collision.
So we have to first calculate the intersection rectangle. It's so easy with java.
Rectangle intersection = ball.getBounds().intersection(brick.getBounds());
Now let's implement the bouncing.
if (intersection.width >= intersection.height)
{
ball.setVy(-ball.getVy());
}
if (intersection.height >= intersection.width)
{
ball.setVx(-ball.getVx());
}
That's it and you should have it fully functional.

Box2D stopping a dynamic body from moving after collision

I am trying to re-create Pong using LibGDX and Box2D. I have 2 problems, if I fix one it creates another.
My paddles are currently set to Kinematic and are controlled using the up/down keys via a controller class. This works just fine and I can happily play back and forth.
Problem being, my walls are static bodies and my paddles just travel right through them.
Now I can fix this by simple changing the paddle body to a dynamic one, this stops the paddles from going through the walls but then when my ball strikes off a paddle, it goes flying off the X axis and off the screen.
I have tried adding an update method in my controller class as follows:
public void update(float delta){
paddleBodyPosY = paddleBody.getPosition().x;
paddleBodyPosY = paddleBody.getPosition().y;
System.out.println(paddleBodyPosY);
}
The console reports the paddle position being updated every frame, from top to bottom of screen.
So I went back to my GameScreen class and tried all sorts of code in the Render() method like so:
if(playerOnePaddle.paddleBodyPosY < 0){
playerOnePaddle.paddleBody.getPosition().y = 0;
System.out.println("resetting paddle");
}
I have tried LOADS of variations, I can easily break movement by calling paddleBody.setLinearVelocity(0,0) but then it gets stuck like this and it's not movable anymore. Obviously the problem must lie with the fact that I can't set a position using a getter lol.
Any ideas? If you need more snippets ask, I didn't want to overload the question with 100 lines of code you don't need to see :S.
The paddle creation method:
public void createPaddle(World world, float x, float y){
//Define a body for the paddle
BodyDef paddleBodyDef = new BodyDef();
paddleBodyDef.type = BodyType.KinematicBody;
paddleBodyDef.position.set(x, y);
//Define a shape for the paddle
PolygonShape paddleShape = new PolygonShape();
paddleShape.setAsBox(paddleWidth, paddleHeight);
//Define a fixture for the paddle
FixtureDef paddleFixtureDef = new FixtureDef();
paddleFixtureDef.shape = paddleShape;
paddleFixtureDef.density = 0;
//Ensures ball bounces off paddle
//Consistently without losing velocity
paddleFixtureDef.restitution = 1.005f;
//Create the paddles
paddleBody = world.createBody(paddleBodyDef);
paddleFixture = paddleBody.createFixture(paddleFixtureDef);
paddleShape.dispose();
}
Heh, so what I did was.
Set my paddles to dynamic, then set there mass to a stupidly high number so that the a ball would not move them on the x axis, well not enough for the human eye to see at least.
Seems like a cheap fix, if anyone has anything better...that would be great lol

Java Pong - assign various reflection points to different parts of a paddle

I'm making pong in Java and wanted to make the game more fun by assigning different reflection logic to each part of the paddle, like so:
(ball hittins outter edges of paddle will have a different effect than it hitting the middle of the paddle)
The paddle extends Rectangle2D so I could use Rectangle2D's intersects() method to determine if the ball has touched any part of it...
Is it possible to determine where exactly the ball has hit on the paddle?
What I'm planning to do is,
calculate angle of incidence and reflective angle based on that...
If the ball hits at a point x on the paddle... I will change the reflection angle accordingly
Thanks
Is it possible to determine where exactly the ball has hit on the paddle?
If it were me, I would grab the current co-ordinates of both the ball and the paddle. For the paddle, you can get two sets of y co-ordinates, to describe the line facing the ball. Ie:
int paddleY1 = paddle.y;
int paddleY2 = paddle.y + paddle.width;
// assuming the paddle can only go up and down, y is the only co-ordinate that matters.
Then, you can compute the mid point of the paddle as:
int paddleYMid = (paddleY1 + paddleY2) / 2;
You can find out if the ball hit the left or right side of the paddle by comparing the y co-ordinates. Ie:
if(ball.y > paddleYMid)
{
// Right side of the paddle.
}
else
{
// Left side of the paddle.
}
Then it's up to you to develop further refinement.
Since the paddle is always vertical (parallel to Y axis), the point of collision of the ball and the paddle will happen at the same y-coordinate as the center of the ball. That is:
if (ball.centerX - ball.radius <= paddle.rightX && ball.velocityX < 0)
{
// collision point, if any, is at (ball.centerX - ball.radius, ball.centerY)
if (ball.centerY >= paddle.bottomY && ball.centerY <= paddle.topY)
{
// handle collision
}
}
As for the handling of the collision itself, you may not have to deal with angle of reflection, etc, but work solely with the raw values of x and y velocity. For example, to simulate a perfectly elastic collision, simply do:
ball.velocityX = -ball.velocityX;
And to account for ball reflecting at a higher or lower angle, you can scale the y velocity based on the position of the collision from the center of the paddle, eg.
ball.velocityY += SCALE_CONSTANT * (ball.centerY - ((paddle.topY + paddle.bottomY) / 2));
To find the exact spot where the ball hits the paddle, you can formulate the problem as a line intersection problem.
The paddle can be represented as a vertical line at the x-coordinate (+thickness if needed, and corrected for the balls diameter) of the paddle. The ball can then be represented as a line along its movement vector (this line could be simply defined by its current position and its next position if it were to move unimpended).
The problem can now be solved using a line intersection algorythm.
Since the paddle is a vertical line, the equations can be simplified to just answer the question at which Y will the ball pass the paddle's X. Thats also a common problem encountered and solved by line clipping: http://en.wikipedia.org/wiki/Line_clipping (the intersection points can also be computed directly, but I can't find the formula atm).

Need help moving an object away from the mouse at the correct rates

I am new to programming, and I am trying to make a 2d applet that will move a circle or ball away from the mouse. The way I want the physics in this program to work is to make the object act like a ball, and the mouse like a movable hill. When the mouse get closer to the ball, it repels the ball faster and farther away, and when the mouse gets farther away from the ball, the ball slows down and eventually stops moving. I need to take into account both the total distance between the mouse and the object, and the x and y distance so the movement of the object is smooth and more realistic. The biggest problem that I have is that even as the distance between the two points become greater, the rate at which the ball moves away stays relatively constant. Currently the rate is the distance of x or y multiplied by a constant, and divided by the total distance. This more or less works when the mouse moves closer to the object, and the rate increases as it should, but it fails when the mouse moves away. I want the rate to decrease and eventually become 0 when the mouse moves away, but in my current set up the x distance will also increase as the distance increases, and the rate will not decrease as much as I want it to, if at all. The way I have it now probably needs to be scraped all together, and thanks for the help.
public void mouseMoved (MouseEvent e)
{
//distance between x coord
xd=e.getX()-x;
//distance between y coord
yd=y-e.getY();
//total distance between mouse and ball
d=Math.sqrt((Math.pow(xd,2))+(Math.pow(yd,2)));
//rate of x change
xrate=(Math.sqrt(Math.pow(xd,2))*4)/(d);
//rate of y change
yrate=(Math.sqrt(Math.pow(yd,2))*4)/(d);
//determines movement of ball based on position of the mouse relative to the ball
if(xd>0)
{
x=x-((int)(xrate));
}
if(xd<0)
{
x=x+((int)(xrate));
}
if(yd>0)
{
y=y+((int)(yrate));
}
if(yd<0)
{
y=y-((int)(yrate));
}
//updates x and y coords of ball
repaint();
}
try this-
//rate of x change
xrate=(1.0/(d))*20; //20 is just a random constant I guessed
//rate of y change
yrate=(1.0/(d))*20;
You just did wrong math.
//total distance between mouse and ball
d=Math.sqrt((Math.pow(xd,2))+(Math.pow(yd,2)));
//rate of x change
xrate=(Math.sqrt(Math.pow(xd,2))*4)/(d);
Think about this :
If you only move on the x cord, will simply make yd equals 0 and d=|xd|
So xrate = |xd|*4/(d) = d*4/d = 4.
There is a easy way to accomplish your task, just make xrate and yrate related with xd and yd.
You can try this :
if(xd==0){
xd = 0.1;//minimum distance
}
if(yd==0){
yd = 0.1;
}
xrate = (1/xd)*10; // you can change number 100 for proper speed
yrate = (1/yd)*10;
x = x - xrate;
y = y - yrate;
Hope this can help.

Categories