Computer Science Canada

Need help for java game

Author:  KeyLimePie [ Fri May 24, 2013 12:56 pm ]
Post subject:  Need help for java game

My game should exit when the ball touches one of the lines. Can someone help me think of a way to achieve this?
Heres is my code so far: (its basically just a ball that can be moved with the arrow keys and some lines)
code:

    public void paint (Graphics g)
    {
        super.repaint ();
        g.setColor (Color.black);
        g.fillRect (0, 0, 1024, 750);

        Font a = new Font ("Century Gothic", Font.BOLD, 18);
        g.setFont (a);
        g.setColor (Color.white);
        g.fillRect (0, 0, 100, 25);
        g.setColor (Color.black);
        g.drawString ("Stage One", 3, 20);

        Color bc = Color.white;
        g.setColor (bc); // ball
        g.fillOval (ballX, ballY, 20, 20);
       
        Color c1 = Color.red;
        g.setColor (c1);
        g.fillRect (35, 35, 5, 500); // red line boundary

        Color c2 = new Color (192, 82, 146); // pink line
        g.setColor (c2);
        g.drawLine (500, 400, 70, 35);       // thickness
        g.drawLine (500, 401, 70, 36);
        g.drawLine (500, 402, 70, 37);
        g.drawLine (500, 403, 70, 38);
        g.drawLine (500, 404, 70, 39);
        g.drawLine (500, 405, 70, 40);

        g.setColor (Color.cyan);
        g.drawLine (100, 350, 500, 500); // bottom-left center cyan line
        g.drawLine (101, 351, 501, 501);
        g.drawLine (102, 352, 502, 502);
        g.drawLine (103, 353, 503, 503);

        g.setColor (Color.blue);
        g.drawLine (150, 400, 400, 205); // center blue line intersects bottom cyan line
        g.drawLine (151, 401, 401, 206);
        g.drawLine (152, 402, 402, 207);
        g.drawLine (153, 403, 403, 208);

        g.setColor (Color.yellow);
        g.drawLine (200, 100, 100, 500);  //
        g.drawLine (201, 101, 101, 501);
        g.drawLine (202, 102, 102, 502);
        g.drawLine (203, 103, 103, 503);

    }


    public void keyPressed (KeyEvent a)
    {
        int keyCode = a.getKeyCode ();
        if (keyCode == KeyEvent.VK_DOWN) // ball speed at 5
        {
            ballY += 5;
        }
        if (keyCode == KeyEvent.VK_UP)
        {
            ballY -= 5;

        }
        if (keyCode == KeyEvent.VK_LEFT)
        {
            ballX -= 5;

        }
        if (keyCode == KeyEvent.VK_RIGHT)
        {
            ballX += 5;
        }
    }


    public void keyReleased (KeyEvent a)
    {
    }


    public void keyTyped (KeyEvent a)
    {
    }

Author:  andrew. [ Fri May 24, 2013 12:57 pm ]
Post subject:  RE:Need help for java game

Well how do you tell if the ball has reached a line?

Author:  KeyLimePie [ Fri May 24, 2013 1:01 pm ]
Post subject:  Re: RE:Need help for java game

andrew. @ Fri May 24, 2013 12:57 pm wrote:
Well how do you tell if the ball has reached a line?


Thats what im trying to ask...

Author:  Nathan4102 [ Fri May 24, 2013 1:07 pm ]
Post subject:  RE:Need help for java game

You have the ball's x and y coords, and you have the line's x and y coords. Using those, you can figure out when the ball is touching the line.

Author:  KeyLimePie [ Fri May 24, 2013 1:11 pm ]
Post subject:  Re: RE:Need help for java game

Nathan4102 @ Fri May 24, 2013 1:07 pm wrote:
You have the ball's x and y coords, and you have the line's x and y coords. Using those, you can figure out when the ball is touching the line.


yeah i know i could do that, but wouldnt it be really inefficient to do that for every single line? Im probably going to have around 50 lines, and thats a hassle to do each one.

Author:  Panphobia [ Fri May 24, 2013 1:30 pm ]
Post subject:  RE:Need help for java game

