当前位置: 首页 > news >正文

基于easyx库的C/C++游戏编程实例-飞机大战

飞机大战游戏设计

首先创建飞机/子弹结构:

struct Plane
{int x;int y;bool live;int width;int height;int type;int hp;
}player,bul[BUL_NUM],enemy[ENE_NUM];

你需要加载图片:

void ImageLoad()
{//背景loadimage(&bg[0], "./image/飞机大战bg.png");loadimage(&bg[1], "./image/Background.png");loadimage(&bg[2], "./image/restart.png");//飞机loadimage(&img_player[0], "./image/Plane1.png");loadimage(&img_player[1], "./image/Plane2.png");//子弹loadimage(&img_bullet[0], "./image/Bullet1.png");loadimage(&img_bullet[1], "./image/Bullet2.png");//敌机loadimage(&img_enemy[0][0], "./image/enemy_small1.png");loadimage(&img_enemy[0][1], "./image/enemy_small2.png");loadimage(&img_enemy[1][0], "./image/enemy_big1.png");loadimage(&img_enemy[1][1], "./image/enemy_big2.png");
}

游戏初始化设置:


void GameInit()
{//创建一个窗口,控制窗口台是自动创建的,图形窗口是需要自己手动创建的(后加 SHOWCONSOLE)initgraph(WIDTH, HEIGHT );//飞机初始状态player.x = WIDTH / 2-53;player.y = HEIGHT - 130;player.live = true;//子弹初始状态for (int i = 0; i < BUL_NUM; i++){bul[i].live = false;}//敌机初始状态for (int i = 0; i < ENE_NUM; i++){enemy[i].live = false;EnemyType(i);}//游戏初始界面ImageLoad();putimage(0, 0, &bg[0]);setbkmode(TRANSPARENT);//设置透明背景settextcolor(YELLOW);settextstyle(60, 0, "黑体");char begin[] = { "打飞机" };outtextxy(WIDTH / 3, HEIGHT / 4, begin);settextstyle(20, 0, "黑体");char b[] = { "按“B”开始游戏" };outtextxy(WIDTH / 3, HEIGHT / 2+50, b);while (!GetAsyncKeyState('B'));
}

游戏界面加载:

游戏界面加载
void GameDraw()
{//双缓冲绘图BeginBatchDraw();//加载图片ImageLoad();//背景putimage(0, 0, &bg[1]);//飞机putimage(player.x, player.y , &img_player[0],NOTSRCERASE);//先贴透明图putimage(player.x, player.y, &img_player[1],SRCINVERT);//子弹for (int i = 0; i < BUL_NUM; i++){if (bul[i].live){putimage(bul[i].x, bul[i].y, &img_bullet[0], NOTSRCERASE);//先贴透明图putimage(bul[i].x, bul[i].y, &img_bullet[1], SRCINVERT);}}//敌机for (int i = 0; i < ENE_NUM; i++){if (enemy[i].live){if (enemy[i].type == BIG){putimage(enemy[i].x, enemy[i].y, &img_enemy[1][0], NOTSRCERASE);//先贴透明图putimage(enemy[i].x, enemy[i].y, &img_enemy[1][1], SRCINVERT);}else //if (enemy[i].type == SMALL){putimage(enemy[i].x, enemy[i].y, &img_enemy[0][0], NOTSRCERASE);//先贴透明图putimage(enemy[i].x, enemy[i].y, &img_enemy[0][1], SRCINVERT);}}}//分数settextstyle(20, 0, "黑体");char str[] = { "当前分数:" };outtextxy(WIDTH-150, 10, str);char t[500];sprintf_s(t, "%d", score);outtextxy(WIDTH - 30, 10, t);EndBatchDraw();
}

随机一定比例地分配敌机类型:


void EnemyType(int i)
{int flag = rand() % 10;if (flag>=0&&flag<2){enemy[i].type = BIG;enemy[i].hp = 3;enemy[i].width = 86;enemy[i].height = 125;}else{enemy[i].type = SMALL;enemy[i].hp = 1;enemy[i].width = 71;enemy[i].height = 52;}
}

子弹发射配置:


void BulletCreate()
{for (int i = 0; i < BUL_NUM; i++){if (!bul[i].live){bul[i].x = player.x + 41;bul[i].y = player.y;bul[i].live = true;break;}}
}

