回 帖 发 新 帖 刷新版面

主题:求助,坦克大战修改

为什么敌人行进时会变成蓝色,我希望他是红色的,还有为什么自己初始是红色的



/*提示:如果发现游戏过快或过慢请修改Pc_Delay的值(越大游戏越慢),以达到最好的运行效果*/
/*这个版本中你永远死不了(从你的分数中可以看出你死亡的情况),但可以供程序爱好者修改相应的函数达到自己不同的游戏规则*/ 
#include <stdio.h> 
#include <stdlib.h> 
#include <bios.h> 
#include <graphics.h> 
/*定义键盘扫描码*/ 
#define k_up 18432 
#define k_down 20480 
#define k_left 19200 
#define k_right 19712 
#define k_space 14624 
#define k_esc 283 
#define k_p 6512
#define Tk_Spd 300/*敌方坦克的行走速度(可升级,修改这个值可以获得不同的执行速度)*/
#define Zd_Spd 100 /*子弹的飞行速度*/
#define Ntank_Time 5000 /*产生新坦克的间隔时间*/
#define Zd_Time 250 /*计算机发出子弹的间隔时间(可升级,修改这个值可以获得不同的执行速度)*/
#define Pc_Delay 2/*不同速度的计算机可能不同!如果有必要的话可以修改*/

#define M_Max 21 /*游戏框大小为21*30*/ 
#define N_Max 30

typedef enum 
{
    F_Begin,
    F_Pause,
    F_Exit
} Fun_Flag; /*游戏操作的功能标志*/ 
typedef enum 
{
    Tk_No,
    Tk_Up,
    Tk_Down,
    Tk_Left,
    Tk_Right
} Tk_Direct; /*坦克行进的方向标志,Tk_No表示销毁或者其他*/ 
typedef enum 
{
    Dt_Zero,
    Dt_Em,
    Dt_Me
} Dt_Type; /*存储在游戏矩阵中的数据类*/ 
/*Dt_Zero表示没有数据,Dt_Em,表示敌人的坦克或者子弹,Dt_Me表示自己的坦克或子弹*/

typedef struct Tk_Node 
{ /*坦克事件的结点定义*/ 
int x; 
int y; /*位置数据*/ 
Dt_Type type; /*数据类型*/ 
Tk_Direct drct; /*坦克的方向*/ 
struct Tk_Node* next; 
}Tk_Node,*Tk_Link;

typedef struct Zd_Node 
{ /*子弹事件的结点定义*/ 
int x; 
int y; /*子弹的位置*/ 
int is_fst; /*是否是刚发射的子弹*/ 
Dt_Type type; /*子弹的数据类型(敌方的还是自己的)*/ 
Tk_Direct drct; /*子弹的飞行方向*/ 
struct Zd_Node* next; 
}Zd_Node,*Zd_Link;

Dt_Type Gm_Array[M_Max][N_Max]; /*建立游戏矩阵,游戏矩阵中的每一个点对应着屏幕上的显示*/ 
/*一个坦克用3*3大小的矩阵存储,用中间那个点表示坦克的位置(表示坦克的存在)*/ 
Tk_Link Tk_List; /*建立坦克事件链表*/ 
Zd_Link Zd_List; /*建立子弹事件链表*/ 
int cs_tks; /*游戏中所有产生的坦克数目*/ 
int kill_tks; /*你在玩游戏过程中杀死的敌方坦克数目*/ 
int Me_Deads; /*你被敌方坦克杀死的次数*/ 
/*cs_tks-kill_tks表示目前在屏幕上的坦克个数*/

static char ct_dx[4]={-1,1,0,0}; /*以下定义常用的检查表。它们的具体功能见程序中*/ 
static char ct_dy[4]={0,0,-1,1}; 
static char frtlbx[4][5]={
    {-1,-2,-2,-2,-1},
    {1,2,2,2,1},
    {-1,-1,0,1,1},
    {-1,-1,0,1,1}}; 
static char frtlby[4][5]={
    {-1,-1,0,1,1},
    {-1,-1,0,1,1},
    {-1,-2,-2,-2,-1},
    {1,2,2,2,1}}; 
static int rot_d[4][3]={
    {3,2,4},
    {4,1,3},
    {2,4,1},
    {1,3,2}}; 
