当前位置: 首页 > 知识库问答 >
问题:

Java:如何检测矩形与半径和速度变化的下落圆之间的碰撞?

裴建华
2023-03-14

首先,我用Java制作了一个简单的游戏,其中包括一个蓝色矩形,可以用箭头键和七个不同颜色、半径和下落速度的下落圆圈来移动。本质上,每当矩形与这些圆中的一个接触时,矩形将“失去”生命,这将由我尚未绘制的JFrame右上方的3个矩形指示。每当矩形被这些圆中的一个击中时,其中一个矩形将消失,当蓝色矩形再次被击中时,帧中间将出现一个红色的“游戏结束”文本。

现在,虽然我很难得到颜色和速度,以随机的每一次圆触及底部,我将把这些留到一个未来的问题。我主要关心的是圆圈和蓝色矩形之间的命中检测。我知道我需要定义一个特定的方法,但我不确定如何去做,以及如何在七个圆圈下降和Y值不断变化的情况下,一遍又一遍地测试它。

我怎么能这样做呢?不管怎样,这是我这个项目的主要课程和圆圈课程。我知道有很多垃圾代码没有在主类中使用。我弄清楚后再清理。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.Random;


public class Keyexample extends JPanel implements ActionListener, KeyListener{
    Timer t = new Timer(5, this);
    private Circle[] Circles = new Circle[7];
    private javax.swing.Timer t2; 
    private Circle newc, c1, c2, c3, c4, c5, c6, c7;
    double x = 100, y = 100;
        double changeX = 0, changeY = 0;
    private int cx = 10, cy = 0;
    private int newcx = 0, newcy = 0;
    private Random rand = new Random();
    private Random colorc = new Random();
    private int n = rand.nextInt(8);


public keyExample() {
    t.start();
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
    Random colorc = new Random();
    Random radiusc = new Random();

    int r1 = radiusc.nextInt(12);
    int r2 = radiusc.nextInt(12);
    int r3 = radiusc.nextInt(12);
    int r4 = radiusc.nextInt(12);
    int r5 = radiusc.nextInt(12);
    int r6 = radiusc.nextInt(12);
    int r7 = radiusc.nextInt(12);
    Color cc1 = new Color(colorc.nextInt(255), colorc.nextInt(255),                
        colorc.nextInt(255));
    Color cc2 = new Color(colorc.nextInt(255), colorc.nextInt(255),                                                
        colorc.nextInt(255));
Color cc3 = new Color(colorc.nextInt(255), colorc.nextInt(255),
    colorc.nextInt(255));
Color cc4 = new Color(colorc.nextInt(255), colorc.nextInt(255),
    colorc.nextInt(255));
Color cc5 = new Color(colorc.nextInt(255), colorc.nextInt(255),
    colorc.nextInt(255));
Color cc6 = new Color(colorc.nextInt(255), colorc.nextInt(255),
    colorc.nextInt(255));
Color cc7 = new Color(colorc.nextInt(255), colorc.nextInt(255),
    colorc.nextInt(255));
    //creating the 7 circles and spacing them out
    c1 = new Circle(cx, cy, r1, cc1);
    c2 = new Circle(cx + 50, cy, r2, cc2);
    c3 = new Circle(cx + 100, cy, r3, cc3);
    c4 = new Circle(cx + 150, cy, r4, cc4);
    c5 = new Circle(cx + 200, cy, r5, cc5);
    c6 = new Circle(cx + 300, cy, r6, cc6);
    c7 = new Circle(cx + 400, cy, r7, cc7);

    Circles[0] = c1;
    Circles[1] = c2;
    Circles[2] = c3;
    Circles[3] = c4;
    Circles[4] = c5;
    Circles[5] = c6;
    Circles[6] = c7;

    t2 = new javax.swing.Timer(33, new CircleListener());
    t2.start();
}
//painting rectangle and circles
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.setColor(Color.BLUE);
    g2.fill(new Rectangle2D.Double(x, y, 40, 40));
        for (int i = 0; i < Circles.length; i++){
        Color circlecolor = new Color(rand.nextInt(255), rand.nextInt(255),    
            rand.nextInt(255));
    //circle color starts spazzing out here. constantly changing while falling
            g2.setColor(circlecolor);
    Circles[i].fill(g);
}
}


    public void createCircle(){
}

    public void actionPerformed(ActionEvent e) {
  repaint();
  x += changeX;
  y += changeY;
  changeX = 0;
  changeY = 0;
}

