2008-12-02 120 views
11

我有两个字符显示在我正在写的游戏中,玩家和敌人。这样定义:Java中两个图像之间的碰撞检测

public void player(Graphics g) { 
    g.drawImage(plimg, x, y, this); 
} 

public void enemy(Graphics g) { 
    g.drawImage(enemy, 200, 200, this); 
} 

然后调用:

player(g); 
enemy(g); 

我能够移动播放器()与周围的键盘,但我很茫然试图检测两者之间的冲突时。很多人都说过要使用矩形,但是作为初学者,我看不出如何将其链接到我现有的代码中。任何人都可以为我提供一些建议吗?

回答

18

我认为你的问题在于你没有为你的玩家和敌人使用好的OO设计。创建两个类:

public class Player 
{ 
    int X; 
    int Y; 
    int Width; 
    int Height; 

    // Getters and Setters 
} 

public class Enemy 
{ 
    int X; 
    int Y; 
    int Width; 
    int Height; 

    // Getters and Setters 
} 

您的玩家应该有X,Y,宽度和高度变量。

你的敌人也应该如此。

在你的游戏循环,这样做(C#):

foreach (Enemy e in EnemyCollection) 
{ 
    Rectangle r = new Rectangle(e.X,e.Y,e.Width,e.Height); 
    Rectangle p = new Rectangle(player.X,player.Y,player.Width,player.Height); 

    // Assuming there is an intersect method, otherwise just handcompare the values 
    if (r.Intersects(p)) 
    { 
     // A Collision! 
     // we know which enemy (e), so we can call e.DoCollision(); 
     e.DoCollision(); 
    } 
} 

为了加快速度,不要打扰,如果敌人COORDS是屏幕外检查。

2

使用矩形围住每个玩家和敌人,矩形的高度和宽度应与您周围的物体相对应,想象它只在一个足够大的盒子中。

现在,您将这些矩形一样的,你做的对象,所以他们有一个“边框”

我不知道,如果Java有这一点,但它可能具有矩形对象的方法叫做.intersects()所以你应该这样做(rectangle1.intersectS(rectangle2)来检查一个对象是否与另一个对象发生冲突。

否则你可以得到x和y坐标的框和使用它们的高度/宽度检测它们是否已经与你自己相交

无论如何,你可以用它来做交叉事件(make on爆炸或其他)或阻止运动被吸引。 (恢复到以前的坐标)

编辑:在这里我们去

布尔

相交(矩形R) 确定此Rectangle与指定 Rectangle是否相交。

所以我会做(不粘贴此代码,它最有可能将无法正常工作,没有做Java的很长一段时间,当我没有使用它,我没有做图形。)

Rectangle rect1 = new Rectangle(player.x, player.y, player.width, player.height); 

Rectangle rect2 = new Rectangle(enemy.x, enemy.y, enemy.width, enemy.height); 

//detects when the two rectangles hit 
if(rect1.intersects(rect2)) 
{ 

System.out.println("game over, g"); 
} 

显然你需要适应在某个地方。

+0

这是我在获得。 Java确实有交集,但我正努力将它应用到我已有的代码中。我需要在player()和enemy()里面定义矩形吗? – 2008-12-02 22:24:14

+0

不。我以前没有在java中使用绘画的东西,但是你应该明确地拥有一个像“Creature”这样的对象,然后创建Creature的实例,即玩家/敌人,或者让它们成为你创建实例的子类。创建对象应包含更新/绘制所需的所有内容NoCharsLeft – Tablet 2008-12-02 22:31:06

2

您不希望在绘画代码中使用碰撞检查代码。这幅画需要很快。碰撞可以进入游戏循环。因此,您需要独立于其精灵的对象的内部表示。

2

由于Java没有交叉函数(真的!),所以可以通过简单地比较每个可能潜在对象的边界框(矩形)的X和Y值,宽度和高度值碰撞。

因此......在每个碰撞对象的基础对象中...即,如果你的玩家和敌人有一个共同的基础,你可以把一个简单的Rectangle对象叫做BoundingBox。如果公共基础是一个内置的Java类,那么您需要创建一个类来扩展该类的构建,让玩家和敌方对象扩展您的新类或者是该类的实例。

在创建(以及每个打勾或更新)时,您需要为玩家和敌人设置边界框参数。我没有面向我的Rectangle类,但它最有可能是X,Y,Width和Height。 X和Y是你游戏世界中的物体位置。我认为宽度和高度是自我解释的。尽管如此,他们很可能会从玩家位置的右侧出来,如果X和Y在0处,而你的宽度和高度都是256,那么你不会看到任何东西,因为角色会位于左上角在屏幕外面。

反正......为了检测碰撞,你需要比较玩家和敌方的BoundingBoxes的属性。因此,像这样......

if(Player.BoundingBox.X = Enemy.BoundingBox.X && If(Player.BoundingBox.Y = Enemy.BoundingBox.Y) 
{ 
     //Oh noes! The enemy and player are on top of eachother. 
} 

逻辑可以得到某种复杂,但你需要比较每个BoundingBox的之间的距离和比较的位置。

+2

Java确实有一个相交方法:http://java.sun.com/javase/6/docs/api/java/awt/Rectangle.html#intersects(java .awt.Rectangle)。 – 2008-12-02 23:04:19

5

首先,使用Jonathan Holland所述的边界框来查找是否可能发生碰撞。

从(多色)精灵创建黑白版本。如果你的精灵是透明的,你可能已经拥有了这些东西(例如,有些地方在边界框内,但你仍然可以看到背景)。这些是“面具”。

在掩模上使用Image.getRGB()以获得像素。对于不透明的每个像素,请在整数阵列中设置一个位(下面的playerArrayenemyArray)。如果width <= 32像素,则阵列的大小为height,否则为(width+31)/32*height。以下代码适用于width <= 32

如果你有边框的碰撞,这样做:

// Find the first line where the two sprites might overlap 
int linePlayer, lineEnemy; 
if (player.y <= enemy.y) { 
    linePlayer = enemy.y - player.y; 
    lineEnemy = 0; 
} else { 
    linePlayer = 0; 
    lineEnemy = player.y - enemy.y; 
} 
int line = Math.max(linePlayer, lineEnemy); 

// Get the shift between the two 
x = player.x - enemy.x; 
int maxLines = Math.max(player.height, enemy.height); 
for (line < maxLines; line ++) { 
    // if width > 32, then you need a second loop here 
    long playerMask = playerArray[linePlayer]; 
    long enemyMask = enemyArray[lineEnemy]; 
    // Reproduce the shift between the two sprites 
    if (x < 0) playerMask << (-x); 
    else enemyMask << x; 
    // If the two masks have common bits, binary AND will return != 0 
    if ((playerMask & enemyMask) != 0) { 
     // Contact! 
    } 

} 

链接:JGameFramework for Small Java Games

3

下面是从我的碰撞检测程序的主类。
你可以看到它在运行:http://www.youtube.com/watch?v=JIXhCvXgjsQ

/** 
* 
* @author Tyler Griffin 
*/ 
import java.awt.*; 
import javax.swing.*; 
import java.awt.event.*; 
import java.awt.GraphicsDevice.*; 
import java.util.ArrayList; 
import java.awt.Graphics; 
import java.awt.geom.Line2D; 


public class collision extends JFrame implements KeyListener, MouseMotionListener, MouseListener 
{ 
    ArrayList everything=new ArrayList<tile>(); 

    int time=0, x, y, width, height, up=0, down=0, left=0, right=0, mouse1=0, mouse2=0; 
    int mouseX, mouseY; 

    GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    GraphicsDevice screen = environment.getDefaultScreenDevice(); 
    DisplayMode displayMode = screen.getDisplayMode(); 

    //private BufferStrategy strategy; 

    JLayeredPane pane = new JLayeredPane(); 

    tile Tile; 
    circle Circle; 
    rectangle Rectangle; 

     textPane text; 

    public collision() 
    { 
     setUndecorated(screen.isFullScreenSupported()); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setVisible(true); 
     setLayout(null); 
     setResizable(false); 
     screen.setFullScreenWindow(this); 


     width=displayMode.getWidth(); 
     height=displayMode.getHeight(); 


      Circle=new circle(-(int)Math.round((double)height/7*2),-(int)Math.round((double)height/7*2),(int)Math.round((double)height/7*.85),this); 
      Rectangle=new rectangle(-(int)Math.round((double)height/7*1.5),-(int)Math.round((double)height/7*1.5),(int)Math.round((double)height/7*1.5),(int)Math.round((double)height/7*1.5),this); 
      Tile=Circle; 
      Tile.move(mouseX-Tile.width/2, mouseY-Tile.height/2); 
        text=new textPane(0,0,width,height,this); 

      everything.add(new circle((int)Math.round((double)width/100*75),(int)Math.round((double)height/100*15),(int)Math.round((double)width/100*10),this)); 
        everything.add(new rectangle((int)Math.round((double)width/100*70),(int)Math.round((double)height/100*60),(int)Math.round((double)width/100*20),(int)Math.round((double)height/100*20),this)); 
        //everything.add(new line(750,250,750,750,this)); 
        /*everything.add(new line(width/700*419,height/700*68,width/700*495,height/700*345,this)); 
        everything.add(new line(width/700*495,height/700*345,width/700*749,height/700*350,this)); 
        everything.add(new line(width/700*749,height/700*350,width/700*549,height/700*519,this)); 
        everything.add(new line(width/700*549,height/700*519,width/700*624,height/700*800,this)); 
        everything.add(new line(width/700*624,height/700*800,width/700*419,height/700*638,this)); 
        everything.add(new line(width/700*419,height/700*638,width/700*203,height/700*800,this)); 
        everything.add(new line(width/700*203,height/700*800,width/700*279,height/700*519,this)); 
        everything.add(new line(width/700*279,height/700*519,width/700*76,height/700*350,this)); 
        everything.add(new line(width/700*76,height/700*350,width/700*333,height/700*345,this)); 
        everything.add(new line(width/700*333,height/700*345,width/700*419,height/700*68,this)); 

        everything.add(new line(width/950*419,height/700*68,width/950*624,height/700*800,this)); 
        everything.add(new line(width/950*419,height/700*68,width/950*203,height/700*800,this)); 
        everything.add(new line(width/950*76,height/700*350,width/950*624,height/700*800,this)); 
        everything.add(new line(width/950*203,height/700*800,width/950*749,height/700*350,this)); 
        everything.add(new rectangle(width/950*76,height/700*350,width/950*673,1,this));*/ 

        everything.add(new line((int)Math.round((double)width/1350*419),(int)Math.round((double)height/1000*68),(int)Math.round((double)width/1350*624),(int)Math.round((double)height/1000*800),this)); 
        everything.add(new line((int)Math.round((double)width/1350*419),(int)Math.round((double)height/1000*68),(int)Math.round((double)width/1350*203),(int)Math.round((double)height/1000*800),this)); 
        everything.add(new line((int)Math.round((double)width/1350*76),(int)Math.round((double)height/1000*350),(int)Math.round((double)width/1350*624),(int)Math.round((double)height/1000*800),this)); 
        everything.add(new line((int)Math.round((double)width/1350*203),(int)Math.round((double)height/1000*800),(int)Math.round((double)width/1350*749),(int)Math.round((double)height/1000*350),this)); 
        everything.add(new rectangle((int)Math.round((double)width/1350*76),(int)Math.round((double)height/1000*350),(int)Math.round((double)width/1350*673),1,this)); 


     addKeyListener(this); 
     addMouseMotionListener(this); 
     addMouseListener(this); 
    } 

    public void keyReleased(KeyEvent e) 
    { 
     Object source=e.getSource(); 

     int released=e.getKeyCode(); 

     if (released==KeyEvent.VK_A){left=0;} 
     if (released==KeyEvent.VK_W){up=0;} 
     if (released==KeyEvent.VK_D){right=0;} 
     if (released==KeyEvent.VK_S){down=0;} 
    }//end keyReleased 


    public void keyPressed(KeyEvent e) 
    { 
     Object source=e.getSource(); 

     int pressed=e.getKeyCode(); 

     if (pressed==KeyEvent.VK_A){left=1;} 
     if (pressed==KeyEvent.VK_W){up=1;} 
     if (pressed==KeyEvent.VK_D){right=1;} 
     if (pressed==KeyEvent.VK_S){down=1;} 

     if (pressed==KeyEvent.VK_PAUSE&&pressed==KeyEvent.VK_P) 
     { 
      //if (paused==0){paused=1;} 
      //else paused=0; 
     } 
    }//end keyPressed 

    public void keyTyped(KeyEvent e){} 

//*********************************************************************************************** 

    public void mouseDragged(MouseEvent e) 
    { 
     mouseX=(e.getX()); 
     mouseY=(e.getY()); 

      //run(); 
    } 

    public void mouseMoved(MouseEvent e) 
    { 
     mouseX=(e.getX()); 
     mouseY=(e.getY()); 

      //run(); 
    } 

//*********************************************************************************************** 

    public void mousePressed(MouseEvent e) 
    { 
     if(e.getX()==0 && e.getY()==0){System.exit(0);} 

    mouseX=(e.getX()+x); 
     mouseY=(e.getY()+y); 

     if(Tile instanceof circle) 
     { 
       Circle.move(0-Circle.width, 0-Circle.height); 
       Circle.setBounds(Circle.x, Circle.y, Circle.width, Circle.height); 
       Tile=Rectangle; 
     } 
     else 
     { 
       Rectangle.move(0-Rectangle.width, 0-Rectangle.height); 
       Rectangle.setBounds(Rectangle.x, Rectangle.y, Rectangle.width, Rectangle.height); 
       Tile=Circle; 
     } 

     Tile.move(mouseX-Tile.width/2, mouseY-Tile.height/2); 
    } 

    public void mouseReleased(MouseEvent e) 
    { 
     //run(); 
    } 

    public void mouseEntered(MouseEvent e){} 
    public void mouseExited(MouseEvent e){} 

    public void mouseClicked(MouseEvent e){} 

//*********************************************************************************************** 

    public void run()//run collision detection 
    { 
     while (this == this) 
     { 
      Tile.move(Tile.x + ((mouseX - (Tile.x + (Tile.width/2)))/10), Tile.y + ((mouseY - (Tile.y + (Tile.height/2)))/10)); 
      //Tile.move((mouseX - Tile.width/2), mouseY - (Tile.height/2)); 

      for (int i = 0; i < everything.size(); i++) 
      { 
       tile Temp = (tile) everything.get(i); 

       if (Temp.x < (Tile.x + Tile.width) && (Temp.x + Temp.width) > Tile.x && Temp.y < (Tile.y + Tile.height) && (Temp.y + Temp.height) > Tile.y)//rectangles collided 
       { 
        if (Temp instanceof rectangle) 
        { 
         if (Tile instanceof rectangle){rectangleRectangle(Temp);} 
         else {circleRectangle(Temp);}//Tile instanceof circle 
        } 
        else 
        { 
         if (Temp instanceof circle) 
         { 
          if (Tile instanceof rectangle) {rectangleCircle(Temp);} 
          else {circleCircle(Temp);} 
         } 
         else//line 
         { 
          if (Tile instanceof rectangle){rectangleLine(Temp);} 
          else{circleLine(Temp);} 
         } 
        } 
       }//end if 
      }//end for 

      try {Thread.sleep(16L);} 
      catch (Exception e) {} 

      Tile.setBounds(Tile.x, Tile.y, Tile.width, Tile.height); 
      //Rectangle.setBounds(x, y, width, height); 
      //Circle.setBounds(x, y, width, height); 
      repaint(); 

      text.out=" "; 
     }//end while loop 
    }//end run 

//***************************************special collision detection/handling functions************************************************ 

    void rectangleRectangle(tile Temp) 
    { 
     int lapTop, lapBot, lapLeft, lapRight, small, scootX=0, scootY=0; 

     lapTop=(Temp.y+Temp.height)-Tile.y; 
     lapBot=(Tile.y+Tile.height)-Temp.y; 
     lapLeft=(Temp.x+Temp.width)-Tile.x; 
     lapRight=(Tile.x+Tile.width)-Temp.x; 

     small=999999999; 

     if (lapTop<small){small=lapTop; scootX=0; scootY=lapTop;} 
     if (lapBot<small){small=lapBot; scootX=0; scootY=lapBot*-1;} 
       if (lapLeft<small){small=lapLeft; scootX=lapLeft; scootY=0;} 
       if (lapRight<small){small=lapRight; scootX=lapRight*-1; scootY=0;} 

     Tile.move(Tile.x+scootX, Tile.y+scootY);text.out="collision detected!"; 
    } 



    void circleRectangle(tile Temp) 
    { 
     if((Tile.x+Tile.width/2<=Temp.x+Temp.width && Tile.x+Tile.width/2>=Temp.x)||(Tile.y+Tile.height/2>=Temp.y && Tile.y+Tile.height/2<=Temp.y+Temp.height)) 
     { 
      rectangleRectangle(Temp); 
     } 
     else//push from nearest corner 
     { 
      int x,y; 
      if(Tile.x+Tile.width/2>Temp.x+Temp.width && Tile.y+Tile.height/2<Temp.y){x=Temp.x+Temp.width; y=Temp.y;} 
      else if(Tile.x+Tile.width/2<Temp.x && Tile.y+Tile.height/2<Temp.y){x=Temp.x; y=Temp.y;} 
      else if(Tile.x+Tile.width/2>Temp.x+Temp.width && Tile.y+Tile.height/2>Temp.y+Temp.height){x=Temp.x+Temp.width; y=Temp.y+Temp.height;} 
      else {x=Temp.x; y=Temp.y+Temp.height;} 

      double distance = Math.sqrt(Math.pow(Tile.x+(Tile.width/2) - x, 2) + Math.pow(Tile.y+(Tile.height/2) - y, 2)); 

      if((int)Math.round(distance)<Tile.height/2) 
      { 
          double normY = ((Tile.y+(Tile.height/2) - y)/distance); 
          double normX = ((Tile.x+(Tile.width/2) - x)/distance); 

          Tile.move(x-Tile.width/2+(int)Math.round(normX*((Tile.width/2))) , y-Tile.height/2+(int)Math.round(normY*((Tile.height/2))));text.out="collision detected!"; 
      } 
     } 
    } 



    void rectangleCircle(tile Temp) 
    { 
     if((Temp.x+Temp.width/2<=Tile.x+Tile.width && Temp.x+Temp.width/2>=Tile.x)||(Temp.y+Temp.height/2>=Tile.y && Temp.y+Temp.height/2<=Tile.y+Tile.height)) 
     { 
      rectangleRectangle(Temp); 
     } 
     else//push from nearest corner 
     { 
      int x,y; 
      if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2<Tile.y){x=Tile.x+Tile.width; y=Tile.y;} 
      else if(Temp.x+Temp.width/2<Tile.x && Temp.y+Temp.height/2<Tile.y){x=Tile.x; y=Tile.y;} 
      else if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2>Tile.y+Tile.height){x=Tile.x+Tile.width; y=Tile.y+Tile.height;} 
      else {x=Tile.x; y=Tile.y+Tile.height;} 

      double distance = Math.sqrt(Math.pow(Temp.x+(Temp.width/2) - x, 2) + Math.pow(Temp.y+(Temp.height/2) - y, 2)); 

      if((int)Math.round(distance)<Temp.height/2) 
      { 
      double normY = ((Temp.y+(Temp.height/2) - y)/distance); 
      double normX = ((Temp.x+(Temp.width/2) - x)/distance); 

      if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2<Tile.y){Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2)))-Tile.width,(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2))));text.out="collision detected!";} 
       else if(Temp.x+Temp.width/2<Tile.x && Temp.y+Temp.height/2<Tile.y){Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2))),(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2))));text.out="collision detected!";} 
       else if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2>Tile.y+Tile.height){Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2)))-Tile.width,(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2)))-Tile.height);text.out="collision detected!";} 
       else {Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2))),(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2)))-Tile.height);text.out="collision detected!";} 
      } 
     } 
    } 




    void circleCircle(tile Temp) 
    { 
     double distance = Math.sqrt(Math.pow((Tile.x+(Tile.width/2)) - (Temp.x+(Temp.width/2)),2) + Math.pow((Tile.y+(Tile.height/2)) - (Temp.y+(Temp.height/2)), 2)); 

     if((int)distance<(Tile.width/2+Temp.width/2)) 
     { 
         double normX = ((Tile.x+(Tile.width/2)) - (Temp.x+(Temp.width/2)))/distance; 
         double normY = ((Tile.y+(Tile.height/2)) - (Temp.y+(Temp.height/2)))/distance; 

      Tile.move((Temp.x+(Temp.width/2))+(int)Math.round(normX*(Tile.width/2+Temp.width/2))-(Tile.width/2) , (Temp.y+(Temp.height/2))+(int)Math.round(normY*(Tile.height/2+Temp.height/2))-(Tile.height/2));text.out="collision detected!"; 
     } 
    } 



    void circleLine(tile Temp) 
    { 
      line Line=(line)Temp; 

      if (Line.x1 < (Tile.x + Tile.width) && (Line.x1) > Tile.x && Line.y1 < (Tile.y + Tile.height) && Line.y1 > Tile.y)//circle may be hitting one of the end points 
      { 
       rectangle rec=new rectangle(Line.x1, Line.y1, 1, 1, this); 
       circleRectangle(rec); 
       remove(rec); 
      } 

      if (Line.x2 < (Tile.x + Tile.width) && (Line.x2) > Tile.x && Line.y2 < (Tile.y + Tile.height) && Line.y2 > Tile.y)//circle may be hitting one of the end points 
      { 
       rectangle rec=new rectangle(Line.x2, Line.y2, 1, 1, this); 
       circleRectangle(rec); 
       remove(rec); 
      } 


      int x1=0, y1=0, x2=Tile.x+(Tile.width/2), y2=Tile.y+(Tile.height/2); 

      x1=Tile.x+(Tile.width/2)-Line.height;//(int)Math.round(Line.xNorm*1000); 
      x2=Tile.x+(Tile.width/2)+Line.height; 
      if(Line.posSlope) 
      { 
       y1=Tile.y+(Tile.height/2)-Line.width; 
       y2=Tile.y+(Tile.height/2)+Line.width; 
      } 
      else 
      { 
       y1=Tile.y+(Tile.height/2)+Line.width; 
       y2=Tile.y+(Tile.height/2)-Line.width; 
      } 

      Point point=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection 

      if (point.x < (Line.x + Line.width) && point.x > Line.x && point.y < (Line.y + Line.height) && point.y > Line.y)//line intersects within line segment 
      { 
       //if(point!=null){System.out.println(point.x+","+point.y);} 
       double distance = Math.sqrt(Math.pow((Tile.x+(Tile.width/2)) - point.x,2) + Math.pow((Tile.y+(Tile.width/2)) - point.y, 2)); 

       if((int)distance<Tile.width/2) 
       { 
        //System.out.println("hit"); 
        double normX = ((Tile.x+(Tile.width/2)) - point.x)/distance; 
        double normY = ((Tile.y+(Tile.height/2)) - point.y)/distance; 

        Tile.move((point.x)+(int)Math.round(normX*(Tile.width/2))-(Tile.width/2) , (point.y)+(int)Math.round(normY*(Tile.height/2))-(Tile.height/2));text.out="collision detected!"; 
        //System.out.println(point.x+","+point.y); 
       } 
      } 

      //new bullet(this, (int)Math.round(tryX), (int)Math.round(tryY)); 
    } 

     void rectangleLine(tile Temp) 
    { 
      line Line=(line)Temp; 
      if(new Line2D.Double(Line.x1,Line.y1,Line.x2,Line.y2).intersects(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height))) 
      { 
       if (Line.x1 < (Tile.x + Tile.width) && (Line.x1) > Tile.x && Line.y1 < (Tile.y + Tile.height) && Line.y1 > Tile.y)//circle may be hitting one of the end points 
       { 
        rectangle rec=new rectangle(Line.x1, Line.y1, 1, 1, this); 
        rectangleRectangle(rec); 
        remove(rec); 
       } 

       if (Line.x2 < (Tile.x + Tile.width) && (Line.x2) > Tile.x && Line.y2 < (Tile.y + Tile.height) && Line.y2 > Tile.y)//circle may be hitting one of the end points 
       { 
        rectangle rec=new rectangle(Line.x2, Line.y2, 1, 1, this); 
        rectangleRectangle(rec); 
        remove(rec); 
       } 

       if(Line.posSlope)//positive sloped line 
       { 
        //first we'll do the top left corner 
        int x1=Tile.x-Line.height; 
        int x2=Tile.x+Line.height; 
        int y1=Tile.y-Line.width; 
        int y2=Tile.y+Line.width; 
        Point topPoint=new Point(-99,-99), botPoint=new Point(-99,-99); 
        double topDistance=0, botDistance=0; 

        topPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection 

        topDistance = Math.sqrt(Math.pow(Tile.x - topPoint.x,2) + Math.pow(Tile.y - topPoint.y, 2)); 

        //new let's do the bottom right corner 
        x1=Tile.x+Tile.width-Line.height; 
        x2=Tile.x+Tile.width+Line.height; 
        y1=Tile.y+Tile.height-Line.width; 
        y2=Tile.y+Tile.height+Line.width; 

        botPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection 

        botDistance = Math.sqrt(Math.pow((Tile.x+Tile.width) - botPoint.x,2) + Math.pow((Tile.y+Tile.height) - botPoint.y, 2)); 


        if(topDistance<botDistance) 
        { 
         if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(topPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(topPoint)) 
         { 
          Tile.move(topPoint.x,topPoint.y);text.out="collision detected!"; 
         } 
        } 
        else 
        { 
         if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(botPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(botPoint)) 
         { 
          Tile.move(botPoint.x-Tile.width,botPoint.y-Tile.height);text.out="collision detected!"; 
         } 
        } 
       } 
       else//negative sloped lne 
       { 
        //first we'll do the top right corner 
        int x1=Tile.x+Tile.width-Line.height; 
        int x2=Tile.x+Tile.width+Line.height; 
        int y1=Tile.y+Line.width; 
        int y2=Tile.y-Line.width; 
        Point topPoint=new Point(-99,-99), botPoint=new Point(-99,-99); 
        double topDistance=0, botDistance=0; 

        topPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection 

        topDistance = Math.sqrt(Math.pow(Tile.x + Tile.width - topPoint.x,2) + Math.pow(Tile.y - topPoint.y, 2)); 

        //new let's do the bottom left corner 
        x1=Tile.x-Line.height; 
        x2=Tile.x+Line.height; 
        y1=Tile.y+Tile.height+Line.width; 
        y2=Tile.y+Tile.height-Line.width; 

        botPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection 

        botDistance = Math.sqrt(Math.pow(Tile.x - botPoint.x,2) + Math.pow((Tile.y+Tile.height) - botPoint.y, 2)); 


        if(topDistance<botDistance) 
        { 
         if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(topPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(topPoint)) 
         { 
          Tile.move(topPoint.x-Tile.width,topPoint.y);text.out="collision detected!"; 
         } 
        } 
        else 
        { 
         if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(botPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(botPoint)) 
         { 
          Tile.move(botPoint.x,botPoint.y-Tile.height);text.out="collision detected!"; 
         } 
        } 
       } 
      } 
    } 

     public Point intersection(double x1, double y1, double x2, double y2,double x3, double y3, double x4, double y4)//I didn't write this. got it from http://www.ahristov.com/tutorial/geometry-games/intersection-lines.html (I altered it) 
     { 
      double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); 

      double xi = ((x3 - x4) * (x1 * y2 - y1 * x2) - (x1 - x2) * (x3 * y4 - y3 * x4))/d; 
      double yi = ((y3 - y4) * (x1 * y2 - y1 * x2) - (y1 - y2) * (x3 * y4 - y3 * x4))/d; 

      int x=(int)Math.round(xi); 
      int y=(int)Math.round(yi); 

      return new Point(x, y); 
     } 

