我有一个程序可以检查距离以及玩家是否与障碍物发生碰撞。我现在试图计算障碍阵列中哪个障碍最接近移动玩家,然后返回该障碍的索引。
这是我到目前为止所做的:
public static int closestBarrier(GameObject object, GameObject[] barriers)
// TODO stub
{
int closest = 0;
for (int i = 0; i < barriers.length - 1; i++) {
if (Math.sqrt((object.getX() - barriers[i].getX())
* (object.getX() - barriers[i].getX()))
+ ((object.getY() - barriers[i].getY()) * (object.getY() - barriers[i]
.getY())) <= Math
.sqrt((object.getX() - barriers[i + 1].getX())
* (object.getX() - barriers[i + 1].getX()))
+ ((object.getY() - barriers[i + 1].getY()) * (object
.getY() - barriers[i + 1].getY()))) {
closest = i;
} else
closest = i + 1;
}
return closest;
}
我还是java的新手,所以我理解我已经拥有的可能不是很有效率或最好的方法(甚至是正确的!?)。
答案 0 :(得分:1)
我将它重构得更简单:
public static int closestBarrier(GameObject object, GameObject[] barriers)
{
int closest = -1;
float minDistSq = Float.MAX_VALUE;//ridiculously large value to start
for (int i = 0; i < barriers.length - 1; i++) {
GameObject curr = barriers[i];//current
float dx = (object.getX()-curr.getX());
float dy = (object.getY()-curr.getY());
float distSq = dx*dx+dy*dy;//use the squared distance
if(distSq < minDistSq) {//find the smallest and remember the id
minDistSq = distSq;
closest = i;
}
}
return closest;
}
通过这种方式,您可以减少距离检查(您的版本每次迭代会进行两次距离检查),而且您只需要id,而不是实际距离,这样您就可以通过不使用{{1}来获得一点速度而只是使用平方距离代替。
我能想到的另一个想法取决于布局。假设您有一个自上而下的垂直滚动条,您可以从检查障碍物的y属性开始。如果您有它们的哈希值或排序列表,对于屏幕底部的对象,您将从最大的y屏障开始循环到最小的屏障。一旦在Y轴上找到最近的障碍物,如果有多于1个,则可以检查x轴上最近的障碍物。您不需要使用正方形或平方根,因为您基本上将检查从每个障碍物中的1个拆分为1D中的2个检查,缩小障碍并丢弃远离障碍而不是检查每个对象 。
更高级的版本将使用space partitioning,但希望您在学习时不需要它来进行简单的游戏。