【发烧期间随笔】第一次游戏开发经历的总结与反思
一、前言
这两天三阳了,头疼头晕恶心发烧打喷嚏流鼻涕咳嗽嗓子疼气管疼都找上门来了,这导致一周以来都没学什么东西,无意间又刷到各个游戏厂关于本人目标岗位HC骤减且要求造火箭的能力的消息,这两天一直是在病痛和焦虑中度过的,躺着就焦虑自己在浪费时间,坐到电脑前又没有精神集中可以学习,因为阳了。但是我还是想尝试写一些东西,说是打发时间也好,或者恢复一下脑子,总之就是想记录一下当时第一次游戏开发的一些经历和感想吧,对自己以后的工作可能也会有一些帮助。(写文章时脑子仍然处于发烧状态,如果出现胡言乱语,还请见谅)
这里我主要想阐述我自己视角下的一些东西,因为当时我是担任程序和一部分策划的工作,关于美术我只负责了一定的美术资源的处理和使用,并没有美术资源产出,所以也不会有什么见解。我想写一些关于游戏开发的个人思考吧,方便小白参考,也方便我日后回顾,当然和我所有的博客一样,如果有大佬看到了错误也请指出,我会虚心改正。同时为了大家都能读懂,我不会用专业术语,尽量让所有人都能读懂。
先说明一下经历的大概情况:要求每个组5个人,分工自定,在6天之内做出一个完整的项目。本人在项目之初担任的是程序,当然后来因为需要,介入了策划和关卡设计与搭建等工作。
二、立项—磨合、集思广益
在立项的时候,理想情况下,如果策划已经有了想法,并且如果策划是一个比较认真负责的策划的话,他会直接写一个项目文档,供大家讨论分析可行性以及潜在问题等等(当然可能后续需要一些细化)。
如果策划是一个不懂程序或者说没有经验的人,那么立项这个事情将会非常拖延时间,常见的情况比如,策划天马行空的想法,程序无法实现,美术无法创作。或者,理论上可以实现,但因为团队中程序技术能力的原因导致的无法实现,这无法直接说是谁的问题,策划有考虑不周到,程序有技术不达标,这都有可能,这是一个团队需要磨合的东西。
有些情况,比如在本人的第一次的游戏开发经历中,我们团队倾向于的是头脑风暴式的立项,看上去是一个很民主的选择,实则个人认为是最浪费时间的一个选择。我们团队的所有人都提出了1~2个想法,并把它们按照自己设想的方法细化,贴到公共的白板上,供我们之间互相提出意见,最后经过长时间的讨论,交流,我们投票选出了,相对来说既可实现落地,又有一定创意的方案,之后在此基础上进行工程上细化和潜在问题的解决。