子弹移动设置:


void BulletMove(int speed)
{for (int i = 0; i < BUL_NUM; i++){if (bul[i].live){bul[i].y -= speed;if (bul[i].y < 0){		bul[i].live = false;}}}
}

飞机移动和子弹发射控制:


void PlayerMove(int speed)
{
#if 0if (_kbhit())	//有按键按下返回真{char key = _getch();		//阻塞函数,不按下停住不执行switch (key){case 'w':case 'W':case 72:player.y -= speed;break;case 's':case 'S':case 80:player.y += speed;break;case 'a':case 'A':case 75:player.x -= speed;break;case 'd':case 'D':case 77:player.x += speed;break;}}
#elif 1//Windows函数,	非阻塞//按键大写可检测到大小写,小写都检测不到if (GetAsyncKeyState(VK_UP)|| GetAsyncKeyState('W')){if (player.y > 0){player.y -= speed;}}if (GetAsyncKeyState(VK_DOWN) | GetAsyncKeyState('S')){if (player.y < HEIGHT - 124){player.y += speed;}}if (GetAsyncKeyState(VK_LEFT) | GetAsyncKeyState('A')){if (player.x > 0){player.x -= speed;}}if (GetAsyncKeyState(VK_RIGHT) | GetAsyncKeyState('D')){if (player.x < WIDTH - 106){player.x += speed;}	}
#endif // 0if (GetAsyncKeyState(VK_SPACE)&&Timer(100,0)){BulletCreate();}
}

随机位置产生一个敌机(敌机会重叠,未优化。可以利用坐标判断飞机之间是否重叠,不重叠则可以创建敌机,否则重新生成坐标进行循环):


