⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bullet.c

📁 坦克大战,实现基本的游戏功能
💻 C
字号:
/*
    bullet.c

    子弹相关的函数实现
    最后修改: 2007-06-19

*/

#include "graph.h"
#include "map.h"
#include "gift.h"
#include "player.h"
#include "bullet.h"

#ifndef NULL
#define NULL 0
#endif

extern CPlayer g_PPlayer1, g_PPlayer2, g_PEnemy;
extern CTank *g_pTank[60][60];

char g_byBulletBomb[6][6] =
{
    /* 子弹爆炸图案 */
    {13,  4, 13, 13, 13, 13},
    {13,  4, 13, 13,  4,  4},
    {13, 13,  4,  4,  4, 13},
    {13,  4,  4,  4, 13, 13},
    { 4,  4, 13,  4,  4, 13},
    {13, 13, 13, 13,  4, 13},

};

CBullet *g_pBullet[60][60];
CBullet *g_pBHead=NULL, *g_pBTail=NULL;
char g_byBaseBombed=0;

void UpdateBullet(CBullet *pThis)  /* 更新子弹所在位置的图案 */
{
    int color;

    if(pThis==NULL) return;
    switch(pThis->m_pOwner->m_pOwner->m_bySide)
    {
    case  1: color=YELLOW;   break;
    case -1: color=LIGHTGRAY;break;
    }

    if(GetPix(pThis->m_nX,   pThis->m_nY  )!=color)
        pThis->m_byPix[0]=GetPix(pThis->m_nX,   pThis->m_nY  );
    if(GetPix(pThis->m_nX+1, pThis->m_nY  )!=color)
        pThis->m_byPix[1]=GetPix(pThis->m_nX+1, pThis->m_nY  );
    if(GetPix(pThis->m_nX,   pThis->m_nY+1)!=color)
        pThis->m_byPix[2]=GetPix(pThis->m_nX,   pThis->m_nY+1);
    if(GetPix(pThis->m_nX+1, pThis->m_nY+1)!=color)
        pThis->m_byPix[3]=GetPix(pThis->m_nX+1, pThis->m_nY+1);
}

void DrawBullet(CBullet *pThis)  /* 画子弹 */
{
    int color;

    if(pThis==NULL) return;
    switch(pThis->m_pOwner->m_pOwner->m_bySide)
    {
    case  1: color=YELLOW;   break;
    case -1: color=LIGHTGRAY;break;
    }
 
    pThis->m_byPix[0]=GetPix(pThis->m_nX,   pThis->m_nY  );
    pThis->m_byPix[1]=GetPix(pThis->m_nX+1, pThis->m_nY  );
    pThis->m_byPix[2]=GetPix(pThis->m_nX,   pThis->m_nY+1);
    pThis->m_byPix[3]=GetPix(pThis->m_nX+1, pThis->m_nY+1);

    PutPix(pThis->m_nX,   pThis->m_nY,   color);
    PutPix(pThis->m_nX+1, pThis->m_nY,   color);
    PutPix(pThis->m_nX,   pThis->m_nY+1,   color);
    PutPix(pThis->m_nX+1, pThis->m_nY+1, color);

    g_pBullet[(pThis->m_nX  )/8][(pThis->m_nY  )/8]=pThis;
    g_pBullet[(pThis->m_nX+1)/8][(pThis->m_nY  )/8]=pThis;
    g_pBullet[(pThis->m_nX  )/8][(pThis->m_nY+1)/8]=pThis;
    g_pBullet[(pThis->m_nX+1)/8][(pThis->m_nY+1)/8]=pThis;
}

void ClearBullet(CBullet *pThis)  /* 清除子弹 */
{
    if(pThis==NULL) return;
    PutPix(pThis->m_nX,   pThis->m_nY,   pThis->m_byPix[0]);
    PutPix(pThis->m_nX+1, pThis->m_nY,   pThis->m_byPix[1]);
    PutPix(pThis->m_nX,   pThis->m_nY+1, pThis->m_byPix[2]);
    PutPix(pThis->m_nX+1, pThis->m_nY+1, pThis->m_byPix[3]);

    g_pBullet[(pThis->m_nX  )/8][(pThis->m_nY  )/8]=NULL;
    g_pBullet[(pThis->m_nX+1)/8][(pThis->m_nY  )/8]=NULL;
    g_pBullet[(pThis->m_nX  )/8][(pThis->m_nY+1)/8]=NULL;
    g_pBullet[(pThis->m_nX+1)/8][(pThis->m_nY+1)/8]=NULL;
}

