1

我正在开发一个 2d 街机游戏,其中有 5 种不同大小的圆圈:船、导弹和 3 种怪物。

这是它的样子:

在此处输入图像描述

目前我正在使用蛮力碰撞检测,在不考虑碰撞概率的情况下检查每个导弹与每个怪物。可悲的是,这使得这个过程真的很慢。

这是我的 Grid 类,但它不完整。非常感谢您的帮助。

    public class Grid {

    int rows;
    int cols;
    double squareSize;
    private ArrayList<Circle>[][] grid;

    public Grid(int sceneWidth, int sceneHeight, int squareSize) {
        this.squareSize = squareSize;
// Calculate how many rows and cols for the grid.
        rows = (sceneHeight + squareSize) / squareSize;
        cols = (sceneWidth + squareSize) / squareSize;
// Create grid
        this.grid = (ArrayList[][]) new ArrayList[cols][rows]; //Generic array creation error workaround
    }

The addObject method inside the Grid class.
    public void addObject(Circle entity) {
// Adds entity to every cell that it's overlapping with.
        double topLeftX = Math.max(0, entity.getLayoutX() / squareSize);
        double topLeftY = Math.max(0, entity.getLayoutY() / squareSize);
        double bottomRightX = Math.min(cols - 1, entity.getLayoutX() + entity.getRadius() - 1) / squareSize;
        double bottomRightY = Math.min(rows - 1, entity.getLayoutY() + entity.getRadius() - 1) / squareSize;

        for (double x = topLeftX; x < bottomRightX; x++) {
            for (double y = topLeftY; y < bottomRightY; y++) {
                grid[(int) x][(int) y].add(entity); //Cast types to int to prevent loosy conversion type error.
            }
        }
    }

但这就是我完全不知所措的地方。我什至不确定我提供的源代码是否正确。请让我知道如何使基于网格的碰撞工作。我基本上已经阅读了我可以掌握的所有教程,但效果不佳。谢谢。

4

1 回答 1

0

我发现在对象本身中存储一个二进制数更容易(而且我猜更快),该二进制数表示对象与哪些单元格重叠(而不是为每个单元格保存一个数组)。我认为它被称为空间蒙版

更具体地说,在任何碰撞测试之前,我计算2^(x/column_width + columns*y/row_width)每个topLeft, topRight... 然后将所有这 4 个组合成一个数字(使用按位 OR),这样我最终得到一个数字,例如5( 00000011,表示物体撞击细胞1 和 2)。

这样一来,您就可以继续与所有其他对象一起测试每个对象,但如果它们未能在同一个单元格中,则跳过缓慢的部分:

  1. 检查两个对象中数字的按位与(仅!=0当某些单元格1用于两个对象时)。
  2. 如果结果不是0,请进行适当的(慢速)碰撞检查(在您的情况下可能是pythagoras,因为这些是圆圈,我读到 pythagoras 比检查边界正方形更快)。
于 2022-01-23T11:31:36.147 回答