void EnemyCreate()
{for (int i = 0; i < ENE_NUM; i++){if (!enemy[i].live){enemy[i].x = rand() % (WIDTH - 86);enemy[i].y = rand()%20;enemy[i].live = true;EnemyType(i);//printf("pos(%d,%d) %d %d\n", enemy[i].x, enemy[i].y, enemy[i].live, enemy[i].hp);	//检测敌机状态,用于调试break;}}
}

敌机移动设置:


void EnemyMove(int speed)
{for (int i = 0; i < ENE_NUM; i++){if (enemy[i].live){enemy[i].y +=speed;if(enemy[i].y>HEIGHT){ enemy[i].live = false;}}}
}

敌机与子弹碰撞检测设置:

bool Bump()
{for (int i = 0; i < ENE_NUM; i++){if (!enemy[i].live)continue;for (int j = 0; j < BUL_NUM; j++){if (!bul[j].live)continue;if (bul[j].x + 12 > enemy[i].x && bul[j].x + 12 < enemy[i].x + enemy[i].width/2&& bul[j].y > enemy[i].y && bul[j].y < enemy[i].y + enemy[i].height/2){bul[j].live = false;enemy[i].hp--;}}if (enemy[i].hp <= 0){enemy[i].live = false;if (enemy[i].type == BIG){score += 3;}else if (enemy[i].type == SMALL){score++;}			}if (player.x + 106/2 > enemy[i].x && player.x < enemy[i].x + enemy[i].width/2&& player.y > enemy[i].y && player.y < enemy[i].y + enemy[i].height/2){return false;}}return true;	//	默认true,可不写
}

由于文件执行速度较快,需要加一定的延时,以便肉眼可见。

再着需要一个定时器,定时发射敌机:

bool Timer(int ms, int id)
{static DWORD t[TimerNum];if (clock() - t[id] > ms){t[id] = clock();return true;}return false;
}

执行主函数:

int main()
{srand((unsigned int)time(NULL));	//让随机数每次进入时都不同,只调用一次!!!GameInit();while (1){while (1){//Sleep(1);	//可以让速度更慢GameDraw();PlayerMove(3);BulletMove(5);if (Timer(300, 1)){EnemyCreate();}if (Timer(10, 2)){EnemyMove(2);}FlushBatchDraw();if (!Bump())break;//printf("无人能挡,所向披靡");	//用于阻塞测试}settextcolor(RED);settextstyle(70, 0, "黑体");char end[] = { "GAME OVER!" };outtextxy(WIDTH / 6, HEIGHT / 3, end);settextstyle(40, 0, "黑体");char b[] = { "按“V”重新开始游戏" };outtextxy(WIDTH / 6, HEIGHT / 2, b);while (!GetAsyncKeyState('V'));GameInit();}return 0;
}

示例视频:

由视频可见,一个基本的飞机大战游戏已经成功设计了,不过在画面上可以进行进一步的优化,玩法上可以自己增加机制提高游戏的趣味性。

相关文章:

基于easyx库的C/C++游戏编程实例-飞机大战

飞机大战游戏设计 首先创建飞机/子弹结构&#xff1a; struct Plane {int x;int y;bool live;int width;int height;int type;int hp; }player,bul[BUL_NUM],enemy[ENE_NUM];你需要加载图片&#xff1a; void ImageLoad() {//背景loadimage(&bg[0], "./image/飞机大…...

stitcher类实现多图自动拼接

效果展示 第一组&#xff1a; 第二组&#xff1a; 第三组&#xff1a; 第四组&#xff1a; 运行代码 import os import sys import cv2 import numpy as npdef Stitch(imgs,savePath): stitcher cv2.Stitcher.create(cv2.Stitcher_PANORAMA)(result, pano) stitcher.st…...

Ubuntu下udp通信

一、知识准备阶段 socket是什么&#xff1f;套接字是什么&#xff1f; https://blog.csdn.net/m0_37925202/article/details/80286946 Socket程序从Windows移植到Linux下的一些注意事项 sockaddr和sockaddr_in详解 bzero和memset函数 函数原型&#xff1a;void bzero&…...

拌合楼管理软件开发(十三) 对接耀华XK3190-A9地磅(实战篇)

前言: 实战开整 目前而言对于整个拌合楼管理软件开发,因为公司对这个项目还处于讨论中,包括个人对其中的商业逻辑也存在一些质疑,都是在做一些技术上的储备.很早就写好了串口与地磅对接获取代码,也大概知道真个逻辑,这次刚好跟库区沟通,远程连接到磅房电脑,开始实操一下. 一、地…...

FastAPI+React全栈开发10 MongoDB聚合查询

Chapter02 Setting Up the Document Store with MongoDB 10 Aggregation framework FastAPIReact全栈开发10 MongoDB聚合查询 In the following pages, we will try to provide a brief introducton to the MongoDB aggregation framework, what it is, what benefits it of…...

python 报错问题汇总

error: [WinError 32] 另一个程序正在使用此文件&#xff0c;进程无法访问。: d:\\anaconda\\envs\\yolov5\\lib\\site-packages\\ISR-2.2.0-py3.7.egg 解决方法&#xff1a;重启pycharm python-contrib 无法安装 opencv-contrib-python 安装包网址&#xff1a;安装包下载链接…...

6.5物联网RK3399项目开发实录-驱动开发之LCD显示屏使用(wulianjishu666)

90款行业常用传感器单片机程序及资料【stm32,stc89c52,arduino适用】 链接&#xff1a;https://pan.baidu.com/s/1M3u8lcznKuXfN8NRoLYtTA?pwdc53f LCD使用 简介 AIO-3399J开发板外置了两个LCD屏接口&#xff0c;一个是EDP&#xff0c;一个是LVDS&#xff0c;接口对应板…...

「Android高级工程师」BAT大厂面试基础题集合-下-Github标星6-5K

C、 com.android.provider.contact D、 com.android.provider.contacts 11.下面关于ContentProvider描述错误的是&#xff08;&#xff09;。 A、 ContentProvider可以暴露数据 B、 ContentProvider用于实现跨程序共享数据 C、 ContentProvider不是四大组件 D、 ContentP…...

【算法】基数排序

简介 基数排序&#xff08;*Radix sort&#xff09;是一种非比较排序算法&#xff08;non-comparative sorting algorithm&#xff09;。现代计算机的基数排序算法由 计数排序 算法的开发人哈罗德H西华德&#xff08;Harold H. Seward&#xff09;于1954年于麻省理工大学开发。…...

2核2G服务器优惠价格轻量61元一年,CVM价格313元15个月

腾讯云2核2G服务器多少钱一年&#xff1f;轻量服务器61元一年&#xff0c;CVM 2核2G S5服务器313.2元15个月&#xff0c;轻量2核2G3M带宽、40系统盘&#xff0c;云服务器CVM S5实例是2核2G、50G系统盘。腾讯云2核2G服务器优惠活动 txybk.com/go/txy 链接打开如下图&#xff1a;…...

不同Python版本和wxPython版本用pyinstaller打包文件大小对比

1、确定wxPython和Python版本的对应关系 在这里可以找到Python支持的所有wxPython版本&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple/wxpython/ 由于Python从3.6版本开始支持f字符串、从3.9版本开始不支持Windows7操作系统&#xff0c;所以我仅筛选3.6-3.8之间的版本…...

【C语言】结构体详解(一)

目录 1、什么是结构体? 2、结构体成分 3、结构体变量的定义与初始化 3.1、结构体变量的三种定义方式 3.2、结构体变量的初始化 4、结构体成员的访问&#xff08;两种方式&#xff09; 4.1、直接访问 4.2、间接访问 5、结构的特殊声明 5.1、不完全声明&#xff08;匿…...

AI时代-普通人的AI绘画工具对比(Midjouney与Stable Diffusion)

AI时代-普通人的AI绘画工具对比&#xff08;Midjouney与Stable Diffusion&#xff09; 前言1、基础对比Stable Diffusion&#xff08;SD&#xff09;SD界面安装与使用SD Midjouney&#xff08;MJ&#xff09; 2、硬件与运行要求对比Stable Diffusion硬件要求内存硬盘显卡 Midjo…...

【蓝桥杯】矩阵快速幂

一.快速幂概述 1.引例 1&#xff09;题目描述&#xff1a; 求A^B的最后三位数表示的整数&#xff0c;A^B表示&#xff1a;A的B次方。 2&#xff09;思路&#xff1a; 一般的思路是&#xff1a;求出A的B次幂&#xff0c;再取结果的最后三位数。但是由于计算机能够表示的数字…...

C语言使用STM32开发板手搓高端家居洗衣机

目录 概要 成品效果 背景概述 1.开发环境 2.主要传感器。 技术细节 1. 用户如何知道选择了何种功能 2.启动后如何进行洗衣 3.如何将洗衣机状态上传至服务器并通过APP查看 4.洗衣过程、可燃气检测、OLED屏显示、服务器通信如何并发进行 小结 概要 本文章主要是讲解如…...

【Hello,PyQt】QTextEdit和QSplider

PyQt5 是一个强大的Python库&#xff0c;用于创建图形用户界面&#xff08;GUI&#xff09;。其中&#xff0c;QTextEdit 控件作为一个灵活多用的组件&#xff0c;常用于显示和编辑多行文本内容&#xff0c;支持丰富的格式设置和文本操作功能。另外&#xff0c;QSlider 控件是一…...

【力扣】191.位 1 的个数、485.最大连续 1 的个数

191.位 1 的个数 题目描述 编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中 设置位 的个数&#xff08;也被称为汉明重量&#xff09;。 示例 1&#xff1a; 输入&#xff1a;n 11 输出&#xff1…...

蓝桥杯 java 承压计算

题目: 思路&#xff1a; 1&#xff1a;其中的数字代表金属块的重量(计量单位较大) 说明每个数字后面不一定有多少个0 2&#xff1a;假设每块原料的重量都十分精确地平均落在下方的两个金属块上&#xff0c;最后&#xff0c;所有的金属块的重量都严格精确地平分落在最底层的电子…...

leetcode268-Missing Number

这道题目要求缺失的数字&#xff0c;一般解决数组的问题&#xff0c;要么往排序数组&#xff0c;要么往双指针遍历这些方向上靠&#xff0c;要么往异或方向上靠&#xff0c;总之落点无非就只有这几个。我们要求缺失的数字&#xff0c;可以依次让1&#xff5e;n和数组元素进行异…...

【jenkins+cmake+svn管理c++项目】jenkins回传文件到svn(windows)

书接上文&#xff1a;创建一个项目 在经过cmakemsbuild顺利生成动态库之后&#xff0c;考虑到我一个项目可能会生成多个动态库&#xff0c;它们分散在build内的不同文件夹&#xff0c;我希望能将它们收拢到一个文件夹下&#xff0c;并将其回传到svn。 一、动态库移位—cmake实…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...