//*************************************************************************************** 

    public static void main(String[] args) 
    { 
     final collision Collision=new collision(); 
      Collision.run(); 
    }//end main 
}//end class 
2

有一个问题:

Rectangle box1 = new Rectangle(100,100,100,100); 
Rectangle box2 = new Rectangle(200,200,100,100); 

// what this means is if any pixel in box2 enters (hits) box1 
if (box1.contains(box2)) 
{ 
    // collision occurred 
} 

// your code for moving the boxes 


这也可以应用到社交圈:

Ellipse2D.Double ball1 = new Ellipse2D.Double(100,100,200,200); 
Ellipse2D.Double ball2 = new Ellipse2D.Double(400,100,200,200); 

// what this means is if any pixel on the circumference in ball2 touches (hits) 
// ball1 
    if (ball1.contains(ball2)) 
    { 
     // collision occurred 
    } 

    // your code for moving the balls 



检查是否你已打到你可以使用下面的屏幕的边缘:

Rectangle screenBounds = jpanel.getBounds(); 
Ellipse2D.Double ball = new Ellipse2D.Double(100,100,200,200); // diameter 200 
Rectangle ballBounds = ball.getBounds(); 

if (!screenBounds.contains(ballBounds)) 
{ 
// the ball touched the edge of the screen 
} 
1

无需使用矩形......不断比较的2名球员的坐标。

like if(x1===x&&y1==y) 记得在比较的时候增加x的范围。

如果乌拉圭回合矩形宽度为30就拿if (x1>x&&x2>x+30) ..likewiseŸ