/***************************************/ 
void opengraph(void); /*打开图形模式*/ 
void Draw_Node(int x,int y,Dt_Type type);
/*在屏幕上画一个方块(底层函数,用于画坦克或子弹,一个坦克用6个方块组成)*/
void Draw_Tankone(int x,int y,Tk_Direct d,int who); 
/*在屏幕上画一个坦克,d为坦克的初始朝向,who表示是那种坦克(自己或是敌人坦克)*/ 
void Rot_Tank(int x,int y,int LR); 
/*对坦克进行旋转操作,(x,y)表示要旋转的坦克,lr表示旋转的程度(左旋,右旋,后旋)*/ 
void Move_Tank(int x,int y,Tk_Direct type); /*移动一个坦克,type表示移动的方向*/ 
void Control_Tank(Tk_Link p,Tk_Direct direct); /*用于控制自己的坦克*/ 
void Insert_Tklink(int x,int y,Dt_Type type,Tk_Direct drct); /*将一个坦克加入坦克事件链表*/ 
void Insert_Zdlink(int x,int y,Dt_Type type,Tk_Direct drct); /*将一个子弹加入子弹事件链表*/ 
int Delete_Tklink(int x,int y);/*在坦克事件链表上删除一个坦克*/ 
int Delete_Zdlink(int x,int y); /*在子弹事件链表上删除一个坦克*/ 
void Init_Tklink(void); /*初始化坦克事件链表*/ 
void Init_Zdlink(void); /*初始化子弹时间链表*/ 
void Delete_Allt(void); /*删除全部坦克事件(用于游戏结束)*/ 
void Delete_Allz(void); /*删除全部子弹时间(用于游戏结束*/ 
void Init(void); /*初始化游戏的所有变量和数据结构*/ 
int Front_Ok(Tk_Link p,Tk_Direct direct); /*查看坦克的前方是否可以行进(用于坦克的行走)*/ 
void Mul_zd(void); /*处理子弹事件(如果有子弹事件产生的话)*/ 
void Kill_Em(int x,int y); /*杀死一个敌方坦克*/ 
void Game_Over(void); /*处理自己被敌方坦克击中的事件(可以修改这个函数获得不同游戏规则)*/ 
int Check_is_zd(int x,int y); /*查看前方是否是一个子弹(用于子弹与子弹碰撞的处理)*/ 
void Product_Zd(void); /*用于产生子弹事件*/ 
void Move_All_Tank(void); /*用于处理敌方坦克移动事件*/ 
int Check_f_again(Tk_Link p); /*用于坦克旋转的二次检查*/ 
void Create_Ntk(void); /*产生新的坦克*/ 
int has_a_tk(int x,int y); /*查看在(x,y)这个位置上有没有坦克(用于产生新的坦克)*/ 
void erase_scoresblue(void); /*记分辅助函数(擦除并从新显示)*/
void erase_scoresred(void);