这个过程我用文字只描述了一点点,但实际上在整个6天的时间里,这个立项花费了我们2天的时间。在此我并不想说这样做不好,因为我觉得大部分人做游戏都是有一定情怀在的,大家想做出自己心目中的那个游戏,而并不想完全追求效率,把它当作一个工业化的产品,当然如果是在公司,那确确实实就是这样,大家都是流水线上的工人,这样可以提高很多效率。所以我在这想说明的就是,立项这个选择因人而异,但无论怎样,策划的脑子里是一定要有东西的,坦白地说作为程序我一开始就已经把自己当成了干活的,而没想到要参与到设计中去,如果大家都是这样,那整个项目就是空谈了,所以无论是策划一人独大也好还是集思广益也罢,策划的脑子里一定要有东西。
三、程序的分工—交叉与并行
我们团队的分工是,2策划+2程序+1美术,也就是负责大部分项目内容工作的只有3个人,美术只有一个人,所以只需要自顾自即可。但程序有2个人,一旦出现1个人以上,就需要进行分工协作了。
在开发之处其实我已经遇见了一些可能会遇到的问题,如果两个程序的开发内容存在交叉,那么一个人写出的BUG另外一个人可能很难调试,就算BUG修好了,又可能会导致修改BUG导致原本程序的其它逻辑出现BUG。而避免这一问题,我们需要把对方的代码再读一遍,理解对方实现某个功能的逻辑,因为一个功能的实现可以有很多种逻辑方法,我们并不能想当然的觉得对方和自己的想法是一样的。因此,读对方的代码,理解对方的逻辑思路,在前期花费了大量的时间。
既然交叉的工作内容会导致问题,难道就没有解决方案了吗?有,当然有,那就是两个人负责不同的大块的整块的内容,比如在我们游戏里有三个角色,它们有各自不同的移动逻辑,和功能逻辑,如果我负责写移动,而他负责写功能,那么这样发生冲突的概率就会减小很多,这就是各自独立并行的工作内容,既可以提升效率又不至于牵一发而动全身。但是问题并没有这样解决,因为整个游戏中各个元素的交互导致了这些逻辑并不是独立的存在,它们仍然有交互,有影响,在这种情况下,我们最终决定我来负责游戏内的角色逻辑,而另一名程序负责UI和关卡的逻辑,其次由于我后续介入了策划和关卡搭建,程序到最后基本都由另一位程序实现了,这样效率有提高,并且减少了BUG的可能性。
在这里我想阐述的观点是,团队协作本身没有错,但是整个项目在分工的时候最好把每个部分分为独立的个体,这样最后把大家的结果合并的时候才会减小发生冲突的概率,当然如果相互沟通能力特别强的话,这应该也算不上什么问题,但大多数情况不是。所以分工的独立性和并行性尤为重要,无论是策划,程序还是美术。
四、项目资产的管理—减少沟通成本

这里用我的经历举例不太具有参考价值,但有一定的参考性,因为作为一个6天的小项目,需要管理的资产并不多,但如果对于一个大项目,所有的脚本,美术资产等等都需要有一定的规范性整理,从命名规则到文件夹包含关系,团队内需要同一的规定,来确保每个人都能轻而易举的调用项目资产,并且每个人自身创建管理资产的时候也需要用同样的标准。这样做可以最大的减少沟通成本,避免混淆冲突。
举例,上图中的Prefabs就是一个例子,预制体作为一个较为大的概况可以包含游戏内各个元素的预制体,角色,地图,UI等等,这样负责搭建场景的人一眼就知道哪些可以用来干什么。
其次Scene场景,是我们存放游戏中关卡的文件夹,这本身到没什么说的,你可能会注意到关卡1-4后面都有一个后缀-new,因为在初期没有美术资产的时候我们需要用简单的几何体来测试BUG,而有了美术资产后将几何体替换掉后,我们同一命名加上后缀-new,以免引起误会,并且很容易区分,一眼就可以看出这是迭代更新后的关卡。
五、美术资源的需求和规范确定—让美术带着镣铐跳舞
1.需求确定
整个项目开发的过程中,这个是最令我头疼的,首先是因为我们团队里只有一个美术,所以产能有限,而另一边的策划经验有限,会时不时的蹦出一些需要新的美术资产的新想法,当然在我的拒绝下,这些想法都被搁置了,原因是项目的核心所需要的美术资产还没生产完成的时候,美术不应该把精力放在其他地方。
在项目立项结束,并且细化确定美术风格以后,我们就应该想到大体需要哪些美术资源,具体到UI的形状颜色等等等等,写成文档,或者列成表格一并交给美术去生产,程序应当也是如此。这样做之后,在此基础上查缺补漏不断迭代,最后再优化细节。一定要避免的情况是,简简单单的想了个大概然后跟美术说了说大概需要哪些东西,然后在项目进行的过程中时不时蹦出新的需求,这回严重影响进度效率。
2.规范确定
美术资产必须要有规范性,而不能让美术闭门造车。
我举一个例子,我们当时是一个2D的解密小游戏,自然涉及到平台跳跃,那么平台这个资产显然是需要大量复用的,并且有着不确定性,因为在关卡设计和搭建的过程中,我们需要各种长度的平台,如果只有一种固定长度的平台,会严重限制关卡的设计种类。你可能会说不是有缩放功能吗?当然,但是缩放后扭曲了原本资产的形状会很丑。而在项目之初,我们的美术确实没考虑过这一点,所以只交给了我们一种平台的美术资产,导致后续的关卡迭代非常繁琐,浪费时间。最后和美术沟通完毕后,我们终于有了分块的可复用的平台美术资产,但是前期浪费的时间确是无法弥补的。
第二个例子,美术资产的尺寸问题,这个问题到最后项目完成时才发现,但是当时已经来不及了。简单的说,就像地图上的比例尺问题一样,由于各个美术资产并不是独立出现的,它们共同放在一个场景里,那么它们就需要有一个相同的比例尺,同时又要考虑角色的尺寸相称性,并且方便角色的交互。
我们出现的问题如下图所示。

上图左边的石头乍一看好像没什么问题,但是仔细看看就会发现有模糊/马赛克的现象,原因是我们把美术给的资源进行了放大,那么可不可以缩小呢?答案是不可以,因为角色的资产的尺寸和我们在脚本中设定的跳跃高度就是当前石头的大小,其次这个石头在设定中属于初级障碍物,也就是一段跳就可以跳过去,而右边的粉色大石头属于次级障碍物,需要垫着小石头跳过,所以左边小石头的放大可以满足这个需求。
所以,综上所述,角色的尺寸导致了我们的脚本的跳跃高度的调整,进而决定了石头的大小,于是它无法调整,只能这样。或者以我们的引擎中的规格来制定美术标准,或者根据美术所生产的资产尺寸我们修改脚本,但实际上这都是不现实的。唯一的解决方法就是在美术生产资产的过程中,自己脑袋里清楚游戏的场景大致长什么样,以及场景中各个元素都是用来干嘛的,并且需要专门的人来制定一套资产规范和尺寸标准。
六、游戏机制与关卡设计—站在玩家的视角
1.关卡的逻辑设计

游戏关卡的设计最初原本是交给我们的策划,但是显然我们策划经验并不丰富,所以我介入了一下,当然这不只是我一个人的功劳,大家都参与到了设计中,只不过我提供了一种可行的产出方法。
在每个关卡/场景,都有一些相同的东西,我把它们列了出来如上图所示,由于是解密游戏,我考虑了玩家具有的能力以及玩家需要解决的问题,那么设计关卡本质上就和老师出卷子一样,你需要考虑到学生会些什么,这样就可以把各个知识点杂糅在一起,不断排列组合形成新的问题,如上图所示,玩家的障碍就是几个东西,四个障碍我们如果排列组合可以得到4+4*4+4*4*4+4*4*4*4种不同的结果,对于一个6天的项目,设计5个关卡来说,已经足够的不能再足够了,当然这只是关卡的逻辑设计部分也是较为烧脑的部分,至于场景如何搭建并不需要花很多时间来思考。
2.考虑玩家的感受
在关卡设计过程中,我们还遇到了一些问题,在最初我们并没有设计新手关卡,我们自认为2D跳跃的游戏,大家玩多了,应该上来就知道怎么玩。但显然这种思路是错误的,因为毕竟我们还是有一定的创新机制在里面,并且它本身也并不是那么容易掌握。
于是在大家的一致建议下,我们为玩家添加了3个新手关卡,循序渐进,难度依次递增,来试图让新接触我们游戏的玩家能快速理解我们游戏的机制,游玩并通关。
七、总结与反思—制定自己的工业化流水线
以上就是关于我第一次游戏开发经历的总结与反思。
还有一点,对于我们这种第一次开发游戏的人来说,个人认为这些是很容易遇到的问题,对于成熟的独立游戏开发者,工作室,公司等,它们应该有一套完整的工业流水线和体系,能够完美的避免这些问题,同时由于我们的项目很简单,所以有许多问题可能是没到一定体量是不会遇到的,因此本篇写的也只是冰山一角,想要流畅的做出一款游戏,还是需要很多碰壁和磨练的。
本质上来说这是一个工程性的东西,和单纯的学习是不一样的,本文没有提到的性能优化,适配等等问题是工业中实际经常会遇到的问题,而我们没有考虑并不代表没有这些问题。
本文提到的问题对于刚入门游戏开发,或者想参加一些游戏开发比赛的小白来说应该还是有一些参考价值的,总的来说,提前的风险预测排雷很重要。希望大家都能在经历中总结和思考,不断历练自己成为一个优秀的工程师。
八、结语
脑袋有点难受,不想写了。。。。。。
相关文章:

【发烧期间随笔】第一次游戏开发经历的总结与反思
一、前言 这两天三阳了,头疼头晕恶心发烧打喷嚏流鼻涕咳嗽嗓子疼气管疼都找上门来了,这导致一周以来都没学什么东西,无意间又刷到各个游戏厂关于本人目标岗位HC骤减且要求造火箭的能力的消息,这两天一直是在病痛和焦虑中度过的&a…...
CCombBox组合框
1、 MFC_Combo_Box(组合框)的详细用法_mfc combo-CSDN博客 2、 常用属性设置: 属性 含义 data 设置内容,不同内容间用英文的分号“;”分隔 type 显示风格 Sort True 内容自动排序 常用接口: 接口 功能 CComboBox::AddString 组…...

机器学习-有监督学习-神经网络
目录 线性模型分类与回归感知机模型激活函数维度诅咒过拟合和欠拟合正则数据增强数值稳定性神经网络大家族CNNRNNGNN(图神经网络)GAN 线性模型 向量版本 y ⟨ w , x ⟩ b y \langle w, x \rangle b y⟨w,x⟩b 分类与回归 懂得两者区别激活函数&a…...
React之组件通信
#一、是什么 我们将组件间通信可以拆分为两个词: 组件通信 回顾Vue系列 (opens new window)的文章,组件是vue中最强大的功能之一,同样组件化是React的核心思想 相比vue,React的组件更加灵活和多样,按照不同的方式可…...
什么是微服务架构
阅读“微服务架构”一词可能会让您直观地了解该术语的含义:计算架构中的小型服务。这个定义并不完全错误,但也不完全正确。 微服务架构通常被称为“打破整体”的一种方式。遗憾的是,这与《2001:太空漫游》无关,而是将…...
<%=%>模板写法
<%%> 这种写法通常称为 "内嵌式模板" 或 "模板标记",在前端开发中,这种标记语法用于将动态数据嵌入HTML模板中。这种写法通常与模板引擎一起使用,这些模板引擎会根据提供的数据动态生成HTML。 不同的模板引擎可能…...

python爬取boss直聘数据(selenium+xpath)
文章目录 一、主要目标二、开发环境三、selenium安装和驱动下载四、主要思路五、代码展示和说明1、导入相关库2、启动浏览器3、搜索框定位创建csv文件招聘页面数据解析(XPATH)总代码效果展示 六、总结 一、主要目标 以boss直聘为目标网站,主要目的是爬取下图中的所…...

GEO生信数据挖掘(六)实践案例——四分类结核病基因数据预处理分析
前面五节,我们使用阿尔兹海默症数据做了一个数据预处理案例,包括如下内容: GEO生信数据挖掘(一)数据集下载和初步观察 GEO生信数据挖掘(二)下载基因芯片平台文件及注释 GEO生信数据挖掘&…...
8.Mobilenetv2网络代码实现
代码如下: import math import os import numpy as npimport torch import torch.nn as nn import torch.utils.model_zoo as model_zoo#1.建立带有bn的卷积网络 def conv_bn(inp, oup, stride):return nn.Sequential(nn.Conv2d(inp,oup,3,stride,biasFalse),nn.Bat…...
Spring Boot Controller
刚入门小白,详细请看这篇SpringBoot各种Controller写法_springboot controller-CSDN博客 Spring Boot 提供了Controller和RestController两种注解。 Controller 返回一个string,其内容就是指向的html文件名称。 Controller public class HelloControll…...
在网络安全、爬虫和HTTP协议中的重要性和应用
1. Socks5代理:保障多协议安全传输 Socks5代理是一种功能强大的代理协议,支持多种网络协议,包括HTTP、HTTPS和FTP。相比之下,Socks5代理提供了更高的安全性和功能性,包括: 多协议支持: Socks5代…...