private class CircleListener implements ActionListener {

public void actionPerformed(ActionEvent e) {
        Random rand = new Random();
        int move = 2 + rand.nextInt(10);
        int move2 =2 + rand.nextInt(10);
        int move3 =2 + rand.nextInt(10);
        int move4 =2 + rand.nextInt(10);
        int move5 =2 + rand.nextInt(10);
        int move6 =2 + rand.nextInt(10);

        c1.move(0, n);
        position(c1);
        c2.move(0, move);
        position(c2);
        c3.move(0, move2);
        position(c3);
        c4.move(0, move3);
        position(c4);
        c5.move(0, move4);
        position(c5);
        c6.move(0, move5);
        position(c6);
        c7.move(0, move6);
        position(c7);
        repaint();
}
public void position(Circle cp) {
    int height = getHeight();
    int loc = cp.centerX;
    int speed = 3 + rand.nextInt(10);
    int radiuss = cp.radius;
    Rectangle bound = cp.Bounds();  
    if (bound.topY + bound.width > height){
        cp.centerY = 0;
                    //moving circle back to the top
        cp.move(0, speed);
                    //randomizing speed of circle after moving to top, not working
        cp.radius = 5 + rand.nextInt(20);
                    //randomizing radius of circle after moving to top, does work

    }
}
}


     public void up() {
        if (y != 0){
        changeY = -3.5;
        changeX = 0;
      }
}
     public void down() {
        if (y <= 350) {
        changeY = 3.5;
        changeX = 0;
       }
}
     public void left() {
       if (x >=0) {
       changeX = -3.5;
       changeY = 0;
       }
}
     public void right() {
       if (x <= 550) {
       changeX = 3.5;
       changeY = 0;
      }
}
     public void keyPressed(KeyEvent e) {
       int code = e.getKeyCode();
       if (code == KeyEvent.VK_UP) {
       up();
  }
     if (code == KeyEvent.VK_DOWN) {
     down();
  }
     if (code == KeyEvent.VK_RIGHT) {
     right();
  }
     if (code == KeyEvent.VK_LEFT) {
     left();
     }
}

     public void keyTyped(KeyEvent e) {
}
 public void keyReleased(KeyEvent e) {
    }
}

**圆圈类

 import java.awt.*;
 import java.util.Random;

 public class Circle{

public int centerX, centerY, radius;
public Color color;

public Circle (int x, int y, int r, Color c){
    centerX = x;
    centerY = y;
    radius = r;
Random random = new Random();

}

public void draw(Graphics g){
    Color oldColor = g.getColor();
    g.setColor(color);
    g.drawOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
    g.setColor(oldColor);
}
public void fill(Graphics g){
    Color oldColor = g.getColor();
    g.setColor(color);
    g.fillOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
    g.setColor(oldColor);   
}
public boolean containsPoint(int x, int y){
    int xSquared = (x - centerX) * (x - centerX);
    int ySquared = (y - centerY) * (y - centerY);
    int radiusSquared = radius * radius;
    return xSquared + ySquared - radiusSquared <=0;
}
public void move(int xAmount, int yAmount){
    centerX = centerX + xAmount;
    centerY = centerY + yAmount;
}
public Rectangle Bounds(){
    int x = centerX - radius;
    int y = centerY - radius;

return new Rectangle(x, y, radius * 2, radius * 2, Color.red);

    }
}

共有1个答案

闾丘正志
2023-03-14

你可以通过屏幕上圆和矩形坐标上的简单if else条件来检测碰撞。距离(圆,矩形)<=圆。半径+矩形。半径

您可以使用两点之间的简单距离公式实现距离帮助器函数。

链接

 类似资料:
  • 我正在编写一个游戏,涉及碰撞的一个移动的圆,由用户控制,和一个移动的矩形,由计算机控制。 完整的代码可以在这里找到:游戏 我在圆和矩形之间的碰撞检测方面遇到了麻烦。当矩形是静态的,碰撞检测工作完美。当圆和矩形的边缘在任一边接触时,程序就会按照它应该的方式进行操作。 这是碰撞检测功能。 谢谢。

  • 在我的自上而下游戏中,当我的玩家通过婴儿床时,我该如何让他发生碰撞?我用的是交叉矩形。 这是我的密码 更新方法 在渲染方法中 这是完整的代码 谁能告诉我矩形碰撞检测的正确实现是什么?没有重叠,我是这个框架的新手。致谢和预付款:)

  • 我有一个问题,碰撞检测一个圆和一个矩形。我曾尝试用勾股定理来解决这个问题。但所有查询都不起作用。矩形与圆的矩形包围盒发生碰撞。

  • 问候SOCommunity, 现在我正在尝试学习形状之间的碰撞检测。检测本身工作良好。但物体的重新定位并不完全有效。 所以每当我的圆碰到矩形的角时,重新定位就不起作用了。 这是我的代码: 请帮助我找出为什么这不起作用,以及我如何让它起作用。 提前感谢:)

  • 我花了数小时寻找解决方案:我正在用libgdx开发一个自上而下的小游戏(可能这与我使用的引擎有关)。现在我必须在我的角色(圆形)和墙(矩形)之间实现碰撞检测。如果可以滑动,我希望角色在碰撞时沿着墙滑动。让我解释一下: 如果我向上移动45度,我可能会撞到墙的下面、左边或角落。 如果我与左边相撞,我想停止x运动,只向上移动。如果我离开墙壁,那么我想继续向上移动。与下侧相同(停止y运动) 如果我与角落相

  • 我已经在这里呆了2-3周了,我仍然无法进行适当的碰撞检测。我用矩形创建了一个迷宫。我希望我的对象(在矩形中)每当我的对象与任何墙壁碰撞时停止,并能够移动到任何地方(或滑下墙壁)。我的墙壁(矩形)具有负坐标,如下所示: 我目前正在使用SO中发现的重叠方法。以下是我的CollisionManager类中的方法: 我有一个功能可以保存对象所做的所有位置移动。因此,当发生碰撞时,对象会恢复到最后一次移动之