void main(void) 

    Fun_Flag flag_f=F_Begin; /*游戏控制的功能类型*/ 
    int keyid; /*存放键盘扫描码*/ 
    Tk_Direct direct; /*定义坦克的方向*/ 
    int zdsd=Zd_Spd; /*子弹的速度*/ 
    int zdjg=Zd_Time; /*子弹的飞行间隔时间(速度的快慢)*/ 
    int tksd=Tk_Spd; /*坦克的移动速度*/ 
    long int ntk=Ntank_Time; /*产生新坦克的间隔时间*/ 
    Tk_Direct temp; /*方向暂存*/ 

    printf("\n\n\n\n\n Press anykey to start game......."); 
    getch(); opengraph(); /*打开图形模式并注册图形驱动*/ 
    setcolor(WHITE); /*设置为白色(用于画框)*/ 
    rectangle(8,8,612,432); /*画游戏大方框*/ 
    setcolor(WHITE); /*输出游戏信息*/ 
    settextstyle(0,0,2); 
    outtextxy(10,450,"TANK!");
    setcolor(BLUE);
    outtextxy(350,450,"BLUE Scores:");
    setcolor(RED);
    outtextxy(130,450,"Red Scores:");
    randomize(); /*初始化随机数生成器的种子*/ 
    Init(); /*初始化游戏数据结构和相关的变量*/ 
    while(flag_f!=F_Exit) 
    { /*对当前的功能类型的选择进行判断*/ 
    if(bioskey(1)) 
    { /*检查是否有键按下*/ 
    keyid=bioskey(0); /*读取所按键的扫描码*/ 
    switch(keyid) 
    { /*对所按键的类型判断*/ 
    case k_up: /*如果是向上的按键*/ 
    if(flag_f==F_Begin) 
        Control_Tank(Tk_List,Tk_Up);/*控制坦克向上移动*/ 
    /*在函数中调用Tk_List表示自己的坦克,因为在定义坦克事件链表时总是将自己的坦克放在链表头那里*/ 
    break; 
    case k_down: /*如果是向下的按键*/ 
    if(flag_f==F_Begin) 
    Control_Tank(Tk_List,Tk_Down); /*控制坦克向下移动*/ 
    break; 
    case k_left: /*如果是向左的按键*/ 
    if(flag_f==F_Begin) 
    Control_Tank(Tk_List,Tk_Left); /*同上*/
    break; 
    case k_right: 
    if(flag_f==F_Begin) 
        Control_Tank(Tk_List,Tk_Right); 
    break; 
case k_space: 
    if(flag_f==F_Begin) 
    { /*产生了一个子弹事件,并处理这个子弹事件*/ 
        temp=Tk_List->drct; /*插入子弹事件队列(类型标志为我方子弹)*/ 
        Insert_Zdlink(Tk_List->x+ct_dx[temp-1],Tk_List->y+ct_dy[temp-1],Dt_Me,temp); 
    } 
    break; 
case k_p: /*用于处理游戏暂停*/ 
    if(flag_f!=F_Pause) 
        flag_f=F_Pause; /*置类型标志为暂停标志*/ 
    else 
        flag_f=F_Begin; /*反向处理暂停*/ 
    break; 
case k_esc: /*退出游戏的处理*/ 
    setcolor(WHITE); 
    outtextxy(200,200,"GAME OVER!"); 
    flag_f=F_Exit; 
    break; 
}
 } 
delay(Pc_Delay); /*设置分频基数为Pc_Delay个单位*/ 
if(flag_f==F_Begin) 
{ /*如果标志为暂停时不处理下列事件*/ 
    if(Zd_List&&!(--zdsd)) 
    { /*如果子弹事件队列中有事件并且定时时间达到就去处理子弹事件*/ 
        Mul_zd(); 
        zdsd=Zd_Spd;
    } 
    if(Tk_List&&Tk_List->next&&!(--zdjg)) 
    {/*如果有坦克的话,那么让这些坦克打出子弹*/ 
        Product_Zd(); /*产生子弹*/ 
        zdjg=Zd_Time; 
    } 
    if(Tk_List&&Tk_List->next&&!(--tksd)) 
    {/*如果有坦克(敌方坦克)的话,让这些坦克移动*/ 
        Move_All_Tank(); /*移动所有敌方坦克*/ 
        tksd=Tk_Spd; } 
    if((cs_tks-kill_tks)<=15&&!(--ntk)) 
    { /*如果屏幕中的敌方坦克数目小于15(左右),产生新的坦克*/ 
        Create_Ntk(); /*产生新的坦克*/ 
        ntk=Ntank_Time; 

}
 }
 getch(); 
 closegraph(); 
}

void erase_scoresblue(void) 

    setfillstyle(SOLID_FILL,BLACK); /*刷新记分的屏幕*/ 
    bar(537,435,638,465); 
    setcolor(BLUE); 
}
void erase_scoresred(void) 

    setfillstyle(SOLID_FILL,BLACK); /*刷新记分的屏幕*/ 
    bar(317,435,345,465); 
    setcolor(RED); 
}

void Game_Over(void) 
{ /*当敌人的坦克打到你,就会调用这个函数,可以编写不同的代码从而实现不同的游戏规则*/ 
    static char format_GO[10]; 
    ++Me_Deads; 
    erase_scoresred(); /*在屏幕中显示分数*/ 
    outtextxy(320,450,itoa(Me_Deads,format_GO,10)); 
 }

void opengraph(void) 
{/*打开图形模式,并注册图形驱动*/ 
    int gdriver=VGA,gmode=VGAHI; 
    initgraph(&gdriver,&gmode,"C:\\TCPP30E\\BGI"); 
}