Web测试框架SeleniumBase
首先,SeleniumBase支持 pip安装: > pip install seleniumbase它依赖的库比较多,包括pytest、nose这些第三方单元测试框架,是为更方便的运行测试用例,因为这两个测试框架是支持unittest测试用例的执行的。 Seleniu…...
jvm打破砂锅问到底- 为什么要标记或记录跨代引用
为什么要标记或记录跨代引用. ygc时, 直接把老年代引用的新生代对象(可能是对象区域)记录下来当做根, 这其实就是依据第二假说和第三假说, 强者恒强, 跨代引用少(存在互相引用关系的两个对象,是应该倾 向于同时生存或者同时消亡的). 拿ygc老年代跨代引用对象当做根…...
小程序长期订阅
准备工作 ::: tip 管理后台配置 小程序类目:住建(硬性要求) 功能-》订阅消息-》我的模版 申请模版:1、预约进度通知 2、申请结果通知 3、业务办理进度提醒 ::: 用户订阅一次后,可长期下发多条消息。目前长期性订阅…...

Studio One6.5中文版本版下载及功能介绍
Studio One是一款专业的音乐制作软件,由美国PreSonus公司开发。该软件提供了全面的音频编辑和混音功能,包括录制、编曲、合成、采样等多种工具,可用于制作各种类型的音乐,如流行音乐、电子音乐、摇滚乐等。 Studio One的主要特点…...

07-Zookeeper分布式一致性协议ZAB源码剖析
上一篇:06-Zookeeper选举Leader源码剖析 整个Zookeeper就是一个多节点分布式一致性算法的实现,底层采用的实现协议是ZAB。 1. ZAB协议介绍 ZAB 协议全称:Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。 Zook…...

云原生安全应用场景有哪些?
当今数字化时代,数据已经成为企业最宝贵的资产之一,而云计算作为企业数字化转型的关键技术,其安全性也日益受到重视。随着云计算技术的快速发展,云原生安全应用场景也越来越广泛,下面本文将从云原生安全应用场景出发&a…...

Step 1 搭建一个简单的渲染框架
Step 1 搭建一个简单的渲染框架 万事开头难。从萌生到自己到处看源码手抄一个mini engine出来的想法,到真正敲键盘去抄,转眼过去了很久的时间。这次大概的确是抱着认真的想法,打开VS从零开始抄代码。不知道能坚持多久呢。。。 本次的主题是搭…...

Excel 插入和提取超链接
构造超链接 HYPERLINK(D1,C1)提取超链接 Sheet页→右键→查看代码Sub link()Dim hl As HyperlinkFor Each hl In ActiveSheet.Hyperlinkshl.Range.Offset(0, 1).Value hl.AddressNext End Sub工具栏→运行→运行子过程→提取所有超链接地址参考: https://blog.cs…...
基础架构开发-操作系统、编译器、云原生、嵌入式、ic
基础架构开发-操作系统、编译器、云原生、嵌入式、ic 操作系统编译器词法分析AST语法树生成语法优化生成机器码 云原生容器开发一般遇到的岗位描述RDMA、DPDK是什么东西NFV和VNF是什么RisingWave云原生存储引擎开发实践 单片机、嵌入式雷达路线规划 ic开发 操作系统 以C和Rust…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...