void CreateBullet(CTank *pThis)  /* 创建子弹 */
{
    int x, y;
    CBullet *pBullet;

    if(pThis==NULL) return;
    switch(pThis->m_byDirect)
    {
    case 1:
        x=pThis->m_nX+7;
        y=pThis->m_nY;
        break;
    case 2:
        x=pThis->m_nX+7;
        y=pThis->m_nY+14;
        break;
    case 3:
        x=pThis->m_nX;
        y=pThis->m_nY+7;
        break;
    case 4:   
        x=pThis->m_nX+14;
        y=pThis->m_nY+7;
        break;
    }

    pBullet=(CBullet *)malloc(sizeof(CBullet));

    pBullet->m_pOwner=pThis;
    pBullet->m_nX=x;
    pBullet->m_nY=y;
    pBullet->m_byDirect=pThis->m_byDirect;
    pBullet->m_byLevel=pThis->m_byLevel;
    pBullet->m_byState=1;
    pBullet->m_pPrev=NULL;
    pBullet->m_pNext=NULL;

    if(g_pBHead==NULL)
    {
        g_pBHead=pBullet;
        g_pBTail=g_pBHead;
    }
    else
    {
        g_pBTail->m_pNext=pBullet;
        g_pBTail->m_pNext->m_pPrev=g_pBTail;
        g_pBTail=g_pBTail->m_pNext;
    }

    DrawBullet(pBullet);

    (pThis->m_nBullets)++;
}

void ExplodeBullet(CBullet *pThis)  /* 爆炸子弹 */
{
    int i, j;

    if(pThis==NULL) return;
    UpdateBullet(pThis);
    ClearBullet(pThis);

    for(i=0;i<6;i++)
    {
        for(j=0;j<6;j++)
        {
            if(IsInMap(pThis->m_nX-2+i, pThis->m_nY-2+j))
            {
                pThis->m_byPix2[i][j]=GetPix(pThis->m_nX-2+i, pThis->m_nY-2+j);
                if(g_byBulletBomb[i][j]!=0) PutPix(pThis->m_nX-2+i, pThis->m_nY-2+j, g_byBulletBomb[i][j]);
            }
	    }
    }

    pThis->m_byTiming=0;
    pThis->m_byState=-1;
}

void DeleteBullet(CBullet *pThis)  /* 删除子弹 */
{
    if(pThis==NULL) return;

    if(pThis->m_pNext!=NULL) pThis->m_pNext->m_pPrev=pThis->m_pPrev;
    if(pThis->m_pPrev!=NULL) pThis->m_pPrev->m_pNext=pThis->m_pNext;

    if(pThis==g_pBHead) g_pBHead=pThis->m_pNext;
    if(pThis==g_pBTail) g_pBTail=pThis->m_pPrev;

    (pThis->m_pOwner->m_nBullets)--;

    free(pThis);
}

void CleanBulletExplode(CBullet *pThis)  /* 清理子弹爆炸图案 */
{
    int i, j;

    if(pThis==NULL) return;

    for(i=0;i<6;i++)
    {
        for(j=0;j<6;j++)
        {
            if(IsInMap(pThis->m_nX-2+i, pThis->m_nY-2+j))
            {
                if(GetPix(pThis->m_nX-2+i, pThis->m_nY-2+j)==g_byBulletBomb[i][j])
                    PutPix(pThis->m_nX-2+i, pThis->m_nY-2+j, pThis->m_byPix2[i][j]);
            }
        }
    }

    pThis->m_byState=-2;
}

int ExplodeWithBullet(int nX, int nY, CBullet *pThis)  /* 与子弹爆炸 */
{
    CBullet *p1=g_pBullet[nX/8][nY/8];

    if(pThis==NULL) return 0;
    if(p1==NULL) return 0;
    if(p1->m_pOwner->m_pOwner->m_bySide==pThis->m_pOwner->m_pOwner->m_bySide) return 0;
    if(p1->m_byState!=1) return 0;
    if((p1->m_byDirect<=2&&pThis->m_byDirect<=2)||(p1->m_byDirect>=3&&pThis->m_byDirect>=3))
    {
        if(!
          (
            (p1->m_nX==nX&&p1->m_nY==nY)||
            (p1->m_nX+1==nX&&p1->m_nY==nY)||
            (p1->m_nX==nX&&p1->m_nY+1==nY)||
            (p1->m_nX+1==nX&&p1->m_nY+1==nY)
          )
        ) return 0;
    }

    UpdateBullet(p1);
    ClearBullet(p1);
    DeleteBullet(p1);

    return 1;
}

