目前子弹还无法击毁敌机,并且英雄也可以若无其事地穿过敌机。预期情况下,应该子弹撞击到敌机后,敌机会发生爆炸并销毁。英雄如果撞击到敌机,英雄飞机也会发生爆炸并销毁。
为了实现这两个效果,我们在mainSceneUpdate
函数中,调用用于检测子弹是否击中敌机的函数bulletHitEnemyCheck
。并且在其后调用检查英雄飞机是否撞击敌机的函数heroHitEnemyCheck
,若英雄飞机撞击到敌机,则把英雄飞机的生命值减1,状态立刻切换为hero_down1
。
源文件mainScene.cpp
void mainSceneUpdate(struct mainScene* s)
{
for (int i = 0; i < s->vecElements.size; i++)
{
struct sprite* pSprite = (struct sprite*)s->vecElements.pData[i];
pSprite->update(pSprite);
}
int n = rand() % 20;
if (n == 0)
{
generateNewEnemy(s);
}
destroyInvalidEnemy(s);
s->bulletGenCnt++;
if (s->bulletGenCnt >= 15)
{
generateBullet(s);
s->bulletGenCnt = 0;
}
destroyInvalidBullet(s);
// 敌机击中碰撞检测
bulletHitEnemyCheck(s);
// hero碰撞敌机检测
bool isHited = heroHitEnemyCheck(s);
if (isHited == true)
{
s->hero->life--;
s->hero->status = hero_down1;
}
}
接下来,让我们看看这两个函数是如何实现的?
源文件mainScene.cpp
void bulletHitEnemyCheck(struct mainScene* s)
{
// 碰撞检测
for (int i = 0; i < s->vecBullets.size; i++)
{
// 将子弹抽象为头部的一个点
struct bullet* pBullet = (struct bullet*)s->vecBullets.get(&s->vecBullets, i);
POINT bulletPoint;
bulletPoint.x = pBullet->super.x + 6 / 2;
bulletPoint.y = pBullet->super.y;
// 检查每一颗子弹是否碰撞到任意敌机
for (int j = 0; j < s->vecEnemy.size; j++)
{
struct enemy* pEnemy = (struct enemy*)s->vecEnemy.get(&s->vecEnemy, j);
// 敌机的宽度与高度
int width, height;
width = pEnemy->super.width;
height = pEnemy->super.height;
// 敌机矩形区域
int left, top, right, bottom;
left = pEnemy->super.x;
top = pEnemy->super.y;
right = left + width;
bottom = top + height;
// 检查子弹是否在矩形区域内
if (bulletPoint.x > left && bulletPoint.x < right &&
bulletPoint.y > top && bulletPoint.y < bottom
)
{
if (pEnemy->life != 0)
{
// 子弹撞击到敌机后,销毁子弹
bulletDestroy(pBullet);
free(pBullet);
s->vecBullets.remove(&s->vecBullets, i);
i--;
// 敌机击中
pEnemy->hited(pEnemy);
break;
}
}
}
}
}