2012-03-01 156 views
2

我剛剛開始Java,並且我們被要求產生pong(或其上的扭曲)。我目前正在研究球與球員蝙蝠之間的碰撞。我有這個代碼。Java - getBounds2D,橢圓矩形碰撞

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 COORDS工作,如果它是其他形狀內。感謝幫助。

回答

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

是參考檢查,因爲它們是對象;不是原始的。你正在檢查兩個遊戲對象返回的Rectangle2D是否都是相同的(他們不是)。

要檢查矩形對象相交另一個矩形對象,你應該做的:

ball.getBounds2D().intersects(player.getBounds2D()) 
+0

感謝您的答案,那會是相同的,如果你正在檢查一個橢圓形和矩形?作爲我目前的代碼 'code'if(ball.getBounds2D()。intersects(player.getBounds2D())) { System.out.println(「true」); // x_inc = -1 * ballS; } 'code' 只是導致遊戲停止。 再次感謝 – Kyle93 2012-03-01 11:23:17

+0

我已經編輯了主要問題,包括我剛剛發現的有關程序 – Kyle93 2012-03-01 11:35:05

+0

是的,Ellipse是一個RectangularShape,它定義了'intersects'方法,因此它可以工作。您的凍結問題很可能是由於您尚未發佈的代碼的其他部分。如果可以,發佈更新週期的簡化版本。 – Hedja 2012-03-01 12:11:25