int ExplodeWithTank(int x, int y, CBullet *pThis)  /* 与坦克爆炸 */
{
    CTank *p1=g_pTank[x/8][y/8];

    if(pThis==NULL) return 0;
    if(p1==NULL) return 0;
    if(p1->m_pOwner->m_bySide==pThis->m_pOwner->m_pOwner->m_bySide) return 0;
    if(p1->m_byState<0) return 0;

    if(p1->m_byProtected==1) return 1;

    if(p1->m_byHasBoat==1)
    {
        p1->m_byHasBoat=0;
        if(p1->m_pOwner!=&g_PEnemy)
        {
            p1->m_pOwner->m_byHasBoat=0;
        }
        ClearTank(p1);
        DrawTank(p1);
        return 1;
    }

    if(p1->m_byLevel>=3)
    {
        (p1->m_byLevel)-=2;
        if(p1->m_pOwner!=&g_PEnemy)
        {
            (p1->m_pOwner->m_byLevel)-=2;
        }
        return 1;
    }

    if(p1->m_pOwner==&g_PEnemy&&rand()%4==0)
        CreateGift(rand()%59, rand()%59, rand()%7);

    KillTank(p1);
    

    return 1;
}

int ExplodeWithMap(int x, int y, CBullet *pThis)  /* 与地图元素爆炸 */
{

    if(pThis==NULL) return 0;
    switch(GetMap(x/8, y/8))
    {
    case 0:
        return 0;
    case 1:
        ClearMapUnit(x/8, y/8);
        return 1;
    case 2:
        if(pThis->m_byLevel>=3)
        {
            ClearMapUnit(x/8, y/8);
        }
        return 1;
    case 3:
        if(pThis->m_byLevel>=5)
        {
            ClearMapUnit(x/8, y/8);
        }
        return 0;
    case 4:
        if(pThis->m_byLevel>=7)
        {
            ClearMapUnit(x/8, y/8);
        }
        return 0;
    case 100:
        g_byBaseBombed=1;
        return 1;
    }
    return 0;
}


CBullet *MoveBullet(CBullet *pThis)  /* 移动子弹 */
{
    int res=0, i;
    int x, y, x1, y1, x2, y2;
    CBullet *pNext;

    if(pThis==NULL) return NULL;

    pNext=pThis->m_pNext;

    switch(pThis->m_byState)
    {
    case -2:
        DeleteBullet(pThis);
        break;
    case -1:
        if((pThis->m_byTiming)++>=1)
        {
            CleanBulletExplode(pThis);
        }
        break;
    case 1:
        switch(pThis->m_byDirect)
        {
        case 1:
            x=pThis->m_nX;
            y=pThis->m_nY-2;
            x1=x;
            y1=y;
            x2=x+1;
            y2=y;
            break;
        case 2:
            x=pThis->m_nX;
            y=pThis->m_nY+2;
            x1=x;
            y1=y+1;
            x2=x+1;
            y2=y+1;
            break;
        case 3:
            x=pThis->m_nX-2;
            y=pThis->m_nY;
            x1=x;
            y1=y;
            x2=x;
            y2=y+1;
            break;
        case 4:
            x=pThis->m_nX+2;
            y=pThis->m_nY;
            x1=x+1;
            y1=y;
            x2=x+1;
            y2=y+1;
            break;
        }

        if(IsInMap(x1, y1)&&IsInMap(x2, y2))
        {
            res=(ExplodeWithBullet(x1, y1, pThis)||res);
            res=(ExplodeWithBullet(x2, y2, pThis)||res);
            if(res==0)
            {
                res=(res||ExplodeWithTank(x1, y1, pThis));
                res=(res||ExplodeWithTank(x2, y2, pThis));
            }
            res=(ExplodeWithMap(x1, y1, pThis)||res);
            res=(ExplodeWithMap(x2, y2, pThis)||res);

        }
        else
        {
            res=1;
        }

        if(res==1)
        {
            /*UpdateBullet(pThis);
            ClearBullet(pThis);
            DeleteBullet(pThis);*/

            ExplodeBullet(pThis);
        }
        else if(res==0)
        {
            UpdateBullet(pThis);
            ClearBullet(pThis);
            pThis->m_nX=x;
            pThis->m_nY=y;
            DrawBullet(pThis);
        }

        break;
    }

    return pNext;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -