#include <graphics.h>
#include <conio.h>
#include <dos.h>
#include <stddef.h>
#include <stdlib.h>
#include <time.h>
#include "TANK_DEF.H"
#include "SETGRAPH.H"
#include "TANK_ACT.H"
#include "BLLTLIST.H"
#include "BACKGRND.H"
#include "GET_KEY.H"
#include "CHINESE.H"
#include "MUSIC.H"
#define Key_Esc 0x1 /* 退出键 */
#define Key_F1 0x3b /* 帮助 */
/* 玩家一的按键 */
#define Key_W 0x11 /* 向上键 */
#define Key_A 0x1e /* 向左键 */
#define Key_S 0x1f /* 向下键 */
#define Key_D 0x20 /* 向右键 */
#define Key_O 0x18 /* 射击键 */
/* 玩家二的按键 */
#define Key_UP 0x48 /* 向上键 */
#define Key_LEFT 0x4b /* 向左键 */
#define Key_DOWN 0x50 /* 向下键 */
#define Key_RIGHT 0x4d /* 向右键 */
#define Key_NUM_0 0x52 /* 射击键 */
void action_loop_my(void);
void action_loop_your(void);
void action_loop_other(void);
void start_game(void);
void next_game(void);
void end_game(void);
int game_manu(void);
void game_help(int playing_flag);
struct tank mytank; /* player_1的坦克 */
struct tank yourtank; /* player_2的坦克 */
char exit_flag=0; /* 结束游戏的指示标志 */
char action_flag=1; /* 与控制游戏动作循环周期有关的一个标志性变量 */
char action_counter=0; /* 决定每一次动作循环执行什么操作的标志 */
int num_players; /* 玩家数 */
int gate=1; /* 关卡 */
int next_gate=0; /* 当值为“1”时进入下一关 */
int score_1=0, score_2=0; /* 得分 */
unsigned char map_state[80][60]; /* 用于地图上没个位置存在哪些东西的屏幕数组 */
void main(void)
{
time_t time_now;
time(&time_now);
srand((unsigned)time_now); /* 初始化随机数 */
startgraph(); /* 初始化图形界面 */
open_hzk(); /* 打开字库文件 */
open_music_file(); /* 打开音乐文件 */
start_game(); /* 开始游戏 */
do /* 游戏循环 */
{
if ((inportb(0x3da)&0x08)!=0 && action_flag==0) /* 利用屏幕的垂直回扫周期来控制游戏节奏(60Hz) */
{
if (action_counter==0) /* 根据action_counter的值来执行相应的游戏动作 */
action_loop_my();
else if (action_counter==2)
action_loop_your();
else
action_loop_other();
action_flag=1;
}
else if ((inportb(0x3da)&0x08)==0 && action_flag==1)
{
play_bk_music(); /* 放背景音乐 */
if (action_counter==3)
action_counter=0;
else
action_counter++;
action_flag=0;
}
if (exit_flag)
{
nosound();
end_game(); /* 退出游戏 */
}
if (next_gate)
{
nosound();
next_game(); /* 下一轮游戏 */
}
}
while (1);
}
void action_loop_my(void) /* player_1的行动 */
{
int dir_key_flag=0; /* 判断方向键是否已经被读取的标志 */
move_bullets(); /* 移子弹 */
act_move_tank(&mytank); /* 如我的坦克有移动(但没有显示完整个移动过程),就在屏幕上移动它 */
act_move_tank(&yourtank); /* 如我的坦克有移动(但没有显示完整个移动过程),就在屏幕上移动它 */
act_move_tanks(); /* 如电脑的坦克有移动(但没有显示完整个移动过程),就在屏幕上移动它 */
add_tank(); /* 加电脑的坦克 */
if (mytank.blood>0)
{
if (get_key_state(Key_W) && !dir_key_flag) /* 根据按键移坦克 */
{
move_tank(&mytank, UP);
dir_key_flag=1;
}
if (get_key_state(Key_A) && !dir_key_flag)
{
move_tank(&mytank, LEFT);
dir_key_flag=1;
}
if (get_key_state(Key_S) && !dir_key_flag)
{
move_tank(&mytank, DOWN);
dir_key_flag=1;
}
if (get_key_state(Key_D) && !dir_key_flag)
{
move_tank(&mytank, RIGHT);
dir_key_flag=1;
}
if (get_key_state(Key_O) && mytank.shoot_interval==0) /* 当O键按下且为可射击时才射击 */
{
add_bullet(&mytank);
mytank.shoot_interval=1; /* 开始新一轮射击间隔计时 */
}
}
if (mytank.shoot_interval>0 && mytank.shoot_interval < mytank.bul_interval_max) /* 射击间隔计时 */
mytank.shoot_interval++;
else
mytank.shoot_interval=0;
}
void action_loop_your(void) /* 一些自动完成的过程 */
{
int dir_key_flag=0; /* 判断方向键是否已经被读取的标志 */
move_bullets(); /* 移子弹 */
act_move_tank(&mytank); /* 如我的坦克有移动(但没有显示完整个移动过程),就在屏幕上移动它 */
act_move_tank(&yourtank); /* 如我的坦克有移动(但没有显示完整个移动过程),就在屏幕上移动它 */
act_move_tanks(); /* 如电脑的坦克有移动(但没有显示完整个移动过程),就在屏幕上移动它 */
tank_auto_action(); /* 电脑的坦克发生一个随机动作(移动或射击或什么都不干) */
if (num_players==2 && yourtank.blood>0)
{
if (get_key_state(Key_UP) && !dir_key_flag) /* 根据按键移坦克 */
{
move_tank(&yourtank, UP);
dir_key_flag=1;
}
if (get_key_state(Key_LEFT) && !dir_key_flag)
{
move_tank(&yourtank, LEFT);
dir_key_flag=1;
}
if (get_key_state(Key_DOWN) && !dir_key_flag)
{
move_tank(&yourtank, DOWN);
dir_key_flag=1;
}
if (get_key_state(Key_RIGHT) && !dir_key_flag)
{
move_tank(&yourtank, RIGHT);
dir_key_flag=1;
}
if (get_key_state(Key_NUM_0) && yourtank.shoot_interval==0) /* 当O键按下且为可射击时才射击 */
{
add_bullet(&yourtank);
yourtank.shoot_interval=1; /* 开始新一轮射击间隔计时 */
}
}
if (yourtank.shoot_interval>0 && yourtank.shoot_interval < yourtank.bul_interval_max) /* 射击间隔计时 */
yourtank.shoot_interval++;
else
yourtank.shoot_interval=0;
}
void action_loop_other(void) /* 其它过程 */
{
move_bullets(); /* 移子弹 */
act_move_tank(&mytank); /* 如我的坦克有移动(但没有显示完整个移动过程),就在屏幕上移动它 */
act_move_tank(&yourtank); /* 如我的坦克有移动(但没有显示完整个移动过程),就在屏幕上移动它 */
act_move_tanks(); /* 如电脑的坦克有移动(但没有显示完整个移动过程),就在屏幕上移动它 */
if (get_key_state(Key_Esc)) /* 判断是否有退出请求 */
exit_flag=1;
if (get_key_state(Key_F1))
game_help(1);
}
void start_game(void) /* 拉开游戏的序幕 */
{
extern void *tank_pic[4][16];
extern unsigned char map_state[][];
extern struct tank mytank;
int i, j, k, m, x, y, size;
struct tank tank_temp;
struct bullet bul_temp;
char *s;
void *image_buffer;
/* 角色图像的预处理 */
cleardevice(); /* 清屏 */
for (i=0, k=1; i<4; i++) /* 在不位置画坦克并存储图像 */
for (j=0; j<16; j++)
if (j==YELLOW || j==RED || j==CYAN || j==GREEN) /* 本游戏中共用到的四种颜色的坦克 */
{
tank_temp.direction=(unsigned)i;
tank_temp.color=j;
tank_temp.left=32*k+36;
tank_temp.top=440;
get_tank_pic(&tank_temp);
k++;
}
for (i=0, k=1; i<4; i++) /* 在不同位置画子弹并存储图像 */
for (j=0; j<16; j++)
if (j==YELLOW || j==RED || j==CYAN || j==GREEN) /* 本游戏中共用到的四种颜色的子弹,分别与坦克相对应 */
{
bul_temp.direction=(unsigned)i;
bul_temp.color=j;
bul_temp.left=32*k+46;
bul_temp.top=432;
get_bul_pic(&bul_temp);
k++;
}
get_eagle_pic(240, 240); /* 得到鹰的图像 */
get_brick_pic(120, 120); /* 并存储砖块图像 */
cleardevice(); /* 清屏 */
/* 菜单和版权 */
s="超级坦克"; x=180; y=420; size=3;
while (*s!='\0')
{
dishz(x, y, s, LIGHTGRAY, size); /* 输出一个汉字 */
x+=20*size; /* 坐标右移,以备输下一个汉字 */
s+=2; /* 使指针指向下一个汉字 */
}
for (i=0; i<100; i++) delay(100);
image_buffer=malloc(imagesize(180, 420, 419, 467));
getimage(180, 420, 419, 467, image_buffer);
for (y=417; y>100; y-=3) /* 实现文字从下往上移动的效果 */
{ /* 清除、重画、暂停一下 */
while ((inportb(0x3da)&0x08)!=0); /* 等待上一次垂直回扫的结束,以消除闪烁 */
while ((inportb(0x3da)&0x08)==0); /* 等待下一次垂直回扫的开始,以消除闪烁 */
putimage(180, y+3, image_buffer, XOR_PUT);
putimage(180, y, image_buffer, XOR_PUT);
}
free(image_buffer);
for (i=0; i<100; i++) delay(3000);
s="单人游戏"; x=240; y=200; size=2;
while (*s!='\0')
{
dishz(x, y, s, WHITE, size);
x+=20*size;
s+=2;
for (i=0; i<10; i++) delay(3000);
}
for (i=0; i<100; i++) delay(3000);
s="双人合作"; x=240; y=240; size=2;
while (*s!='\0')
{
dishz(x, y, s, WHITE, size);
x+=20*size;
s+=2;
for (i=0; i