Just add an if statement that asks whether the ball is within the Parameters of the line

Author:  KeyLimePie [ Mon May 27, 2013 11:22 am ]
Post subject:  Re: RE:Need help for java game

Panphobia @ Fri May 24, 2013 1:30 pm wrote:
Just add an if statement that asks whether the ball is within the Parameters of the line


I added an if statement for ballX and ballY at a specified location. How do you specify the exact parameters of the line in the if statement?

Example code:

if (ballX == 500 && ballY == 500);
{
System.exit (0);
}

Thanks Smile

Author:  Insectoid [ Mon May 27, 2013 12:47 pm ]
Post subject:  RE:Need help for java game

Given 2 points on a line, you can get its equation in the form ax+by+c=0. You then can calculate the distance between the centre of the ball and the line using the forumla abs(ax+by+c)/sqrt(a^2+b^2). If the distance is less than or equal to the radius of the ball, they have collided.

Author:  KeyLimePie [ Tue May 28, 2013 12:38 pm ]
Post subject:  Re: RE:Need help for java game

Insectoid @ Mon May 27, 2013 12:47 pm wrote:
Given 2 points on a line, you can get its equation in the form ax+by+c=0. You then can calculate the distance between the centre of the ball and the line using the forumla abs(ax+by+c)/sqrt(a^2+b^2). If the distance is less than or equal to the radius of the ball, they have collided.


is there a more efficient way to detect the collision? is it possible to detect specific colors for the lines?

Author:  KeyLimePie [ Thu May 30, 2013 12:31 pm ]
Post subject:  Re: Need help for java game

PLEASE HELP ME Sad Sad Sad Sad Sad

Author:  DemonWasp [ Thu May 30, 2013 1:01 pm ]
Post subject:  RE:Need help for java game

There isn't really a more efficient way (at least, not in terms of computer time). But, Java does have a library that could help (hint: in Java, this is almost invariably true: either the standard library covers your use case or there is a free open-source library that helps).

In this case, there is an existing Line2D class that you can use to represent a line segment (notably not a line, which is infinite). That class also has a method called ptLineDist which will tell you how far a point is from that line. As Insectoid mentioned, if that distance is less than the ball's radius, then the ball has collided with that line.

Since you are almost certainly using Ready To Program Java, here's a link to the Java 1.4.2 API for Line2D: http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/geom/Line2D.html

Once you have represented your lines with Line2D objects, you can also use those to draw the lines themselves. Here's a short code snippet that should help you:

Java:

// Imports are required!
import java.awt.geom.Line2D;

// Representing a line
Line2D line = new Line2D.Double(100, 350, 500, 500);  // specify your line coordinates exactly once

// Computing distance from ball to line:
float dist = line.ptLineDist ( ball.x, ball.y );
// You'll have to figure out the code for checking whether the ball collides with the line on your own. Read what Insectoid said carefully, then read the line above this one.

// Drawing the line:
g.drawLine ( line.getX1(), line.getY1(), line.getX2(), line.getY2() );


One other piece of advice: instead of drawing each line 4+ times to make them look thicker, try setting the Graphics object up to draw thicker lines. I didn't know how to do that, so I:

1) Googled "java draw thick line". The first result was this: http://stackoverflow.com/questions/2839508/java2d-increase-the-line-width
2) Read that code snippet.
3) Reduce the code snippet to the minimum required:

Java:

((Graphics2D)g).setStroke(new BasicStroke(10)); // change the 10 to increase or decrease line thickness


put that as the first line of paint and you should get thicker lines.

Author:  KeyLimePie [ Tue Jun 04, 2013 1:52 pm ]
Post subject:  Re: RE:Need help for java game

DemonWasp @ Thu May 30, 2013 1:01 pm wrote:
There isn't really a more efficient way (at least, not in terms of computer time). But, Java does have a library that could help (hint: in Java, this is almost invariably true: either the standard library covers your use case or there is a free open-source library that helps).

