C语言之飞机大战

C语言之飞机大战

技术原型

  1. void gotoxy(int x, int y) 函数,该函数可以使光标去到(x,y)的位置进行打印;
  2. 链表,用于存储状态;
  3. windows.h中有非阻塞输入,_kbhit();
  4. 随机生成数;
  5. 视觉暂留;
  6. 碰撞检测;
  7. 清屏函数;
  8. 设置边界;

技术路线

  1. 设置一个边界;
  2. 维护一个子弹的列表;
  3. 维护一个敌机的列表;
  4. 初始化飞机的位置;
  5. 每隔一秒钟生成一架敌机,生成位置x坐标随机,坐标为0;
  6. 设置点击空格生成子弹;
  7. 设置while(1)循环,在其中每次进行清屏和更新;
  8. 每次更新遍历子弹链表,使所有子弹的位置向上移动1;
  9. 每次更新遍历敌机链表,使所有敌机的位置向下移动1;
  10. 碰撞检测,遍历子弹和敌机列表,发现碰撞则从各自的链表中移除碰撞的节点;
  11. 当有敌机碰撞到本机游戏结束;
  12. 当子弹或者敌机碰撞到边界,则从链表中移除;
  13. 每次检测到碰撞加一分。

实现效果

在这里插入图片描述

花费时间

约6小时30分钟

代码

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <windows.h>
#include <math.h>


struct node {
	int 			x;
	int				y;
	struct node*    next;
};

typedef struct node  node_t;
typedef struct node* nodeptr_t;

void gotoxy(int x, int y); //光标定位函数
void print_plane(int x, int y); //打印飞机
nodeptr_t generate_bullet(nodeptr_t listnode, int x, int y); //生成子弹
void print_bullet(nodeptr_t listnode); //打印子弹
nodeptr_t update_bullet(nodeptr_t listnode); //更新子弹位置
nodeptr_t generate_target(nodeptr_t listnode, int x); //生成敌机
void print_target(nodeptr_t listnode); //打印敌机
nodeptr_t update_target(nodeptr_t listnode); //更新敌机位置
int collision_detection(nodeptr_t bulletlist, nodeptr_t targetlist); //碰撞检测
bool is_gameover(int x,int y, nodeptr_t targetlist); // 游戏结束
void clear(nodeptr_t bulletlist, nodeptr_t targetlist);


int main() {
	int plane_x = 0, plane_y = 19; //飞机位置
	char control; //输入
	bool isfire = 0; //是否开火

	nodeptr_t target = nullptr; //敌机链表
	target = (nodeptr_t)malloc(sizeof(node_t));
	target->next = nullptr;
	target->x = 0;
	target->y = 0;

	nodeptr_t bullet = nullptr; //子弹链表
	bullet = (nodeptr_t)malloc(sizeof(node_t));
	bullet->next = nullptr;
	bullet->x = 0;
	bullet->y = 0;

	int subtime = 0;
	time_t starttime;
	starttime = time(NULL);
	int grade = 0; //分数
	int targetspeed = 0;
	int bulletspeed = 0;

	while(1)
	{
		system("cls");
		time_t currenttime;
		currenttime = time(NULL);
		//每隔一秒生成一架敌机
		if (currenttime - starttime - subtime > 0)
		{
			srand((unsigned)time(NULL));
			unsigned int target_y = rand() % 14 + 3;
			target = generate_target(target, target_y);
		}
		subtime = currenttime - starttime;
		//开火则生成子弹
		if (isfire)
		{
			bullet = generate_bullet(bullet, plane_x, plane_y - 1);
			isfire = 0;
		}
		//打印敌机
		print_target(target);
		targetspeed++;
		if(targetspeed % 2 == 0)
			target = update_target(target);
		//打印子弹
		print_bullet(bullet);
		bulletspeed++;
		if (bulletspeed % 2 == 0)
			bullet = update_bullet(bullet);
		//碰撞检测
		grade = grade + collision_detection(bullet, target);
		gotoxy(0, 25);
		printf("SCORE: %d", grade);
		//打印飞机
		print_plane(plane_x, plane_y);
		//敌机本机是否相撞
		bool isgameover = is_gameover(plane_x, plane_y, target);
		//Sleep(100);
		//非阻塞键盘输入
		if (isgameover)
		{
			clear(target, bullet);
			plane_x = 0;
			plane_y = 19;
			isfire = 0;
			system("cls");
			gotoxy(8, 8);
			printf("SCORE: %d", grade);
			gotoxy(8, 9);
			printf("GAME OVER");
			grade = 0;
			break;
		}
		if (_kbhit())
		{
			control = _getch();
			if (control == ' ')
				isfire = 1;
			else
				isfire = 0;
			if (control == 'w' && plane_y > 0)
				plane_y--;
			if (control == 's' && plane_y < 20)
				plane_y++;
			if (control == 'a' && plane_x > 0)
				plane_x--;
			if (control == 'd' && plane_x < 20)
				plane_x++;
		}


	}
	return 0;
}

void gotoxy(int x, int y)//光标定位函数
{
	COORD p;//定义结构体变量p
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//获取当前函数句柄
	p.X = x;
	p.Y = y;//将光标的目标移动位置传递给结构体
	SetConsoleCursorPosition(handle, p);//移动光标
	return;
}

