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

复杂形状的碰撞检测

壤驷麒
2023-03-14

我想做一个游戏,有每一个水平加载从一个图像。我想在Photoshop中把整个关卡画出来,然后把它设置为背景并允许玩家走过去。我想要另一个看不见的图像超过顶部,这将是黑色的所有地方,我想要碰撞。

我不想使用瓷砖的原因,这是更容易与矩形碰撞和诸如此类,因为将有复杂的角,并不是所有将是矩形。

这是一个好主意吗?有没有可能轻松做到?这将是一个巨大的CPU拥有者还是有更好的方法做到这一点?

共有1个答案

欧阳安阳
2023-03-14

会有复杂的角,不是所有的东西都是矩形的。

这可以通过绘制和处理shapearea实例来实现。例如。

  • 黄色是一个小动画‘播放器’。
  • 图像的边界表示包含播放机路径的墙壁(它从这些墙壁上弹出)。
  • 障碍物未碰撞时涂成绿色,否则涂成红色。
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

class ShapeCollision {

    private BufferedImage img;
    private Area[] obstacles = new Area[4];
    private Area walls;

    int x; 
    int y;
    int xDelta = 3;
    int yDelta = 2;

    /** A method to determine if two instances of Area intersect */
    public boolean doAreasCollide(Area area1, Area area2) {
        boolean collide = false;

        Area collide1 = new Area(area1);
        collide1.subtract(area2);
        if (!collide1.equals(area1)) {
            collide = true;
        }

        Area collide2 = new Area(area2);
        collide2.subtract(area1);
        if (!collide2.equals(area2)) {
            collide = true;
        }

        return collide;
    }

    ShapeCollision() {
        int w = 400;
        int h = 200;
        img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        final JLabel imageLabel = new JLabel(new ImageIcon(img));
        x = w/2;
        y = h/2;

        //circle 
        obstacles[0] = new Area(new Ellipse2D.Double(40, 40, 30, 30));

        int[] xTriangle = {330,360,345};
        int[] yTriangle = {60,60,40};
        //triangle 
        obstacles[1] = new Area(new Polygon(xTriangle, yTriangle, 3));

        int[] xDiamond = {60,80,60,40};
        int[] yDiamond = {120,140,160,140};
        //diamond 
        obstacles[2] = new Area(new Polygon(xDiamond, yDiamond, 4));

        int[] xOther = {360,340,360,340};
        int[] yOther = {130,110,170,150};
        // other 
        obstacles[3] = new Area(new Polygon(xOther, yOther, 4));

        walls = new Area(new Rectangle(0,0,w,h));

        ActionListener animate = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                animate();
                imageLabel.repaint();
            }
        };
        Timer timer = new Timer(50, animate);

        timer.start();
        JOptionPane.showMessageDialog(null, imageLabel);
        timer.stop();
    }

    public void animate() {
        Graphics2D g = img.createGraphics();
        g.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING, 
                RenderingHints.VALUE_ANTIALIAS_ON);

        g.setColor(Color.BLUE);
        g.fillRect(0, 0, img.getWidth(), img.getHeight());
        x+=xDelta;
        y+=yDelta;
        int s = 15;
        Area player = new Area(new Ellipse2D.Double(x, y, s, s));

        // Acid test of edge collision;
        if (doAreasCollide(player,walls)) {
            if ( x+s>img.getWidth() || x<0 ) {
                xDelta *= -1;
            } 
            if(y+s>img.getHeight() || y<0 ) {
                yDelta *= -1;
            }
        }
        g.setColor(Color.ORANGE);
        for (Area obstacle : obstacles) {
            if (doAreasCollide(obstacle, player)) {
                g.setColor(Color.RED);
            } else {
                g.setColor(Color.GREEN);
            }
            g.fill(obstacle);
        }

        g.setColor(Color.YELLOW);
        g.fill(player);


        g.dispose();
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                new ShapeCollision();
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}

让它检测所有的红色,并将其设置为冲突边界

在启动时,使用平滑锯齿路径问题中的源代码获取红色像素的轮廓(请参阅GetOutline(Color target,BufferedImage bi)方法)。在启动时将区域存储为单个障碍。

 类似资料:
  • 我试图用HTML画布和JavaScript制作一个非常简单的游戏。我发现了许多关于检测画布上基本形状(如矩形和圆)的碰撞的教程和问题。但我想知道是否有可能检测出一个复杂形状(由许多基本形状组成的形状)是否与另一个形状碰撞,或者即使两个复杂形状正在碰撞。如果是这样,怎么做?提前谢谢!

  • 我知道如何检查一个圆是否要与一个正方形相撞,我知道如何检测一个正方形是否要与一个正方形相撞,但是如果一个多边形要与一个正方形相撞,我该如何检测呢? 或者更好的是,当一个多边形将要与另一个多边形碰撞时。 或者更好的是,当由非直线组成的形状与另一个类似的形状(多边形或圆形/矩形)发生冲突时 有什么方法可以得到一个图形可能占用的像素和另一个图形可能占用的像素,并检查它们是否相同? 我希望有一些解决方案不

  • 我正在尝试做一些碰撞检测。对于这个测试,我使用了一个简单的矩形,并检查它们的,以确定它们是否碰撞。尽管检测没有如预期那样工作。我尝试过使用不同的方法来移动对象(重定位、设置布局X、Y)以及不同的绑定检查(boundsInLocal、BoundsParrent等),但我仍然无法做到这一点。如您所见,检测仅适用于一个对象,即使有三个对象,也只有一个对象检测碰撞。这是一些演示问题的工作代码:

  • 当前有三种类型的碰撞形状: 圆形:快速简单的碰撞形状 线段:主要作为静态形状。可以倾斜以便给之一个厚度。 凸多边形:最慢,但却为最灵活的碰撞形状。 如果你愿意,你可以在一个刚体上添加任意数量的形状。这就是为什么两种类型(形状和刚体)是分离开的。这将会给你足够的灵活性来给相同对象的不同区域提供不同的摩擦力、弹性以及回调值。 当创建不同类型的形状的时候,你将永远得到一个cpShape*指针返回。这是因

  • 问题内容: 我遇到一个问题,即一个矩形与另一个矩形发生碰撞。所以我的问题是,如何获取相交方法以检查碰撞?还是在这种情况下还有其他方法可以处理碰撞? 我正在创建一个回合制战斗游戏(类似于《最终幻想》或《龙骑传奇》),其中玩家的角色在屏幕的右侧,而敌人在屏幕的左侧。玩家和敌人轮流进攻。因此,当玩家攻击时,子画面动画会从右到左在屏幕上移动,直到停在敌人面前,进行攻击并返回到其起始坐标。玩家和敌人周围都有

  • 我遇到了一个问题,显示一个矩形与另一个矩形发生了碰撞。所以我的问题是,如何让Intersect方法检查碰撞?或者在这种情况下有其他方法来处理碰撞吗? 我正在制作一个回合制战斗游戏(类似于《最终幻想》或《龙骑兵传说》),其中玩家的角色位于屏幕的右侧,敌人位于屏幕左侧。玩家和敌人轮流攻击。因此,当玩家攻击时,精灵动画会在屏幕上从右向左移动,直到它停在敌人面前,攻击并返回到其起始坐标。玩家和敌人都有一个