In this case, there is an existing Line2D class that you can use to represent a line segment (notably not a line, which is infinite). That class also has a method called ptLineDist which will tell you how far a point is from that line. As Insectoid mentioned, if that distance is less than the ball's radius, then the ball has collided with that line.

Since you are almost certainly using Ready To Program Java, here's a link to the Java 1.4.2 API for Line2D: http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/geom/Line2D.html

Once you have represented your lines with Line2D objects, you can also use those to draw the lines themselves. Here's a short code snippet that should help you:

Java:

// Imports are required!
import java.awt.geom.Line2D;

// Representing a line
Line2D line = new Line2D.Double(100, 350, 500, 500);  // specify your line coordinates exactly once

// Computing distance from ball to line:
float dist = line.ptLineDist ( ball.x, ball.y );
// You'll have to figure out the code for checking whether the ball collides with the line on your own. Read what Insectoid said carefully, then read the line above this one.

// Drawing the line:
g.drawLine ( line.getX1(), line.getY1(), line.getX2(), line.getY2() );


One other piece of advice: instead of drawing each line 4+ times to make them look thicker, try setting the Graphics object up to draw thicker lines. I didn't know how to do that, so I:

1) Googled "java draw thick line". The first result was this: http://stackoverflow.com/questions/2839508/java2d-increase-the-line-width
2) Read that code snippet.
3) Reduce the code snippet to the minimum required:

Java:

((Graphics2D)g).setStroke(new BasicStroke(10)); // change the 10 to increase or decrease line thickness


put that as the first line of paint and you should get thicker lines.


Thank you for your suggestions. Smile I managed to represent and draw a line using Line2D and I added thickness to my lines. I don't know how to use float dist = line.ptLineDist ( ball.x, ball.y ); It took me a really long time but I figured out the equation of the line but I do not know what the ball.x and ball.y values are. Do I compare the distance with the ball's radius or the centre of the ball? If so, how do you find the centre point of the ball?

int ballX = 50;
int ballY = 500;
static int rx = 20;
static int ry = 20;

g.fillOval (ballX, ballY, rx, ry);

If I decide to change my entire game to vertical and horizontal lines (like a maze), would it be easier to calculate the collision detection because my final ISU is due really soon?

Thanks! Very Happy

Author:  DemonWasp [ Tue Jun 04, 2013 4:37 pm ]
Post subject:  RE:Need help for java game

You find the centre point of the ball by already knowing it (ballX, ballY). Note that you're drawing the ball incorrectly: g.fillOval(ballX, ballY, rx, ry) draws from (ballX, ballY) to (ballX+rx, ballY+ry). That means that it's drawing a ball centered at (ballX+rx/2, ballY+ry/2).

You need to figure out how to draw a ball centred at (ballX, ballY). That shouldn't be too hard: try drawing a ball with a radius of 5 first, then switch the 5 out for a variable.

You calculate the distance from the ball's centre coordinates (ballX, ballY) to the line. Then you compare that with the ball's radius. If the distance is less than that radius, then the ball and the line must have collided. You'll have to figure out how to turn that into code yourself.

Switching to strictly vertical and horizontal lines won't really make your life any easier. Honestly you should have maybe 3 lines of code to detect a collision between the ball and any single line. You should only have to add two lines of code to turn that into checking for collisions between the ball and ALL lines.

Author:  KeyLimePie [ Wed Jun 05, 2013 1:01 pm ]
Post subject:  Re: RE:Need help for java game

DemonWasp @ Tue Jun 04, 2013 4:37 pm wrote:
You find the centre point of the ball by already knowing it (ballX, ballY). Note that you're drawing the ball incorrectly: g.fillOval(ballX, ballY, rx, ry) draws from (ballX, ballY) to (ballX+rx, ballY+ry). That means that it's drawing a ball centered at (ballX+rx/2, ballY+ry/2).

You need to figure out how to draw a ball centred at (ballX, ballY). That shouldn't be too hard: try drawing a ball with a radius of 5 first, then switch the 5 out for a variable.

You calculate the distance from the ball's centre coordinates (ballX, ballY) to the line. Then you compare that with the ball's radius. If the distance is less than that radius, then the ball and the line must have collided. You'll have to figure out how to turn that into code yourself.

