小游戏之飞机躲子弹

游戏在终端运行,使用左右键移动飞机。飞机撞上子弹或撞上边界都会结束游戏。

源代码:

// gcc plane.c -lpthread
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define KEYCODE_L 0x44   // 向左按键
#define KEYCODE_R 0x43   // 向右按键

int kfd = 0;
struct termios cooked, raw;
char dir = 0;    // 飞机移动方向

// 获取键盘响应:左、右键
void* get_dir(void *a)
{
	while(1)
	{
		char c;                                                              
		tcgetattr(kfd, &cooked); // 得到 termios 结构体保存,然后重新配置终端
		memcpy(&raw, &cooked, sizeof(struct termios));
		raw.c_lflag &=~ (ICANON | ECHO);                       
		raw.c_cc[VEOL] = 1;
		raw.c_cc[VEOF] = 2;
		tcsetattr(kfd, TCSANOW, &raw);

		if(read(kfd, &c, 1) < 0)
		{
			perror("read():");
			exit(-1);
		}
		tcsetattr(kfd, TCSANOW, &cooked);//在程序结束时在恢复原来的配置
		dir = c;
	}
}

unsigned char map[17][36] = {0};   // 游戏地图,先初始化边界
unsigned char plane = 18; //初始化飞机位置
unsigned char bullet[6] = {5,18,10,15,25,32};//初始化子弹水平位置
unsigned char height[6] = {1,1,3,3,5,5};//初始化子弹垂直位置

// 更新地图数据
void update_map()
{	
	int i, j;
	//更新边界
	for (i = 0; i < 17; i++)
	{
		for (j = 0; j < 36; j++)
		{
			if (i == 0 || i == 16 || j == 0 || j == 35)  // 代表地图的边界
			{
				map[i][j] = '#';
			}
			else
			{
				map[i][j] = ' ';
			}
			
		}
	}
	// 更新飞机和子弹
	map[15][plane] = '@';
	map[14][plane] = '@';
	map[15][plane+1] = '@';
	map[15][plane-1] = '@';
	
	for (i = 0;i < 6;i++)
	{
		map[height[i]][bullet[i]] = '*';
	}
	
}

// 打印地图
void print_map()
{
	int i, j;
	for (i = 0; i < 17; i++)
	{
		for (j = 0; j < 36; j++)
		{
			printf ("%c", map[i][j]);
		}
		printf ("\n");
	}
	usleep(400000);           // 让程序睡眠一段时间
	system("clear");    // 清屏
}

// 生成子弹
unsigned char generate_bullet()
{
	unsigned char new_bullet;
	do
	{
		new_bullet = rand() % 35;
			
	}while (new_bullet == 0);
	
	return new_bullet;
}

// 移动飞机
void move_plane()
{
	
	// 判断移动方向
	switch (dir)
	{
		case KEYCODE_L:   // 向左移动
			plane--;
			dir = 0;
			break;
		case KEYCODE_R:   // 向右移动
			plane++;
			dir = 0;
			break;
	}
}

//子弹落下
void move_bullet()
{
	int i;
	for(i = 0;i < 6;i += 2)
	{
		if(height[i] >= 16)
		{
			bullet[i] = generate_bullet();//获得新的食物
			height[i] = 1;
		}
		height[i] += 1;//子弹速度为1
	}
	for(i = 1;i < 6;i += 2)
	{
		if(height[i] >= 16)
		{
			bullet[i] = generate_bullet();
			height[i] = 1;
		}
		height[i] += 2;//子弹速度为2
	}
}

// 判断有没有撞子弹或边界,如果返回值是0代表没撞,1代表撞了
int isalive()
{
	if ((plane-1) == 0 || (plane+1) == 35)//撞上边界
	{
		return 1;
	}
	int i;
	for (i = 0;i < 6;i++)
	{
		if (height[i] == 15 && bullet[i] == plane)//撞上机身
		{
			return 1;
		}
		if (height[i] == 15 && bullet[i] == plane+1)//撞上右翼
		{
			return 1;
		}
		if (height[i] == 15 && bullet[i] == plane-1)//撞上左翼
		{
			return 1;
		}
	}
	
	return 0;
}

int main()
{
	srand ((unsigned int)time(NULL));   // 生成一个随机数的种子
	// 开启一个线程用于获取键盘的左右键响应
	pthread_t tid1;
	pthread_create(&tid1, NULL, get_dir, NULL);
	system("clear"); 
	update_map();//初始化地图
	while(1)
	{
		move_plane();//移动飞机
		move_bullet();//子弹落下
		update_map();// 更新地图数据
		print_map();// 打印地图
		
		if (isalive() == 1)//判断子弹是否击中飞机或飞机是否撞边界
		{
			break;
		}	
	}
	tcsetattr(kfd, TCSANOW, &cooked);//在程序结束时在恢复原来的配置
	
	printf ("Game Over!\n");
	return 0;
}





小游戏之飞机躲子弹_第1张图片

欢迎大家对其进行改进,希望能一起交流。

你可能感兴趣的:(小游戏)