Java - getBounds2D,Ellipse Rectangle Collision

时间:2012-03-01 10:19:12

标签: java 2d collision

我刚刚开始使用Java,我们被要求制作乒乓球(或其上的扭曲)。我目前正在研究球和球员之间的碰撞。我有这个代码。

Rectangle2D.Double player;
Ellipse2D.Double ball;
public void drawActualPicture( Graphics2D g )
{
    // Players Bat

    g.setPaint( Color.green );              // Paint Colour
    player = new Rectangle2D.Double( playerX, playerY, PW, PH );
    g.fill(player);

    // The ball at the current x, y position (width, height)
    g.setPaint( Color.red );
    ball = new Ellipse2D.Double( x-HALF_BALL_SIZE, y-HALF_BALL_SIZE, BALL_SIZE, BALL_SIZE );
    g.fill( ball );
}

一些不相关的代码已被删除。

然后检测我的碰撞我用过

if ( ball.getBounds2D() == player.getBounds2D() )
{
    System.out.println("true");
    //x_inc = -1*ballS;
}

当使用代码时,游戏简单冻结。当评论出游戏运行良好时。

有什么想法吗?我是否以正确的方式使用正确的方法?使用相交会更好吗?

由于

编辑:似乎涉及.getBounds2D();导致游戏崩溃。有什么想法吗?

EDIT2:添加所有代码完全不需要的部分

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.*;
import javax.swing.JFrame;
import javax.swing.JPanel;

/*
 * Note If you change S (Speed) collision detection will be more complex
 *      as the ball edge may be within the bat.
 *      Ignores concurrency issues (x,y access)
 */

class Main
{
    public static void main( String args[] ) //
    {                                        //
        System.out.println("Application");
        Application app = new Application();
        app.setVisible(true);
        app.run();
    }                                        //
}

class Application extends JFrame            // So graphical
{
    private static final int H = 600;         // Height of window
    private static final int W = 800;         // Width  of window