Switching to strictly vertical and horizontal lines won't really make your life any easier. Honestly you should have maybe 3 lines of code to detect a collision between the ball and any single line. You should only have to add two lines of code to turn that into checking for collisions between the ball and ALL lines.


I fixed the radius of the ball. The collision detection checks for the line (infinitely) but I do not know how to implement the math equation in the code so that it checks for the specific max and min points of a line.

code:

        double dist = (((-4 * ballXR) + (900 * ballYR)) / Math.sqrt (Math.pow (radius, 2) + Math.pow (radius, 2)));
         if (((-4 * ballXR + 900 * ballYR)) / Math.sqrt (Math.pow (radius, 2) + Math.pow (radius, 2)) == 1000)
         {
         g.setColor (Color.white);
         g.drawString ("You lose!", 50, 100);
         }


Here is the code I currently have:

code:

        int radius = 10;  // radius of ball
        int ballXR = ballX - radius;
        int ballYR = ballY - radius;

        g.fillOval (ballXR, ballYR, 2 * radius, 2 * radius);  // draws the ball

        Graphics2D G2D = (Graphics2D) g; // yellow line
        Line2D L1 = new Line2D.Double (200, 100, 100, 500);
        double dist = L1.ptLineDist (ballXR+10, ballYR+10);
        g.setColor (Color.yellow);
        g.drawLine ((int) L1.getX1 (), (int) L1.getY1 (), (int) L1.getX2 (), (int) L1.getY2 ());

        if (dist <= radius)
        {
            g.setColor (Color.white);
            g.drawString ("You lose!", 50, 100);
        }

Thanks! Smile

Author:  DemonWasp [ Wed Jun 05, 2013 2:09 pm ]
Post subject:  RE:Need help for java game

Your code seems to have all the critical bits there (even if it is a bit messy).

You are right, however, that you're checking the line, rather than the line segment. This is my fault: I told you to use ptLineDist when I should have said ptSegDist. If you look carefully at http://docs.oracle.com/javase/6/docs/api/java/awt/geom/Line2D.html , you'll see that ptSegDist will find the distance to the line segment, rather than the infinite-extension of the line.

(Sorry!)

Author:  KeyLimePie [ Thu Jun 06, 2013 12:20 pm ]
Post subject:  Re: RE:Need help for java game

DemonWasp @ Wed Jun 05, 2013 2:09 pm wrote:
Your code seems to have all the critical bits there (even if it is a bit messy).

You are right, however, that you're checking the line, rather than the line segment. This is my fault: I told you to use ptLineDist when I should have said ptSegDist. If you look carefully at http://docs.oracle.com/javase/6/docs/api/java/awt/geom/Line2D.html , you'll see that ptSegDist will find the distance to the line segment, rather than the infinite-extension of the line.

(Sorry!)


Thank you! I fixed my game. Is there a way to check for the other lines without repeating it?

Author:  DemonWasp [ Thu Jun 06, 2013 12:37 pm ]
Post subject:  RE:Need help for java game

Yes, of course there is!

Instead of:
Java:

Line2D line1 = new Line2D.Double ( ... );
Line2D line2 = new Line2D.Double ( ... );


You should be putting all of your lines (and any other repeated objects) into a collection of some kind. There are a few basic types (List, Set, Map), but the best one for this scenario is a List:

Java:

// Note: this syntax is for Java versions prior to 1.5. I'll show the newer version below...

List lines = new ArrayList();
lines.add ( new Line2D.Double ( ... ) );
lines.add ( new Line2D.Double ( ... ) );

// Then later on, you can check the ball against all lines pretty easily by checking them one at a time:
for ( int i = 0; i < lines.size(); ++i ) {
    Line2D line = lines.get(i);

    // Fill in your "check ball against line" code here (exactly once, not more!).
    // Make sure you're checking against the 'line' variable I introduce in the line above, not L1 or something else.
}


Of course, if you're using a newer version of Java, such as 1.7 or better, the syntax gets a bit better:
Java:

List<Line2D> lines = new ArrayList<>();
lines.add ( new Line2D.Double ( ... ) );
lines.add ( new Line2D.Double ( ... ) );

// Then for each line in lines, check that line against the ball:
for ( Line2D line : lines ) {
    // Fill in your "check ball against line" code here...
}

Author:  KeyLimePie [ Sun Jun 09, 2013 9:42 pm ]
Post subject:  Re: RE:Need help for java game

DemonWasp @ Thu Jun 06, 2013 12:37 pm wrote:
Yes, of course there is!

Instead of:
Java:

Line2D line1 = new Line2D.Double ( ... );
Line2D line2 = new Line2D.Double ( ... );


You should be putting all of your lines (and any other repeated objects) into a collection of some kind. There are a few basic types (List, Set, Map), but the best one for this scenario is a List:

Java:

// Note: this syntax is for Java versions prior to 1.5. I'll show the newer version below...

List lines = new ArrayList();
lines.add ( new Line2D.Double ( ... ) );
lines.add ( new Line2D.Double ( ... ) );

// Then later on, you can check the ball against all lines pretty easily by checking them one at a time:
for ( int i = 0; i < lines.size(); ++i ) {
    Line2D line = lines.get(i);

    // Fill in your "check ball against line" code here (exactly once, not more!).
    // Make sure you're checking against the 'line' variable I introduce in the line above, not L1 or something else.
}


Of course, if you're using a newer version of Java, such as 1.7 or better, the syntax gets a bit better:
Java:

List<Line2D> lines = new ArrayList<>();
lines.add ( new Line2D.Double ( ... ) );
lines.add ( new Line2D.Double ( ... ) );

// Then for each line in lines, check that line against the ball:
for ( Line2D line : lines ) {
    // Fill in your "check ball against line" code here...
}


Thank you! I added the list into my game and it checks for all the lines in my game. Smile

I want to clear all the lines on the screen after the collision occurs. I tried to use GC.dispose (); but it displays an error if I add it to my if dist statement. How do I dispose the frame if the ball touches the lines (lose) and the white box (win) so that I can make a new frame?

code:

    public static void main (String[] args) // transitions from splash screen to game
    {
        PCircle PC = new PCircle ();

        GC.setSize (800, 600);
        int x = ((1024 - 640) / 2);
        int y = ((768 - 480) / 2);
        GC.setLocation (x, y);

        GC.add (PC); // new frame for game content

        GC.setVisible (true);
    }
   
    public void paint (Graphics g)
    {
        g.setColor (Color.white); // white color box
        g.fillRect (220, 360, 20, 20); // draws the box
    }

Author:  DemonWasp [ Sun Jun 09, 2013 10:32 pm ]
Post subject:  Re: RE:Need help for java game

KeyLimePie @ Sun Jun 09, 2013 9:42 pm wrote:
I want to clear all the lines on the screen after the collision occurs. I tried to use GC.dispose (); but it displays an error if I add it to my if dist statement. How do I dispose the frame if the ball touches the lines (lose) and the white box (win) so that I can make a new frame?


I'm not a Swing expert, but I think you want to call .dispose() on the JFrame. Is 'GC' a JFrame object? If it is, can you post the exact error you're encountering?

If not, can you post your whole source code so that I can run it?

Author:  KeyLimePie [ Tue Jun 11, 2013 3:30 am ]
Post subject:  Re: RE:Need help for java game

DemonWasp @ Sun Jun 09, 2013 10:32 pm wrote:
KeyLimePie @ Sun Jun 09, 2013 9:42 pm wrote:
I want to clear all the lines on the screen after the collision occurs. I tried to use GC.dispose (); but it displays an error if I add it to my if dist statement. How do I dispose the frame if the ball touches the lines (lose) and the white box (win) so that I can make a new frame?


I'm not a Swing expert, but I think you want to call .dispose() on the JFrame. Is 'GC' a JFrame object? If it is, can you post the exact error you're encountering?

If not, can you post your whole source code so that I can run it?


My game works now.

Thank you for helping me. Smile I've learned a lot from you! Very Happy


: