亲宝软件园·资讯

展开

C语言之飞机大战游戏

weixin_38554391 人气:0

技术原型

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;
 }

加载全部内容

相关教程
猜你喜欢
用户评论