基于Easyx制作的飞机大战

2024-02-19 06:40
文章标签 制作 easyx 大战 飞机

本文主要是介绍基于Easyx制作的飞机大战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

来源:微信公众号「编程学习基地」

目录

    • 飞机大战
      • 结构体
      • 游戏三部曲
        • 初始化Game_Init()
        • 绘制Game_Paint()
        • 数据更新Game_Updata()
      • 主函数
      • 按键的处理
        • 说明
      • 链表的增删操作
        • 添加敌方飞机
        • 敌方飞机移动
        • 添加子弹
        • 子弹移动

飞机大战

基于链表操作的飞机大战游戏

运行截图:
在这里插入图片描述
源码获取: 飞机大战.

结构体

定义飞机大战所需结构体并全局定义结构体成员

//子弹的结构体 
struct bullet
{int x;int y;struct bullet* pnext;
};
// 我方飞机   
struct plane  //我方飞机的结构体
{int x, y;			//飞机的坐标bool exist;			//飞机是否存活   exist==false(0)  飞机灭亡 ;  exist=ture(1) 飞机存在struct bullet* bt;  //子弹
};
//敌方飞机 
struct enemy
{int x, y; //敌方飞机的坐标struct enemy* pnext; //用来保存下一个飞机的地址 
};
struct plane myPlane;		//定义我方飞机的结构体变量.
struct enemy* emy_Phead;	//敌方飞机链表的头节点. 

游戏三部曲

游戏三部曲:初始化,绘制,数据更新

初始化Game_Init()

包括加载图片和初始化游戏数据

void Game_Init()
{loadimage();myPlane.y = 700;			myPlane.x = rand() % 500;   //范围 0~499 myPlane.exist = true;		//飞机存在为true//初始化子弹链表的头结点myPlane.bt = (struct bullet *)malloc(sizeof(struct bullet));myPlane.bt->pnext = NULL;//初始化敌方飞机的头结点emy_Phead = (struct enemy *)malloc(sizeof(struct enemy));emy_Phead->pnext = NULL;//初始化其他变量begin = GetTickCount();t1 = GetTickCount();g_bk.X = 0;g_bk.Y = 0;//开局先添加两架敌方飞机AddEnemy();AddEnemy();
}
绘制Game_Paint()

包含背景图片、我方飞机,敌方飞机、子弹的绘制

void Game_Paint()
{//开始批量绘图BeginBatchDraw();cleardevice();	//刷新屏幕/*========================贴背景图片========================*/putimage(g_bk.X, g_bk.Y, &g_back);putimage(g_bk.X, g_bk.Y - 768, &g_back);/*========================贴我方飞机========================*///判断我方的飞机是否存活,如果存活就贴飞机,否者就贴游戏失败的图片.if (myPlane.exist){putimage(myPlane.x, myPlane.y, &g_plane[1], SRCAND);putimage(myPlane.x, myPlane.y, &g_plane[0], SRCPAINT);}else{//游戏结束//贴 Game Over图片}/*========================贴敌方飞机========================*///遍历链表去绘制struct enemy* pTmp = emy_Phead->pnext; //指向第一架敌方飞机while (pTmp){putimage(pTmp->x, pTmp->y, &g_enemy[1], SRCAND);putimage(pTmp->x, pTmp->y, &g_enemy[0], SRCPAINT);//要往后遍历pTmp = pTmp->pnext;}/*========================贴我方飞机子弹========================*/struct bullet* pBullet = myPlane.bt->pnext;while (pBullet) //贴图{putimage(pBullet->x, pBullet->y, &g_Bullet, SRCPAINT);pBullet = pBullet->pnext;}//结束批量绘图EndBatchDraw();
}
数据更新Game_Updata()

包含敌方飞机,子弹,背景的移动,我方飞机的移动有按键消息来控制不在此列

void Game_Updata()
{EnemyMove();	//飞机移动BulletMove();	//子弹移动BackMove();		//背景移动
}

主函数

通过不断获取end的时间来控制游戏的绘制和数据更新

通过不断获取t2的时间来控制敌方飞机的数量

通过不断获取按键消息来控制我方飞机的移动

int main()
{initgraph(512, 768);	/* 初始化图形库 */Game_Init();	/* 游戏的初始化 */while (1){end = GetTickCount();	/* 获取end时间 */t2 = GetTickCount();	/* 获取t2时间 */if (kbhit())			/* 判断是否有按键消息 */{PlaneMove();	/* 玩家操作飞机移动和开火 */}if (end - begin >= 50){Game_Paint();	/* 游戏的绘制 */Game_Updata();	/* 游戏的跟新 */begin = end;}if (t2 - t1 >= 3000){AddEnemy();		/* 添加敌方飞机 */AddEnemy();		/* 添加敌方飞机 */t1 = t2;}}closegraph();	/* 关闭图形库 */return 0;
}

按键的处理

玩家操作实现功能

  1. 实现我方飞机的上下左右移动
  2. 实现空格添加子弹
void PlaneMove()
{// 获取键盘按下信息 char ch = getch();  //获取键盘输入switch (ch)		// 上 下 左  右  发射子弹{case 72:		//往上走    72 是 ↑ 键值case 'W':case 'w'://在里面定义变量 就要加{}myPlane.y -= 20;if (myPlane.y < 0){myPlane.y = 0;}break;case 80:  //往下走case 'S':case 's':myPlane.y += 20;if (myPlane.y>668){myPlane.y = 700;}break;case 75:  //左边case 'A':case 'a':myPlane.x -= 20;if (myPlane.x < 0){myPlane.x = 0;}break;case 77: //右边case 'D':case 'd':myPlane.x += 20;if (myPlane.x > 437){myPlane.x = 437;}break;case 32: //32是空格键//调用函数  发射子弹FireBullet();break;}
}
说明

