08年的暑假我们“苹果核”团队开发以款手机游戏,在制作中我们遇到了关于精灵碰撞检测的问题.想了很多的解决办法,下面是我们最终的算法:
与“波”进行碰撞检测的对象有敌人、箱子、游戏道具、墙壁、敌人子弹等.在“波”初始化时其检测范围仅为其下半身.当“波”移动时,在其移动的方向前另外加上一层宽为一个像素,长为“波”下半身长的检测膜.
例如,当初始化状态监测区域为:defineCollisionRectangle(6, 27, 20, 20),当“波”向右走时的在迈出步伐之前监测区域为:defineCollisionRectangle(6, 27, 21, 20)
当键盘按下后要把监测区域还原的初始化状态,如果继续保留增加的监测区域就会使敌人或敌人子弹对“波”造成误伤,也会使“波”对游戏道具造成误伤.但在“波”迈出步伐后还要对“波”所处的新的位置的周围环境做检测,以更新“波”对其他事物的触发状态.
具体源码见“碰撞检测代码”
“波”向上走的代码:
if ((keyStates & GameCanvas.UP_PRESSED) != 0)//当按向下键时
{
this.defineCollisionRectangle(6, 26, 20, 21); //重设检测区域
for (int i = pc.getBoxnum(); i >= 0; i--) {
isCollides(pc.box[i]); //与箱子做检测
if (iscollidesWB == true){ //如果与箱子发生碰撞
m=i; //记录箱子的序号
pc.box[i].moveD= 1; //设置箱子要移动的方向
push = true; //设置“波”是否可踢箱子的状态为“是”
break; //跳出循环,不与剩余的箱子做检测
}
else
push = false;
}
if (iscollidesWB == false)
isCollides(pc.tree); //与墙壁做检测
if (iscollidesWB == false && iscollidesWT == false) {//如果没跟箱子和墙
壁发生任何碰撞
if (this.getFrame() == 6)//改变“波”的图片,实现走路的效果
this.setFrame(7);
else if (this.getFrame() == 7)
this.setFrame(8);
else
this.setFrame(6);
panda_Y = Math.max(0, panda_Y - 20);
setPosition(panda_X, panda_Y); //是“波”的位置发生移动
for (int i = pc.getBoxnum(); i >= 0; i--) {
isCollides(pc.box[i]); //再“波”的新位置做检测
if (iscollidesWB == true){
m=i;
pc.box[i].moveD= 1;
push = true;
break;
}
else
push = false;
}
prestep = 1; //记录“波”此次走的方向
} else {
this.setFrame(8);
prestep = 1;
}
defineCollisionRectangle(6, 27, 20, 20); //恢复初始检测区域
}