gitbook/从0开始学游戏开发/docs/10551.md
2022-09-03 22:05:03 +08:00

73 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 复习课 | 带你梳理客户端开发的三个重点
我们用了将近两个月的时间,讲述了游戏客户端的开发流程和代码编写,今天我来带你总结并且回顾一下。
我这里列了一些编写游戏客户端**你必须要掌握的知识和注意的事项**。希望通过梳理这些知识,能让你对学过的内容有一个全盘的认识和更加深入的理解。
## 重点一客户端开发中4个重要方法
**首先我们来看设置前后遮挡效果时要用到的一个虚拟概念Z值。** 2D游戏中其实是不存在这个概念的因为Z值是高度概念一般只存在于3D游戏当中。2D游戏的坐标轴拥有X和Y两种位置。X轴是横向坐标Y轴是纵向坐标。在斜45度角的游戏或者需要经常改变前后遮挡位置游戏中往往才需要加入这个概念。在2D开发中用好了Z值能够帮你计算2D游戏中图片的前后位置在游戏中设置前后遮挡效果的时候就会更加方便。
**其次在2D游戏中制作碰撞检测的时候可以使用图片相交检测的方法来替代物理引擎**。像打飞机游戏这样非常简单的2D游戏是完全不需要使用物理引擎的我们使用**图片相交检测**的方法,直接写对应的代码就可以。
**什么时候才要使用物理引擎呢?这取决于你的代码量和程序编写的复杂程度。**
如果碰撞代码非常复杂占据整个工程量的1/5~1/4那就可以直接使用物理引擎如果仅仅用一两个函数就可以搞定那就可以自己模拟物理碰撞效果来写相应的代码。毕竟2D游戏不比3D游戏对“拟真”的要求没有那么高。而图片相交检测这样的方法易于编写且效果也可以满足需求。当然3D游戏中往往需要高精度地模拟真实世界的碰撞这个时候就直接使用物理引擎就好了。
**再次,在游戏开发中,保持低耦合度,能够提高你的开发效率,减少你的工作量。** 如果一款游戏引擎没有提供UI模块的话那需要你编写一套UI模块或者UI库。所谓单独的UI模块指的是仍然使用游戏引擎作为基础编写代码但是却独立于游戏本身的逻辑之外将之抽象出UI模块和UI库。如果UI模块直接融合在游戏里虽然玩家看起来是一样的效果但是在代码层面耦合度却更高可复用性和可修改性就变得更低代码质量就更差。
同样在游戏开发中很多模块都可以提取出来。比如鼠标和键盘的检测单独提取出来做变成相应的模块和库很多的内容都可以进行抽象和独立有了抽象和独立的模块这样可以保证游戏版本的迭代不出现问题你甚至可以拿这一套独立的抽象模块比如UI模块、鼠标键盘模块等等继续来做第二款游戏因为里面很多代码都可以复用。
**低耦合度,是游戏开发,甚至编程中都非常重要的思想**。我这里推荐一本书[《设计模式》](https://book.douban.com/subject/1052241/)。这里面对于耦合度的几种模式有详细的讲解。比如工厂模式、代理模式等等,但是不管用什么模式,**低耦合度始终是编程中追求的一种代码方式**。
所谓低耦合度,简单理解,就是将功能抽象出来,并且写成一组函数或者类(我们简称为接口)。这些接口有传入传出的参数或者返回值,可以通过外界代码传给接口,接口通过计算,将计算后的结果返回给外部代码。这些接口和别的功能关联性不大,替换了接口,就仅仅替换了算法或者内部实现而已,但是核心功能是一样的。
**最后,我想来说一下游戏逻辑。将游戏逻辑放在脚本语言里去写,迭代版本的时候可以不更新主程序,只更新脚本。**(如果不放在脚本语言里,就直接写在硬代码里面。)我们在使用引擎和原生语言开发游戏的时候,只保持核心内容,其他游戏逻辑、游戏配置,特别是在游戏中可活动、可配置、可调节的部分,都提取出来,放到脚本语言里去编写。
所谓的主程序在Windows下就是EXE文件一般情况下更新EXE执行文件会导致一系列的更新比如DLL动态链接库或者某些资源也会更新所以更新资源包会变得很大。如果纯粹更新脚本文件那就是几个脚本程序而已。当然这个也要看具体的需求并不是说一定不更新主程序如果有迫切需求更新主程序也是必须要更新的。
除此之外,关于客户端其他部分的流程和要注意的细节,我放在一起梳理一下。如果有哪些还不是很清楚,你可以回到对应的文章去复习一下。
* 首先,一款成熟的引擎会包含各种编辑器和工具。如果游戏引擎没有提供相应工具,你就必须根据要做的游戏项目,编写方便策划和美术使用的编辑器,包括地图编辑器、关卡编辑器、场景编辑器等等。
* 游戏的网络部分,要尽量保持网络连接和数据传输的安全性,游戏的网络协议可以迭代更新,网络传输的内容和逻辑也可以放在游戏脚本里面去做。
* 游戏的音乐部分,如果引擎不提供,建议使用成熟的音乐库。游戏要合理使用多线程技术,才能保证流畅性。游戏资源打包的包裹格式,如果没有现成的方案,可以使用压缩包的开发库编写,成熟稳定可靠。
* 每个平台的游戏机制都不相同比如在HTML5游戏里面它使用的是事件机制并非普通的循环。
## 重点二游戏开发的3大模块
这里我按照游戏开发中的三大模块策划、程序、美术,画了一个图。
![](https://static001.geekbang.org/resource/image/63/25/63c518012e92fb2dea46ffc58c1df125.jpg)
开发游戏的时候策划要先行先出策划稿、UI图、页面迁徙图等等然后美术开始跟上紧接着根据策划案开始制作UI、原画、人物、场景等等。程序员开始制作各种编辑器和周边工具如果引擎没有提供的话随后美术开始制作地图和各种关卡程序员开始编写demo。随后就开始内部测试和运行总结问题和经验修正和补缺。最后开始第一个正式版本的开发。正式版本的开发流程和demo版本是一样的我在[第5讲](https://time.geekbang.org/column/article/8670)的时候已经详细说过demo的作用。
在专栏中我用Pygame来做教学示例有很多人在留言里问我想用别的语言编写游戏难道不可以吗当然是可以的Pygame只是利用Python+SDL封装的游戏库而我只是以Pygame为载体告诉你编写2D游戏引擎的一些核心知识是怎样的。有了核心知识了解了流程语言层面就简单地多了。举一反三换作任何语言、任何引擎都不会有问题了。
在这之后,如果你想要进一步学习,或者从事相关的开发工作,你要自己多练习、多思考。如果是在公司里,那就多上手去做项目。游戏的开发流程就是这么回事,要做的东西也就那么多,但是不同的项目,不同种类的游戏,就会有不同的问题出现。每次遇到问题,**多换几种思路去思考,多去了解策划、运营的想法**,而不要只是在“不断填坑”。
## 重点三:如何写出过硬的代码?
其实,说了这么多,我现在要说我认为最重要的一点。 **无论你是做游戏开发或者别的开发,你都要有过硬的代码基础。** 一款游戏,有再好的引擎,再好的策划,如果代码写得不好,也会影响游戏体验,毕竟引擎只是在底层带动游戏的运行,在上层业务上,还是要依赖代码的牢靠和稳固。
我从96年写下第一行代码开始走过许多的弯路也经历过许多挫折。**在写代码方面,我或许可以带给你一些直接的经验和警示之谈**。
十几年前当我刚还是个入门级程序员的时候经历过一个项目我负责做一个共享内存的接口。事实上写这个接口很简单用不了多少代码就能完成但当时我正在学习C++最新的Loki库后来加入了Boost觉得里面的模板技巧简直是无敌所以我在共享内存接口之上又封装了类似Loki模板的方法最终导致代码过于复杂很难控制和管理项目失败。
因此,**如果代码不是特别复杂,你大可以直接写功能,不需要从类、框架开始写起,因为这会造成我所犯的那个错误,就是“过度设计”**。举个简单的例子如果一个“hello word”却有500行代码这很明显就是“过度设计”。
所以,我的多年的习惯是,**如果一个正常的软件、游戏,或者模块、接口,我都会将普通的功能、重复性高的功能,抽象出来,做成一个模块,特殊的功能、无法重复的,再做成一个模块。代码尽可能不要长,长的代码分割成几部分,放在几个文件里,阅读起来也会很清晰。能写简洁的绝对不要花里胡哨,能用正常技巧的绝对不用小聪明,实在没办法才用小聪明。**
对外提供接口要清晰、易于阅读,逻辑要一条一条理顺。有异常,就写异常处理代码;有错误,就处理错误代码;没有问题,再运行下一条。
好记性不如烂笔头,写之前先想明白思路,将自己即将要写的代码在脑子里跑一遍,然后将思路记录下来,记在笔记本、电脑、手机哪里都可以。这样写出的代码比直接上手写,速度上会慢很多,但是出错概率极低。直接写你可能一下子就写完,但还要修修补补,调试一整天,事实上,这比思考虑好了再写还要慢。
最后,还是那句话,不管是编写大型游戏还是一款小游戏,还是做任何项目,都离不开踏踏实实把代码写好。毕竟这是基础。如果你总想着什么多少天速成法,快速入门、快速编写出一款脍炙人口的游戏,用户上几百万,这是不存在的。游戏开发,应该说任何程序开发,都不适合任何想要走捷径的人。真正聪明的人,都应该知道学习本来也没有什么捷径。
经过这两个月的学习,不知道你对游戏开发有没有更深入的认识?关于游戏开发或者编程,你还有什么想要了解的,你可以继续在留言区写下想法。
我在后面的挑战中继续等待你的到来!