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++小游戏笔记——射击小行星(附源码)相关推荐

  1. java 打地鼠 源代码_Java实现的打地鼠小游戏完整示例【附源码下载】

    本文实例讲述了Java实现的打地鼠小游戏.分享给大家供大家参考,具体如下: 这里涉及到java线程和GUI的相关知识,一个简单的java小游戏打地鼠,有兴趣的朋友可以优化一下.先来看看运行效果: 具体 ...

  2. 敲地鼠java_Java实现的打地鼠小游戏完整示例【附源码下载】

    本文实例讲述了Java实现的打地鼠小游戏.分享给大家供大家参考,具体如下: 这里涉及到java线程和GUI的相关知识,一个简单的java小游戏打地鼠,有兴趣的朋友可以优化一下.先来看看运行效果: 具体 ...

  3. 【Python游戏】Python基于第三方库pygame实现一个魂斗罗小游戏,毕业设计必备 | 附源码

    前言 halo,包子们下午好 今天给打击整一个魂斗罗小游戏 很多小伙伴接触魂斗罗应该是在小时候的一个手柄游戏上面吧 我记得作为90后的我,玩这一款游戏是在小学的时候 废话不多说,直接上才艺 今天给大家 ...

  4. c语言2048代码linux,C语言2048小游戏课设(附源码).doc

    PAGE PAGE 1 C语言2048小游戏课设 项目说明 本系统基于C语言开发,适用于刚入门的C语言新手项目课设,开发软件采用VC++6.0开发,VS,DEV C++等均可运行.(书生) 项目运行截 ...

  5. python之flappy bird(飞扬的小鸟)小游戏分享,内附源码哦~

    导语: 哈喽,哈喽~今天小编又来分享小游戏了--flappy bird(飞扬的小鸟),这个游戏非常的经典,游戏中玩家必须控制一只小鸟,跨越由各种不同长度水管所组成的障碍.这个游戏能对于小编来说还是有点 ...

  6. JAVA课程设计(小游戏贪吃蛇)完整源码附素材(二)

    目录 JAVA课程设计(小游戏贪吃蛇)完整源码附素材(一) JAVA课程设计(小游戏贪吃蛇)完整源码附素材(二) JAVA课程设计(小游戏贪吃蛇)完整源码附素材(三) 前言 1. 任务描述 1.1  ...

  7. 《设计模式之禅》笔记序言(附源码链接)

    <设计模式之禅>笔记序言(附源码链接) GitHub链接 2021年9月初,我下定决心要从书本出发,建立自己的技术栈基础体系.在此过程中,从阅读的部分书籍的源代码导读中,我发现其中有迹可循 ...

  8. 基于JAVA网页小游戏交流论坛计算机毕业设计源码+数据库+lw文档+系统+部署

    基于JAVA网页小游戏交流论坛计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA网页小游戏交流论坛计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S架构 开 ...

  9. java游戏下载象棋暗棋_JS小游戏之象棋暗棋源码详解

    本文实例讲述了JS小游戏的象棋暗棋源码,分享给大家供大家参考.具体如下: 游戏运行后如下图所示: Javascript 部分: /** chinese chess * Author: fdipzone ...

最新文章

  1. java并发处理时mvel表达式处理慢,一文说清!
  2. Codeforces 911F Tree Destruction
  3. Python 字符串转义序列及格式化
  4. docker network
  5. Java System类console()方法及示例
  6. 要闻君说:FaceTime的服务究竟坑有多大?CNCF 技术监督委员会首添中国面孔,来自阿里!高通华为暂和解……...
  7. 那些你不知道的程序员的多重身份
  8. Java中看今天是星期几,礼拜几
  9. linux修改默认python版本_将Linux下python默认版本切换成替代版本
  10. 果皇的矩阵[matrix]
  11. 2014.8.25二分法,二维数组
  12. echarts 动态设置y轴单位_Recharts动态设置y轴的最大值最小值
  13. 航信3.0开票模拟系统
  14. 上,下拉电阻的作用与计算
  15. PNG转ICO-在线转换
  16. 记 · 迎接寒风 · 独自北上旅行
  17. PT100温度传感器的工作原理
  18. java中的日志处理
  19. 速卖通重点国家市场俄罗斯市场分析平台热销产品推荐
  20. Intel Realsense D435i标定详细步骤

热门文章

  1. 【社交网络】2010年电影观后随想
  2. BaiduOCR实现身份证,银行卡,机动车牌,图像审核等识别
  3. 6.aync和await的原理及实现
  4. 不属于c语言程序运算符,下面属于C语言关系运算符的是:( ) (A) (B) (C) =! (D) = - 试题答案网问答...
  5. excel中怎么批量在文字前后增加文字
  6. 软件测试参数化的作用,Pytest之测试的参数化
  7. python爬虫爬取某网站全站图片案列(源码全给可白漂,仅供学习使用,切勿用作非法用途)
  8. 基于FPGA的电子密码锁
  9. 花卉世界大观园和杂技之游(r12笔记第97天)
  10. 读万卷书,写万行代码