C++小游戏笔记——射击小行星(附源码)
C++小游戏笔记——射击小行星(附源码)
- 游戏展示图
- 一、飞船
- 1.飞船的绘制
- 2.飞船的角度
- 二、小行星
- 1.小行星的绘制
- 2.“凹凸不平”效果的形成
- 3.小行星的分裂
- 三、子弹
- 四、边界溢出的处理
- 1.飞船和小行星
- 2.子弹
- 五、碰撞判定
- 总结
游戏的代码有点长,链接我放在评论区了,我的博客中也免费发布了该代码,需要留言的自取即可。代码参考了一位youtube编程大佬的视频,该视频在b站地址为:
https://www.bilibili.com/video/BV14z4y1r7wX?p=12
下文是我对该游戏中一些重要问题的处理方法的原理与理解:
游戏展示图
游戏介绍:
通过左右键控制飞船摆动,上键控制飞船加速,空格键馈控制飞船发射子弹。当子弹击中小行星后,单个小行星会分裂成两个朝向随机方向的小行星,并获取相应分数,如果子弹击毁了所有小行星,则会重新生成两个大的小行星,并给予更多分数奖励。而当飞船碰撞到小行星时,游戏结束,重置游戏。
一、飞船
1.飞船的绘制
飞船是一个等腰三角形,这里只定义该三角形的三个顶点,即可创建出飞船对象vecModelShip。利用头文件中封装好的DrawWireFrameModel函数,传入飞船对象,飞船坐标,飞船角度,即可完成飞船的绘制,如下:
vecModelShip =
{{ 0.0f, -4.0f},{-2.0f, +2.0f},{+2.0f, +2.0f}
};
DrawWireFrameModel(vecModelShip, player.x, player.y,player.angle);
2.飞船的角度
飞船的角度通过angle变量来实现,其具体体现相当于下图中的角度Θ,当持续按下左右方向键后,飞船的angle值会持续++或–某一固定值直到Θ。
此时飞船的前进速度为v,则旋转一定角度后,飞船的横向速度dx与纵向速度dy可以用
dx=v * sinΘ
dy=v * cosΘ
表示,经过时间t后,飞船的位置x,y可以用
x += dx * t
y += dy * t
表示,这样飞船的坐标xy就可以通过angle来控制,而飞船对象图形的角度旋转,在上文封装好的函数中传入angle就可以实现绘制了。
通过以上方法,既解决了因角度变化而导致飞船坐标移动的问题,也解决了飞船对象图形的旋转问题。
二、小行星
1.小行星的绘制
小行星对象vecModelAsteroid主体上是一个圆,绘制的原理是截取圆上若干点verts(这里取verts=20个),通过封装好的DrawWireFrameModel()函数,将20个点连成线,函数调用与飞船相似。
需要注意的是,小行星不像飞船一样只有一个,所以他是以数组的形式存在着的,对于小行星对象的操作,都要以遍历的方法进行:
for (auto& a : vecAsteroids)DrawWireFrameModel((vecModelAsteroid, a.x, a.y, a.angle, (float)a.nSize, FG_YELLOW)
2.“凹凸不平”效果的形成
而为了让小行星看起来“凹凸不平”,这20个点,并不是绝对在圆上,而是生成一个较小的随机数,让点与圆心距离在某一区间内随机生成,这样可以营造出小行星的效果,该方法的具体实现如下:
int verts = 20;
for (int i = 0; i < verts; i++)
{float noise = (float)rand() / (float)RAND_MAX * 0.4f + 0.8f;vecModelAsteroid.push_back(make_pair(noise * sinf(((float)i / (float)verts) * 6.28318f),noise * cosf(((float)i / (float)verts) * 6.28318f)));
}
3.小行星的分裂
小行星的分裂上,会随机生成两个分裂方向,然后在原来的原点位置,push_back两个方向的,大小减半的新小行星对象newvecModelAsteroid,然后删除旧的小行星,添加完成后,在原小行星组中,加上新生成的这两个小行星,如下所示:
for (auto& a : vecAsteroids)//遍历小行星
{//*************************////前面有一些判断子弹碰撞到小行星的前置条件//*************************//if (a.nSize > 4)//如果小行星还能分裂{float angle1 = ((float)rand() / (float)RAND_MAX) * 6.283185f;//任意生成一个方向float angle2 = ((float)rand() / (float)RAND_MAX) * 6.283185f;//任意生成一个方向//添加新的小行星newAsteroids.push_back({ (int)a.nSize >> 1 ,a.x, a.y, 10.0f * sinf(angle1), 10.0f * cosf(angle1), 0.0f });newAsteroids.push_back({ (int)a.nSize >> 1 ,a.x, a.y, 10.0f * sinf(angle2), 10.0f * cosf(angle2), 0.0f });}
}
三、子弹
子弹的绘制比较简单,它是以数组的形式存在的。因为子弹是一个像素点,而其角度是用户按下“space”键时继承的该时刻飞船的角度angle,所以变化不多,直接调用封装的Draw函数,传入子弹数组的横纵坐标x,y即可。
for (auto b : vecBullets)Draw(b.x, b.y);
四、边界溢出的处理
当飞船或小行星或子弹运动到屏幕之外时,即
x<0 || y< 0 || x>ScreenWidth() || y >ScreenHeight()
根据对象的不同有以下两种处理方式:
1.飞船和小行星
飞船和小行星来到屏幕之外时,会回到另一边,比如飞船一直往左走到x<0了,则飞船就从右边ScreenWidth()出现,继续往左走,即对于飞船和小行星来说,是如下图的空间:
处理该情况的WrapCoordinates函数如下所示:
void WrapCoordinates(float ix, float iy, float& ox, float& oy)//超出屏幕边缘就从另一边回去,&ox与&oy的引用写法相当于return两个变量,调用时传两遍对象的x,y即可
{ox = ix;oy = iy;if (ix < 0.0f) ox = ix + (float)ScreenWidth();if (ix >= (float)ScreenWidth()) ox = ix - (float)ScreenWidth();if (iy < 0.0f) oy = iy + (float)ScreenHeight();if (iy >= (float)ScreenHeight()) oy = iy - (float)ScreenHeight();}
2.子弹
子弹超出边界直接删除!不用WrapCoordinates函数
五、碰撞判定
一个是飞船与小行星碰撞的判定,一个是子弹与小行星碰撞的判定。
两种情况非常相似,其核心就是判定子弹或飞船与小行星中心的距离与半径的关系,该距离小于等于半径即判定二者发生碰撞,封装的函数如下:
//碰撞检测函数(计算两个点直线距离与半径的关系)
bool IsPointInsideCircle(float cx, float cy, float radius, float x, float y)
{return sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)) < radius;
}
总结
以上就是针对该C++游戏的所有重点问题,至于游戏的开启、更新、重置问题,在代码中有详细的注释,在实战方面会用即可。
有关问题欢迎与我讨论~
C++小游戏笔记——射击小行星(附源码)相关推荐
- java 打地鼠 源代码_Java实现的打地鼠小游戏完整示例【附源码下载】
本文实例讲述了Java实现的打地鼠小游戏.分享给大家供大家参考,具体如下: 这里涉及到java线程和GUI的相关知识,一个简单的java小游戏打地鼠,有兴趣的朋友可以优化一下.先来看看运行效果: 具体 ...
- 敲地鼠java_Java实现的打地鼠小游戏完整示例【附源码下载】
本文实例讲述了Java实现的打地鼠小游戏.分享给大家供大家参考,具体如下: 这里涉及到java线程和GUI的相关知识,一个简单的java小游戏打地鼠,有兴趣的朋友可以优化一下.先来看看运行效果: 具体 ...
- 【Python游戏】Python基于第三方库pygame实现一个魂斗罗小游戏,毕业设计必备 | 附源码
前言 halo,包子们下午好 今天给打击整一个魂斗罗小游戏 很多小伙伴接触魂斗罗应该是在小时候的一个手柄游戏上面吧 我记得作为90后的我,玩这一款游戏是在小学的时候 废话不多说,直接上才艺 今天给大家 ...
- c语言2048代码linux,C语言2048小游戏课设(附源码).doc
PAGE PAGE 1 C语言2048小游戏课设 项目说明 本系统基于C语言开发,适用于刚入门的C语言新手项目课设,开发软件采用VC++6.0开发,VS,DEV C++等均可运行.(书生) 项目运行截 ...
- python之flappy bird(飞扬的小鸟)小游戏分享,内附源码哦~
导语: 哈喽,哈喽~今天小编又来分享小游戏了--flappy bird(飞扬的小鸟),这个游戏非常的经典,游戏中玩家必须控制一只小鸟,跨越由各种不同长度水管所组成的障碍.这个游戏能对于小编来说还是有点 ...
- JAVA课程设计(小游戏贪吃蛇)完整源码附素材(二)
目录 JAVA课程设计(小游戏贪吃蛇)完整源码附素材(一) JAVA课程设计(小游戏贪吃蛇)完整源码附素材(二) JAVA课程设计(小游戏贪吃蛇)完整源码附素材(三) 前言 1. 任务描述 1.1 ...
- 《设计模式之禅》笔记序言(附源码链接)
<设计模式之禅>笔记序言(附源码链接) GitHub链接 2021年9月初,我下定决心要从书本出发,建立自己的技术栈基础体系.在此过程中,从阅读的部分书籍的源代码导读中,我发现其中有迹可循 ...
- 基于JAVA网页小游戏交流论坛计算机毕业设计源码+数据库+lw文档+系统+部署
基于JAVA网页小游戏交流论坛计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA网页小游戏交流论坛计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S架构 开 ...
- java游戏下载象棋暗棋_JS小游戏之象棋暗棋源码详解
本文实例讲述了JS小游戏的象棋暗棋源码,分享给大家供大家参考.具体如下: 游戏运行后如下图所示: Javascript 部分: /** chinese chess * Author: fdipzone ...
最新文章
- java并发处理时mvel表达式处理慢,一文说清!
- Codeforces 911F Tree Destruction
- Python 字符串转义序列及格式化
- docker network
- Java System类console()方法及示例
- 要闻君说:FaceTime的服务究竟坑有多大?CNCF 技术监督委员会首添中国面孔,来自阿里!高通华为暂和解……...
- 那些你不知道的程序员的多重身份
- Java中看今天是星期几,礼拜几
- linux修改默认python版本_将Linux下python默认版本切换成替代版本
- 果皇的矩阵[matrix]
- 2014.8.25二分法,二维数组
- echarts 动态设置y轴单位_Recharts动态设置y轴的最大值最小值
- 航信3.0开票模拟系统
- 上,下拉电阻的作用与计算
- PNG转ICO-在线转换
- 记 · 迎接寒风 · 独自北上旅行
- PT100温度传感器的工作原理
- java中的日志处理
- 速卖通重点国家市场俄罗斯市场分析平台热销产品推荐
- Intel Realsense D435i标定详细步骤
热门文章
- 【社交网络】2010年电影观后随想
- BaiduOCR实现身份证,银行卡,机动车牌,图像审核等识别
- 6.aync和await的原理及实现
- 不属于c语言程序运算符,下面属于C语言关系运算符的是:( ) (A) (B) (C) =! (D) = - 试题答案网问答...
- excel中怎么批量在文字前后增加文字
- 软件测试参数化的作用,Pytest之测试的参数化
- python爬虫爬取某网站全站图片案列(源码全给可白漂,仅供学习使用,切勿用作非法用途)
- 基于FPGA的电子密码锁
- 花卉世界大观园和杂技之游(r12笔记第97天)
- 读万卷书,写万行代码