主题:求助,坦克大战修改
为什么敌人行进时会变成蓝色,我希望他是红色的,还有为什么自己初始是红色的
/*提示:如果发现游戏过快或过慢请修改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;
}
}
/*提示:如果发现游戏过快或过慢请修改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;
}
}