33.飞机大战:击毁敌机与菜单场景

  • 学习人数 15K+
  • 适合有C语言基础人群学习
avatar
林耿亮

你好编程主讲老师

目前子弹还无法击毁敌机,并且英雄也可以若无其事地穿过敌机。预期情况下,应该子弹撞击到敌机后,敌机会发生爆炸并销毁。英雄如果撞击到敌机,英雄飞机也会发生爆炸并销毁。

没有碰撞检测

为了实现这两个效果,我们在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;
                }
            }
        }
    }
}