void print_plane(int x, int y) //打印飞机
{
	if (x == 0)
	{
		gotoxy(x, y);
		printf("*");
		gotoxy(x, y + 1);
		printf("***");
		gotoxy(x, y + 2);
		printf(" *");
	}
	else if (x == 1)
	{
		gotoxy(x, y);
		printf("*");
		gotoxy(x-1, y + 1);
		printf("****");
		gotoxy(x-1, y + 2);
		printf("* *");
	}
	else if (x == 20)
	{
		gotoxy(x, y);
		printf("*");
		gotoxy(x - 2, y + 1);
		printf("***");
		gotoxy(x - 1, y + 2);
		printf("* ");
	}
	else if (x == 19)
	{
		gotoxy(x, y);
		printf("*");
		gotoxy(x - 2, y + 1);
		printf("****");
		gotoxy(x - 1, y + 2);
		printf("* *");
	}
	else
	{
		gotoxy(x, y);
		printf("*");
		gotoxy(x - 2, y + 1);
		printf("*****");
		gotoxy(x - 1, y + 2);
		printf("* *");
	}
	return;
}

nodeptr_t generate_bullet(nodeptr_t listnode, int x, int y)
{
	nodeptr_t newbullet = nullptr; //子弹链表
	newbullet = (nodeptr_t)malloc(sizeof(node_t));
	newbullet->next = listnode->next;
	newbullet->x = x;
	newbullet->y = y;
	listnode->next = newbullet;
	return listnode;
}

void print_bullet(nodeptr_t listnode)
{
	nodeptr_t templist = listnode;
	while (templist->next != nullptr)
	{
		gotoxy((templist->next->x), templist->next->y);
		printf("|");
		templist = templist->next;
	}
	return;
}

nodeptr_t update_bullet(nodeptr_t listnode)
{
	nodeptr_t templist = listnode;
	while (templist->next != nullptr)
	{
		if (templist->next->y > 0)
			(templist->next->y)--;
		else
		{
			nodeptr_t tempnode = templist->next;
			templist->next = tempnode->next;
			tempnode->next = nullptr;
			free(tempnode);
		}
		if (templist->next != nullptr)
			templist = templist->next;
		else
			break;
	}
	return listnode;
}

nodeptr_t generate_target(nodeptr_t listnode, int x)
{
	nodeptr_t newtarget = nullptr; //子弹链表
	newtarget = (nodeptr_t)malloc(sizeof(node_t));
	newtarget->next = listnode->next;
	newtarget->x = x;
	newtarget->y = 0;
	listnode->next = newtarget;
	return listnode;
}

void print_target(nodeptr_t listnode)
{
	nodeptr_t templist = listnode;
	while(templist->next != nullptr)
	{
		gotoxy(templist->next->x, templist->next->y);
		printf("+");
		templist = templist->next;
	}
	return;
}

nodeptr_t update_target(nodeptr_t listnode)
{
	nodeptr_t templist = listnode;
	while (templist->next != nullptr)
	{
		if (templist->next->y < 21)
			(templist->next->y)++;
		else
		{
			nodeptr_t tempnode = templist->next;
			templist->next = tempnode->next;
			tempnode->next = nullptr;
			free(tempnode);
		}
		if (templist->next != nullptr)
			templist = templist->next;
		else
			break;
	}
	return listnode;
}

int collision_detection(nodeptr_t bulletlist, nodeptr_t targetlist)
{
	int grade = 0;
	nodeptr_t tempbulletlist = bulletlist;
 	while(tempbulletlist->next != nullptr)
 	{
		nodeptr_t temptargetlist = targetlist;
 		while(temptargetlist->next != nullptr)  
 		{
			
 			if(temptargetlist->next->x == (tempbulletlist->next->x) && temptargetlist->next->y > tempbulletlist->next->y)
 			{
     			nodeptr_t tempnode = temptargetlist->next;
				temptargetlist->next = tempnode->next;
				tempnode->next = nullptr;
				free(tempnode);

				tempnode = tempbulletlist->next;
				tempbulletlist->next = tempnode->next;
				tempnode->next = nullptr;

 				free(tempnode);
				grade++;
				break;

 			}
			if (temptargetlist->next != nullptr)
				temptargetlist = temptargetlist->next;
			else
				break;
 		}
		if (tempbulletlist->next != nullptr)
			tempbulletlist = tempbulletlist->next;
		else
			break;
 	}
	return grade;
}

 bool is_gameover(int x, int y, nodeptr_t targetlist)
 {
	 nodeptr_t temptargetlist = targetlist;
	 while (temptargetlist->next != nullptr)
	 {
		 int tempsub = abs((temptargetlist->next->x) - x);
		 if (tempsub == 0 && temptargetlist->next->y > y)
		 {
			 return 1;
		 }
		 else if(tempsub == 1 && temptargetlist->next->y > y + 1)
		 {
			 return 1;
		 }
		 else if (tempsub == 2 && temptargetlist->next->y > y + 1)
		 {
			 return 1;
		 }
		 temptargetlist = temptargetlist->next;
	 }
	 return 0;
 }

 void clear(nodeptr_t bulletlist, nodeptr_t targetlist)
 {
	 while (bulletlist->next != nullptr)
	 {
		 nodeptr_t temp = bulletlist->next;
		 bulletlist->next = temp->next;
		 //temp->next = nullptr;
		 free(temp);
	 }
	 while (targetlist->next != nullptr)
	 {
		 nodeptr_t temp = targetlist->next;
		 targetlist->next = temp->next;
		 //temp->next = nullptr;
		 free(temp);
	 }
	 return;
 }
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值