help - pong
Author |
Message |
whoareyou
|
Posted: Wed May 18, 2011 5:36 pm Post subject: help - pong |
|
|
I have a ball that can move around the screen and bounce off the edges of the console screen. Currently, I'm trying to add the paddle and make the ball bounce off of it. I tried to make an array to store the front side y-coordinates so if the ball touches it, then it would bounce off. My problem is that sometimes the ball gets stuck in the paddle and sometime it sticks to the paddle while moving down. Can anyone help me please?
ps. yes I'm using the HSA console, and sorry for the flashy graphics
Java: |
int x, y, w, h, vx, vy, timer;
x = c.maxx () / 2;
y = c.maxy () / 2;
w = 50;
h = w;
vx = 5;
vy = 5;
int x2, y2, w2, h2;
x2 = 0;
y2 = 124;
w2 = 30;
h2 = 250;
timer = 5;
c.setColor (Color.black);
c.fillOval (x, y, w, h);
c.fillRect (x2, y2, w2, h2);
int[] horizontal = new int [x2 + w2 + 1];
int[] vertical = new int [h2 - y2 + 1];
for (int i = 0 ; i < horizontal.length ; i++)
{
horizontal [i] = i;
}
int start = y2;
for (int i = 0 ; i < vertical.length ; i++)
{
vertical [i] = start;
start++;
}
while (true)
{
x += vx;
y += vy;
for (int i = 0 ; i < vertical.length ; i++)
{
if (vertical [i] < y && x < w && y < h2)
{
vx *= -1;
break;
}
}
if (x < 0 || x >= c.maxx () - w)
{
vx *= -1;
}
else if (y < 0 || y >= c.maxy () - h)
{
vy *= -1;
}
c.fillOval (x, y, w, h);
c.fillRect (x2, y2, w2, h2);
Thread.sleep (timer);
c.clear ();
}
|
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
Zren
|
Posted: Wed May 18, 2011 6:42 pm Post subject: RE:help - pong |
|
|
Good programming practices no1. Use descriptive variables. When you have two things with x and y values (or something similar), the approach is to use paddleX and ballX, not x1, x2. The latter kind of implies the two are connected somehow.
This code is a mess.
code: |
int start = y2;
for (int i = 0 ; i < vertical.length ; i++)
{
vertical [i] = start;
start++;
}
|
can be done with:
code: |
for (int i = 0 ; i < vertical.length ; i++)
{
vertical [i] = y2 + i;
}
|
I don't really understand to point of those two arrays anyways...
Your actual problem is probably do to the fact your paddle is moving onto the ball, and your collision detection is making it freak out and flip back and forth.
You should only be flipping it when it goes first hits (when the ball detects it will hit the paddle after it's moved). Not after it's moved.
Logic should go something like:
code: |
while {
getInput
movePaddle(s)
checkForBallsFutureCollision -> changeDirection?
moveBall
render
}
|
Basically the responce is to let the ball phaze through the paddle if it didn't reach it in time. |
|
|
|
|
|
whoareyou
|
Posted: Wed May 18, 2011 7:19 pm Post subject: Re: help - pong |
|
|
So I took your advice into consideration and this is what I got:
Java: |
int ballx, bally, paddlex, paddley, ballw, ballh, paddlew, paddleh, velox, veloy, pause;
ballx = c.maxx () / 2;
bally = c.maxy () / 2;
ballw = 50;
ballh = ballw;
paddlex = 0;
paddley = c.maxy () / 4;
paddlew = c.maxx () / 20;
paddleh = c.maxy () / 2;
velox = 5;
veloy = 5;
pause = 15;
c.fillRect (paddlex, paddley, paddlew, paddleh);
c.fillOval (ballx, bally, ballw, ballh);
while (true)
{
if (ballx <= paddlex && bally >= paddley && bally <= paddleh)
{
velox *= -1;
}
else if (ballx < 0 || ballx >= c.maxx () - ballw)
{
velox *= -1;
}
if (bally < 0 || bally >= c.maxy () - ballh)
{
veloy *= -1;
}
ballx += velox;
bally += veloy;
c.setColor (Color.black);
//c.fillRect (paddlex, paddley, paddlew, paddleh);
c.setColor (Color.red);
c.fillOval (ballx, bally, ballw, ballh);
Thread.sleep (pause);
//c.clear ();
}
|
This time around, the ball doesn't even detect the paddle and just pretends as if it isn't there. I inserted the code:
Java: |
if (ballx <= paddlex && bally >= paddley && bally <= paddleh)
{
velox *= -1;
}
|
but it doesn't seem to be fixing anything.
code: |
"If the x-pos of the ball is less than or equal to the paddle's x-pos AND the y-pos of the ball is greater than or equal to the the paddle's top y-pos AND the y-pos of the ball is less than the bottom y-pos of the paddle, then reflect the ball."
|
Unfortunately, this isn't even detecting the paddle at all and I don't know what I'm doing wrong . |
|
|
|
|
|
Zren
|
Posted: Wed May 18, 2011 7:39 pm Post subject: RE:help - pong |
|
|
if (ballx <= paddlex && bally >= paddley && bally <= paddleh)
paddleh is a constant. Well a constant as in you're never changing it. I'm preeeeety sure you meant (p.y + p.h). |
|
|
|
|
|
whoareyou
|
Posted: Wed May 18, 2011 8:36 pm Post subject: Re: help - pong |
|
|
Zren @ Sun May 01, 2011 11:35 pm wrote:
You need to start off with drawRect(offsetX, offsetY, ...) for everything instead of assuming it starts at (0,0).
Yes I remember now!
Okay, I fixed that and I also fixed the p.x + p.w, so now it bounces off the paddle. HOWEVER (gosh, there's always a problem!), after a couple of bounces it touches the paddle and then zig-zags down the paddle and then leaves it at the end, and I don't understand that. I can't really get a picture of it because it'll only show it stuck to the paddle.
This is that part that does the collision detection; I'm pretty sure the problem is occurring here, but I don't see a problem
Java: |
if (ballx <= paddlex + paddlew && bally >= paddley && bally <= paddley + paddleh)
{
velox *= -1;
}
else if (ballx < 0 || ballx >= c.maxx () - ballw)
{
velox *= -1;
}
if (bally < 0 || bally >= c.maxy () - ballh)
{
veloy *= -1;
}
|
|
|
|
|
|
|
Zren
|
Posted: Wed May 18, 2011 8:53 pm Post subject: Re: help - pong |
|
|
Read the latter part of my first post. I addressed the issue there. It's not the math, it's the method and order. You're moving to the new coordinates, then reacting, when you should be reacting before moving.
You could do a hackish approach (which I frown on) and don't do the flip if the ball is moving outwards... |
|
|
|
|
|
whoareyou
|
Posted: Wed May 18, 2011 8:57 pm Post subject: Re: RE:help - pong |
|
|
Zren @ Wed May 18, 2011 6:42 pm wrote:
Your actual problem is probably do to the fact your paddle is moving onto the ball, and your collision detection is making it freak out and flip back and forth.
You should only be flipping it when it goes first hits (when the ball detects it will hit the paddle after it's moved). Not after it's moved.
Logic should go something like:
code: |
while {
getInput
movePaddle(s)
checkForBallsFutureCollision -> changeDirection?
moveBall
render
}
|
Basically the responce is to let the ball phaze through the paddle if it didn't reach it in time.
Isn't that what I'm doing? I have my if statements before I actually add the values to the new position of the ball. |
|
|
|
|
|
Zren
|
Posted: Wed May 18, 2011 9:03 pm Post subject: RE:help - pong |
|
|
Yes but your if statements are for where the ball currently is. Not where it will be. So basicaly it's like:
checkHere
move
render
which, logic wise, is no different from
move
checkhere
Which is checking after you've moved.
Make a couple new variables, that you use to calculate where it will be, then after you've done the CD, set the ball's coords there. |
|
|
|
|
|
Sponsor Sponsor
|
|
|
whoareyou
|
Posted: Wed May 18, 2011 9:15 pm Post subject: RE:help - pong |
|
|
Okay, what I did was I created two new variables (ballx2 and bally2) [ps. i think you kind of hinted this before when you indicated that x1 and x2 are somehow related] and added velox and veloy to them, and then did the CD, and I'm stuck here.
Do I still keep the "then" for the "if's" the same? Because then it'd basically be the same thing that I was doing before (I think)?
I ran the program like this, and it still does the zig-zag down the paddle at the beginning.
Java: |
while (true)
{
ballx2 = ballx + velox;
bally2 = bally + veloy;
if (ballx2 <= paddlex + paddlew && bally2 >= paddley && bally2 <= paddley + paddleh)
{
velox *= -1;
}
else if (ballx2 < 0 || ballx2 >= c.maxx () - ballw)
{
velox *= -1;
}
if (bally2 < 0 || bally2 >= c.maxy () - ballh)
{
veloy *= -1;
}
ballx += velox;
bally += veloy;
c.setColor (Color.black);
c.fillRect (paddlex, paddley, paddlew, paddleh);
c.setColor (Color.red);
c.fillOval (ballx, bally, ballw, ballh);
Thread.sleep (pause);
c.clear ();
}
|
|
|
|
|
|
|
Zren
|
Posted: Wed May 18, 2011 9:38 pm Post subject: RE:help - pong |
|
|
Only at the beginning? Does it start within the paddle? The flip could also be that it's not traveling fast enough to exit the paddle. Perhaps moving the ballx to the edge of the paddle when it collides there?
PS: there's no point to calculating twice.
ballx = ballx2 |
|
|
|
|
|
whoareyou
|
Posted: Thu May 19, 2011 9:14 am Post subject: RE:help - pong |
|
|
No, the ball starts in the middle of the screen, but like after a few bounces around, when it touches the top edge and bottom edge of the paddle, it zig zags up/down the paddle. |
|
|
|
|
|
Raknarg
|
Posted: Thu May 19, 2011 10:51 am Post subject: Re: help - pong |
|
|
It might actually be because of your direction statement. If it's on the edge, and it doesn't get out before that statement comes back, it could get stuck in an infinite loop of being multiplied by -1.
Idk if that's it, but you could try something else for the direction and see if it helps. something like:
Java: |
if (bally2 <= 0 )
{
veloy = 1;
}
elsif (bally2 >= c.maxy () - ballh)
{
veloy = -1;
}
if (balx2 <= 0 )
{
velox = 1;
}
elsif (ballx2 >= c.maxx () - ballw)
{
velox= -1;
}
|
Idk Java, so it's probs something like that |
|
|
|
|
|
whoareyou
|
Posted: Thu May 19, 2011 2:41 pm Post subject: RE:help - pong |
|
|
I tried changing it the direction statements, but those didn't make a difference.
I tried changing the speed much higher and that throws the ball off the screen after a while.
This is why at the beginning I had my array; I was setting up all the points of the paddle into the array and checking the see if the ballx and bally coordinates touch the points in the array, then the necessary action would be taken.
I can't seem to fix the problem by doing this with what I currently have - I just wanna know if it would be a good idea to do the arrays? |
|
|
|
|
|
chrisbrown
|
Posted: Thu May 19, 2011 3:11 pm Post subject: Re: RE:help - pong |
|
|
whoareyou @ Thu May 19, 2011 2:41 pm wrote: I just wanna know if it would be a good idea to do the arrays? This is a good example of a terrible idea, no offence intended. That would involve much more work than is necessary.
If you detect a collision, adjust the position of the ball so that it only touches the border instead of overlapping it. For example, if x < 0, set x to 0 and then reverse direction. That way, your collision detection corrects for invalid ball positions.
Similarly (and this will involve just a little more logic), if you detect a ball-paddle collision (i.e. that the ball is inside the paddle), move the ball so that it is located just outside the paddle on the side that it is coming from, and then reverse direction. |
|
|
|
|
|
whoareyou
|
Posted: Thu May 19, 2011 3:51 pm Post subject: Re: help - pong |
|
|
I added an if statement, so now it doesn't zig zag down the paddle (or at least, in the first 2 minutes of runtime that I've been watching) but now, you see how theres like a barrier at paddlex+paddlew? Even though it's not hitting the paddle, the ball will still bounce off at paddlex+paddlew; it doesn't go to the spaces above and below the paddle.
ps. the random colors are so that I can see where the ball is moving
pss. i tried chrisbrown's way, and the result is the same ...
Java: |
// The "Moving_Ball" class.
import java.awt.*;
import hsa.Console;
public class Moving_Ball
{
static Console c;
public static void main (String[] args) throws InterruptedException
{
c = new Console ();
int ballx, bally, paddlex, paddley, ballw, ballh, paddlew, paddleh, velox, veloy, pause;
ballx = c.maxx () / 2;
bally = c.maxy () / 2;
ballw = 50;
ballh = ballw;
paddlex = 0;
paddley = c.maxy () / 4;
paddlew = c.maxx () / 20;
paddleh = c.maxy () / 2;
velox = 10;
veloy = 10;
pause = 5;
c.fillRect (paddlex, paddley, paddlew, paddleh);
c.fillOval (ballx, bally, ballw, ballh);
while (true)
{
if (ballx <= paddlex + paddlew && (bally <= paddley || bally >= paddley + paddleh))
{
velox *= -1;
}
if (ballx <= paddlex + paddlew && bally >= paddley && bally <= paddley + paddleh)
{
velox *= -1;
}
if (ballx <= 0 || ballx >= c.maxx () - ballw)
{
velox *= -1;
}
if (bally <= 0 || bally >= c.maxy () - ballh)
{
veloy *= -1;
}
ballx += velox;
bally += veloy;
c.setColor (Color.black);
//c.fillRect (paddlex, paddley, paddlew, paddleh);
int R = (int) (Math.random () * 256);
int G = (int) (Math.random () * 256);
int B = (int) (Math.random () * 256);
Color randomColor = new Color (R, G, B);
c.setColor (randomColor); //Set random color
c.fillOval (ballx, bally, ballw, ballh);
Thread.sleep (pause);
//c.clear ();
}
} // main method
} // Moving_Ball class
|
|
|
|
|
|
|
|
|