[OpenGL] 游戏开发的简单demo
来源:互联网 发布:一线城市 知乎 编辑:程序博客网 时间:2024/06/10 12:12
完成时间:2016年08月23日(大三上)
博客时间:2017年04月19日
转载请注明作者 _(:3 」∠)_ :RyuZhihao123 (Northwest A&F University,985/211)
程序截图:
简介:
这个程序是我大二为《软件工程》课程的作业而编写的,采用C++/OpenGL开发。因为只是一个作业,实现的比较简单,但是还是运用了一些设计思想,比较有参考价值吧。现在过了将近半年才回来填这个坑,主要也是因为涉及到的内容太多了(其实是我太懒 (。・`ω´・))。
这篇博客可能更多地侧重于游戏的设计思想,如果想要交流欢迎评论或者私信哦。
游戏开发的几点重要策略:
1. 高效的游戏循环(Game Loop)
方法一:一个最简单粗暴但相当劣质的处理方式是:用一种能跑多快跑多快的方式进行游戏循环。简单的用代码表示一下:
int main() {while(true) // 一种不好的方式{processInput(); // CPU处理输入update(); // CPU修改状态render(); // GPU渲染画面}}
不难发现,在快的机器上,游戏循环可能快得令玩家看不清游戏在做什么;在慢的机器上,游戏则会变得又慢又卡。方法二:我们稍加一下改进:你想让时间以60fps的速度运行,也就是间隔MS_PER_UPDATE=16毫秒进行一个游戏循环,那么则可以以一个稳定的帧率来跑游戏。What you should do is to wait for next frame.简单的用代码表示一下:
int main(){while(true) // 维持相对稳定的帧率的方法{double start = getCurrentTime();processInput();update();render(); // 等待一段时间,凑够16mssleep( MS_PER_UPDATE - (getCurrentTime() - start));}}
这种方法,通过引入的一个sleep()方法帮助我们维持了一个相对稳定的fps。但是,我们也能发现一个问题:若每次实际用于更新的时间长于固定的间隔时间MS_PER_UPDATE,那么游戏同样会变慢。例如,当需要16ms以上的时间去更新fps=16ms的游戏时,就会无法维持运行速度。
方法三: 让我们试一下稍微复杂点的方法。为了解决方法二中出现的问题,我们以这一帧与上一帧的实际时间间隔来作为更新步长。帧处理花费的实际时间越长,这个步长也就越长。这个方法舍弃了固定的MS_PER_UPDATE,而是采用实际间隔时间elapsed来作为更新依据。这个方法使得游戏总会越来越接近于实际的时间。因此也被称为变值时间步长。
int main(){double lastTime = getCurrentTime();while(true) // 维持相对稳定的帧率的方法{double current = getCurrentTime();double elapsed = current - lastTime;processInput();update(elapsed);render();lastTime = current;}}
这种游戏循环虽然有了很大的提高,但是也有潜在的问题(可以参考给出的参考资料)。方法四:最后的改进,通过引入一个新的变量lag来表示游戏时钟相对于现实时间落后的差量。接着用一个内部循环更新游戏,每次以固定时长MS_PER_UPDATE进行,直到追上现实时间(此处的MS_PER_UPDATE不是视觉上的帧速,而是更新游戏update()的间隔)
int main() // 一个比较好的方案:可以追回因为render()落后的时间{double lastTime = getCurrentTime();double lag = 0.0;while(true){double current = getCurrentTime();double elapsed = current - lastTime;lastTime = current;lag += elapsed;processInput();// 内部循环:以固定时长更新游戏以赶上落后的时间。while(lag >= MS_PER_UPDATE){double startUpdate = getCurrentTime();update();lag -= MS_PER_UPDATE;sleep(MS_PER_UPDATE - (getCurrentTime()-startUpdate));}render();}}
2. 场景管理Scene Management
3D游戏中场景管理的方法有很多:四叉树、八叉树、BSP树、KD树等。方法各有优劣,适用的情形各不相同。但是原理较为复杂,这里也不过多描述,需要的可以自己去google。
例如:使用八叉树/kd树,可以以很高的效率进行空间查询:
(1) 邻近查询(proximity query):如查询玩家周围的npc、掉落物品等。
(2) 可见性判断(view frustum culling):剔除不可见的物体
(3) 粗略的碰撞检测:找到潜在的可能碰撞的对象。
下图便是采用k-d树的空间划分结构,为每个单位划分一个区域。
3. 人工智能单位 AI
其实,对于AI单位的管理,应当归于Scene Management。但是AI单位有自己的特殊之处,受到攻击时会追击、拉开距离后停止追赶。
这里的话,需要进行碰撞、攻击判定等。可能会用到的技术有:AABB包围盒等。
4. 大规模地形渲染
这是一个比较复杂的东西,但是如果使用下面提到的技术会大大提高你的渲染效率。我们在render large terrains时,经常采用的便是LOD(level of detail)的技术,根据距离确定细节层次。
详情可以看一下我翻译的另一片博客:How to rendering large terrains
5. 参考资料:
1. [Book] Game Programming Patterns - Robert Nystrom
2. [LINK] http://gameprogrammingpatterns.com/game-loop.html
3. [LINK]http://www.koonsolo.com/news/dewitters-gameloop/
6. 写在后面
希望我的文章,能够为有志于开发游戏的同志有所帮助。我也还只是一个普通的本科生,欢迎不幸点开这篇文章的诸位大神批评指正!!!
这是一个比较简单的demo,欢迎评论或者私信讨论。另外我之前做的一个游戏仿制《minecraft》的资料还有演示程序可以在我的其他博客中翻到~ (ง •̀_•́)ง。
我使用OpenGL仿制的一款《Minecraft》:仿制《Minecraft》
- [OpenGL] 游戏开发的简单demo
- openGL 简单demo
- 使用pureMVC构建简单的游戏demo
- 使用pureMVC构建简单的游戏demo
- 基于HTML5的简单游戏动画Demo
- cocos2d开发学习六:一个简单的打地鼠游戏demo
- 游戏开发--OpenGL ES的基础介绍
- Qt+OpenGL游戏开发的资料
- Qt+OpenGL游戏开发的资料
- MOSS 对象模型的简单开发DEMO
- JNI开发的一个简单Demo
- [MFC开发]CInternetSession的简单使用demo
- Linux下FFMPEG 简单的Demo开发
- 一个简单的入门的android游戏demo
- flash与游戏笔记:简单的人物demo
- 一个VR游戏DEMO的开发历程是怎样的?
- android游戏开发-OPENGL ES
- 用QtCreator开发OpenGL游戏
- [LeetCode]26. Remove Duplicates from Sorted Array
- 数据库知识总结
- ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
- Problem D: C++习题-快速排序
- PAT(Python)-1030:完美数列(25)
- [OpenGL] 游戏开发的简单demo
- highcharts坐标轴实现html里的title效果
- VMware安装Ubuntu虚拟机后的相关必备操作
- 解决android webview闪烁的现象
- C# Hashtable 使用说明 以及 Hashtable和HashMap的区别[转]
- Unity3D Shader之路 写Shader前必须要知道的事情2 表面着色器的理解
- gdb调试
- audio录音在JAVA层的调用
- JS和COM口通信