kbbhit:检查控制台的键盘输入。

int kbhit( void );

返回值:

如果按下某个键,则**_kbhit**返回一个非零值。否则,它返回0。

链表的增删操作

添加敌方飞机

如果ni链表操作ok的话这个敌方飞机的添加操作是完全没问题的,就一个头插

void AddEnemy()
{//申请新结点struct enemy* newnode = (struct enemy*)malloc(sizeof(struct enemy));newnode->x = rand() % 412;	//x坐标 随机newnode->y = -100;			//y坐标 固定//头插newnode->pnext = emy_Phead->pnext;emy_Phead->pnext = newnode;
}
敌方飞机移动

简简单单的链表遍历和删除操作,掌握基础就掌握力量

void EnemyMove()
{struct enemy* pTmp = emy_Phead;//指向敌方飞机的头结点struct enemy* pDelete;while (pTmp->pnext != NULL){pTmp->pnext->y += rand() % 10; //可快可慢//判断飞机是否越界了if (pTmp->pnext->y >= 800){//把越界的飞机销毁掉pDelete = pTmp->pnext;pTmp->pnext = pDelete->pnext;free(pDelete);pDelete = NULL;continue;}//往后遍历pTmp = pTmp->pnext;}
}
添加子弹

又是一个链表的头插操作,链表很重要啊

void FireBullet()
{//发射子弹其实就是创建结点.struct bullet *newbullet = (struct bullet *)malloc(sizeof(struct bullet));//给x和y 赋值newbullet->x = myPlane.x + 28; //子弹的x坐标		 newbullet->y = myPlane.y - 10;  //子弹的 y坐标//连接结点 newbullet->pnext = myPlane.bt->pnext;myPlane.bt->pnext = newbullet;
}
子弹移动

这里就比较复杂了,但终究还是链表的遍历和匹配操作,注释很清楚,仔细看

  1. 通过遍历每一个子弹来实现子弹的移动
  2. 通过将每一个子弹和敌方飞机做匹配判断是否杀敌
void BulletMove()
{//遍历每一个子弹 让他们向上移动struct bullet* pPlane = myPlane.bt;			//指向子弹的头结点struct bullet* pDelete;						//指向要删除的子弹while (pPlane->pnext != NULL){//子弹的移动速度 都是一样的pPlane->pnext->y -= 10;//处理子弹越界if (pPlane->pnext->y < -50){pDelete = pPlane->pnext;pPlane->pnext = pDelete->pnext;free(pDelete);pDelete = NULL;continue;}//处理子弹撞到飞机   子弹坐标 跟敌方飞机做比较 // 遍历敌方飞机 struct enemy *pEnemy = emy_Phead; struct enemy *pDeleteEnemy;  //遍历敌方飞机的循环while (pEnemy->pnext != NULL){if ((pPlane->pnext->x >= pEnemy->pnext->x) && pPlane->pnext->x <= (pEnemy->pnext->x + 80) && pPlane->pnext->y <= (pEnemy->pnext->y + 100)){//飞机爆炸的图片 贴上去 //把飞机释放掉pDeleteEnemy = pEnemy->pnext;pEnemy->pnext = pDeleteEnemy->pnext;free(pDeleteEnemy);pDeleteEnemy = NULL;// 把子弹释放掉 pDelete = pPlane->pnext;pPlane->pnext = pDelete->pnext;free(pDelete);pDelete = NULL;break;	//这个break是个坑,当子弹击中敌方某一架飞机的时候已经不需要继续遍历后面的飞机了,因为子弹已经没有了}//判断敌方飞机是不是NULLif (pEnemy->pnext == NULL){break;}pEnemy = pEnemy->pnext;}//判断子弹是不是NULLif (pPlane->pnext == NULL){break;  //如果子弹没了就break}pPlane = pPlane->pnext;}
}

这篇关于基于Easyx制作的飞机大战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/723812

相关文章

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

OpenStack离线Train版安装系列—0制作yum源

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack镜像制作系列5—Linux镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作

OpenStack镜像制作系列4—Windows Server2019镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录  CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系

OpenStack镜像制作系列2—Windows7镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系列

OpenStack镜像制作系列1—环境准备

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作

CSDN:OpenStack镜像制作教程指导(全)

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录,涉及基本环境准备、常见类型操作系统的镜像制作。 让你可以从零开始安装一个操作系统,并支持个性化制作OpenStack镜像。 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows

docker学习系列(四)制作基础的base项目镜像--jdk+tomcat

前面已经完成了docker的安装以及使用,现在我们要将自己的javaweb项目与docker结合 1.1准备jdk+tomcat软件 ​​我下载了apache-tomcat-7.0.68.tar.gz和jdk-7u79-linux-x64.tar.gz,存储于Linux机器的本地目录/usr/ect/wt/下(利用xshell上传)。利用linux命令 tar -zxvf apache-tom

选项卡制作问题--折磨了我一整天,记录下来

看老曹的html+css课程,学习html+css基础,讲到制作选项卡,以京东商城的选项卡为例,效果如下: 看着他做出来很简单,结果自己做花了2个多小时才有个样子,效果是这样的: 内部代码如下 <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-