当前位置: 首页 > 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实…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...