    public Application()
    {
        setSize( W, H );                        // Size of application
        addKeyListener( new Transaction() );    // Called when key press
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void update( Graphics g )          // Called by repaint
    {                                         //
        drawPicture( (Graphics2D) g );          // Draw Picture
    }

    public void paint( Graphics g )           // When 'Window' is first
    {                                         //  shown or damaged
        drawPicture( (Graphics2D) g );          // Draw Picture
    }

    private Dimension     theAD;              // Alternate Dimension
    private BufferedImage theAI;              // Alternate Image
    private Graphics2D    theAG;              // Alternate Graphics

    public void drawPicture( Graphics2D g )   // Double buffer
    {                                         //  allow re-size
        Dimension d    = getSize();             // Size of curr. image

        if (  ( theAG == null )  ||
        ( d.width  != theAD.width ) ||
        ( d.height != theAD.height ) )
        {                                       // New size
            theAD = d;
            theAI = (BufferedImage) createImage( d.width, d.height );
            theAG = theAI.createGraphics();
            AffineTransform at = new AffineTransform();
            at.setToIdentity();
            at.scale( ((double)d.width)/W, ((double)d.height)/H );
            theAG.transform(at);
        }

        drawActualPicture( theAG );             // Draw Actual Picture
        g.drawImage( theAI, 0, 0, this );       //  Display on screen
    }

    // The ball position and how to increment to next position
    private int x = W/2, x_inc = 1;
    private int y = H/2, y_inc = 1;

    // The bat position and how to increment to next position
    private int playerX = 60;
    private int playerY = PH/2, playerY_inc = 1;

    double count = 0.00;

    // Called on key press 

    class Transaction implements KeyListener  // When character typed
    {
        public void keyPressed(KeyEvent e)      // Obey this method
        {
            // Key typed includes specials
            switch ( e.getKeyCode() )              // Character is
            {
                /*
                case KeyEvent.VK_LEFT:               // Left Arrow
                x_inc = -1;
                break;
                case KeyEvent.VK_RIGHT:              // Right arrow
                x_inc = 1;
                break;
                 */
                case KeyEvent.VK_UP:                 // Up arrow
                playerY_inc = -1;
                break;
                case KeyEvent.VK_DOWN:               // Down arrow
                playerY_inc = 1;
                break;
            }
            // x,y could send to a server instead of calling 
            repaint();                            // Call update method
        }

        public void keyReleased(KeyEvent e)
        {
            switch ( e.getKeyCode() )              // Character is
            {  
                /*
                case KeyEvent.VK_UP:                 // Up arrow
                playerY_inc = playerY_inc;
                break;
                case KeyEvent.VK_DOWN:               // Down arrow
                playerY_inc = playerY_inc;
                break;
                 */
            }
        }

        public void keyTyped(KeyEvent e)
        {
            // Normal key typed
            char c = e.getKeyChar();              // Typed
            repaint();                            // Redraw screen
        }
    }

    private static final int B = 6;           // Border offset
    private static final int M = 26;          // Menu offset
    private static final int BALL_SIZE = 10;  // Ball diameter
    private static final int HALF_BALL_SIZE = BALL_SIZE/2;

    //Players Bat
    private static final int PW = 20;
    private static final int PH = 100;
    private static final int HALF_PLAYER = PH/2;

    // Code called to draw the current state of the game
    Rectangle2D.Double player;
    Ellipse2D.Double ball;
    public void drawActualPicture( Graphics2D g )
    {
        // White background
        g.setPaint( Color.white );
        g.fill( new Rectangle2D.Double( 0, 0, W, H ) );

        Font font = new Font("Monospaced",Font.PLAIN,24); 
        g.setFont( font ); 

        // Blue playing border
        g.setPaint( Color.blue );              // Paint Colour
        g.draw( new Rectangle2D.Double( B, M, W-B*2, H-M-B ) );

        // Players Bat

        g.setPaint( Color.green );              // Paint Colour
        player = new Rectangle2D.Double( playerX, playerY, PW, PH );
        g.fill(player);

        // Display state of game
        g.setPaint( Color.blue );
        FontMetrics fm = getFontMetrics( font );

        String fmt = "Score/ Time lasted = %3f";
        String text = String.format( fmt, count );
        g.drawString( text, W/2-fm.stringWidth(text)/2, M*2 );

        // The ball at the current x, y position (width, height)
        g.setPaint( Color.red );
        ball = new Ellipse2D.Double( x-HALF_BALL_SIZE, y-HALF_BALL_SIZE, BALL_SIZE, BALL_SIZE );
        g.fill( ball );
    }

    // Main program loop

    public void run()
    {
        int ballS = 1;                    // Speed 1 - 5
        int playerS = 1;
        try
        {
            while ( true )
            {
                count = count + 0.015;
                //Ball hitting walls
                //Right wall
                if ( x >= W-B-HALF_BALL_SIZE )
                {
                    x_inc = -1*ballS;
                }
                //Left wall
                if ( x <= 0+B+HALF_BALL_SIZE )
                {
                    count = count;
                    break;
                }
                //Bottom Wall
                if ( y >= H-B-HALF_BALL_SIZE )
                {
                    y_inc = -1*ballS;
                }
                //Top Wall
                if ( y <= 0+M+HALF_BALL_SIZE )
                {
                    y_inc = 1*ballS;
                }
                //Player Hiting Wall
                //Bottom Wall
                if ( playerY >= H-B-100 )
                {
                    playerY_inc = -1*playerS;
                }
                //Top Wall
                if ( playerY <= 0+M )
                {
                    playerY_inc = 1*playerS;
                }
                //Player
                Rectangle2D ballB = ball.getBounds2D();

                if ( ball.getBounds2D().intersects(player.getBounds2D() ))
                {
                    System.out.println("true");
                    //x_inc = -1*ballS;
                }

                //Wall

                x += x_inc;
                y += y_inc;

                playerY += playerY_inc;

                repaint();                      // Now display

                Thread.sleep( 10 );             // 100 Hz
            }
        } catch ( Exception e ) {};
    }
}

编辑:解决了它,我使用数学和x-y坐标来计算它是否在另一个形状内。谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

 ball.getBounds2D() == player.getBounds2D()

是参考检查,因为它们是对象;不是原始人。您正在检查两个游戏对象返回的Rectangle2D是否相同(它们不是)。

要检查Rectangle2D对象是否与另一个Rectangle2D对象相交,您应该这样做:

ball.getBounds2D().intersects(player.getBounds2D())