int has_a_tk(int x,int y) 
{ /*判断在(x,y)位置是否有一个坦克(或其他的障碍),用于产生新的坦克*/ 
    int i,tx,ty; 
    int flag=1; 
for(i=0;i<9&&flag;i++) 
{ /*对该点四周检查*/ 
    tx=x+i/3-1; 
    ty=y+(i+3)%3-1; 
if(Gm_Array[tx][ty]) 
flag=0; /*如果该点的周围有东西的话,就表示不应该在这个地方产生坦克*/ 

return !flag; 
}

void Create_Ntk(void) 
{ /*在屏幕的四个角产生新的坦克(每个角产生坦克的概率为1/2)*/ 
    if(rand()%2&&!has_a_tk(1,1)) 
    { /*判断:“1/2的概率” 且 “在(1,1)位置是否有东西”*/ 
        Insert_Tklink(1,1,Dt_Em,Tk_Down); /*如果满足产生新坦克的条件,则产生新的坦克*/ 
        /*产生的方法为:在坦克事件队列中插入一个坦克,并画出这个坦克*/ 
        Draw_Tankone(1,1,Tk_Down,0); ++cs_tks; } 
    if(rand()%2&&!has_a_tk(1,28)) { 
        Insert_Tklink(1,28,Dt_Em,Tk_Down); 
    Draw_Tankone(1,28,Tk_Down,0); ++cs_tks; } 
    if(rand()%2&&!has_a_tk(19,1)) { 
        Insert_Tklink(19,1,Dt_Me,Tk_Up); 
        Draw_Tankone(19,1,Tk_Up,1); ++cs_tks; } 
    if(rand()%2&&!has_a_tk(19,28)) { 
        Insert_Tklink(19,28,Dt_Me,Tk_Up); 
        Draw_Tankone(19,28,Tk_Up,1); ++cs_tks; } 
}

void Move_All_Tank(void) 
{ /*从坦克事件队列中依次取出坦克并移动它们*/ 
    Tk_Link p=Tk_List->next; 
    int rot; 
    while(p) 
    { /*读取坦克队列中的每一个坦克*/ 
        if(Front_Ok(p,p->drct)) 
        { /*如果前方没有障碍的话*/ 
            Move_Tank(p->x,p->y,p->drct); /*向前移动坦克*/ 
            p->x+=ct_dx[p->drct-1]; 
            p->y+=ct_dy[p->drct-1]; 
        } 
        else if(Check_f_again(p)) 
        { /*如果前方有障碍,查看该坦克是否满足旋转(掉头)的条件*/ 
            rot=rand()%3-1; /*旋转掉头的方向为随机*/ 
            Rot_Tank(p->x,p->y,rot); /*旋转该坦克*/ 
            p->drct=rot_d[p->drct-1][rot+1]; /*从新设置旋转的方向*/ 

        p=p->next; 
    }
 }

int Check_f_again(Tk_Link p) 
{ /*查看旋转是否满足条件*/ 
    static int ck_a[4][3]={
        {0,2,7},
        {1,6,8},
        {0,5,6},
        {2,3,8}}; /*应该查看的点的位置矩阵*/ 
    /*采用静态查表可以节约大量的时间*/ 
/* 0 1 2 0 1 0 坦克在矩阵中的存储顺序为: 3 4 5 如坦克:1 1 1 在处理中要进行矩阵变换 6 7 8 1 0 1 */ 
    int tx,ty,i; 
    int flag=1; 
    for(i=0;i<3&&flag;i++) 
    { /*对应该检查的点进行逐个检查*/ 
        tx=p->x+ck_a[p->drct-1][i]/3-1; /*进行坦克相对位置到游戏矩阵(Gm_Array)的地址变换*/ 
        ty=p->y+(ck_a[p->drct-1][i]+3)%3-1; 
        if(Gm_Array[tx][ty]!=Dt_Zero) 
            flag=0; 
    } 
    return flag; 
}

int Front_Ok(Tk_Link p,Tk_Direct direct) 
{ /*对坦克前方的5个点进行检测*/ 
    int i,flag=0,tx,ty; 
    for(i=0;i<5&&!flag;i++) 
    { 
        tx=p->x+frtlbx[direct-1][i]; /*查frtlbx表(确定5个点的查找位置)*/ 
    ty=p->y+frtlby[direct-1][i]; 
    if(tx<0||tx>M_Max-1||ty<0||ty>N_Max-1) 
        flag=1; 
    else if(Gm_Array[tx][ty]!=Dt_Zero) 
        flag=1; 
    } 
    return !flag; 
}

void Product_Zd(void) 
{ /*产生子弹事件*/ 
    Tk_Link p=Tk_List->next; 
int temp; 
while(p) 
{ /*查坦克链表,对每一个坦克都有1/2的概率打出子弹*/ 
    if(rand()%2) 
    { 
        temp=p->drct; /*将产生的子弹插入到子弹链表中去*/ 
        Insert_Zdlink(p->x+ct_dx[temp-1],p->y+ct_dy[temp-1],Dt_Em,temp); 

    p=p->next; 

}

回复列表 (共12个回复)

11 楼


        Draw_Node(tx,ty,dtdata[d][i]); 
        if(dtdata[d][i]) 
            Gm_Array[tx][ty]=who+1; /*修改游戏矩阵*/ 
        else 
            Gm_Array[tx][ty]=Dt_Zero;
            
            
            
            这一句?
            1是自己0是敌人啊

12 楼

终于好了,明白了,是那里的问题,再新建一个Draw_Me改一下就好了

我来回复

您尚未登录,请登录后再回复。点此登录或注册