[Game Framework之StarForce解读]04.游戏场景
上一篇我们聊得不是很愉快,我觉得我们不是很适合…个屁啊!都说些什么呢。
上一篇我们只是发现了框架的作者是怎么让游戏进入到游戏主场景的,真正重要的是游戏主场景里都做了些什么事情,这一篇,我们就来瞎猜ProcedureMain里都做了些什么吧。(旁白:果然从一开始就是骗人的啊,一直都瞎猜的啊!)
1.OnInit
ProcedureMain也是一个流程,自然也就按照流程的生命周期来研究它了,首先是OnInit,这个就算瞎猜都知道,它是在OnEnter之前执行的,我非常肯定….
后来我还是研究了一下,发现,OnInit确实是在OnEnter之前调用的,而且是非常前,在流程初始化时就调用(此时还没切换到Main流程)。如果没看错的话,是这么个逻辑,以后再深入研究。
protected override void OnInit(ProcedureOwner procedureOwner)
{Debug.LogError("OnInit");base.OnInit(procedureOwner); m_Games.Add(GameMode.Survival, new SurvivalGame());
}
OnInit里只做了一件事情——添加游戏类型对应的处理类。
m_Games只是一个字典对象,用来存放不同游戏类型对应的处理类(比如生存、无限、关卡模式)。
这里不是非得要这个m_Games对象的,只是StarForce这个项目这么做了,与Game Framework框架本身没有什么关系。
由于StartForce只有生存模式,所以这里只添加了一种类型。
2.OnEnter
最重要的是OnEnter函数:
protected override void OnEnter(ProcedureOwner procedureOwner)
{Debug.LogError("OnEnter");base.OnEnter(procedureOwner); // 控制是否返回菜单的标记m_GotoMenu = false; // 获取游戏类型(GameMode只是一个枚举而已)GameMode gameMode = (GameMode)procedureOwner.GetData<VarInt>(Constant.ProcedureData.GameMode).Value; // 获取游戏类型对应的处理器(暂且这么称呼吧)m_CurrentGame = m_Games[gameMode]; // 初始化游戏m_CurrentGame.Initialize();
}
OnEnter其实也很简单,只做了一件事情——初始化游戏。
但是,StarForce并不是随意写的一个demo,它做了一些简单的封装(比如游戏模式)。
这里需要先获取游戏模式对应的处理类,然后再调用处理类进行初始化操作。
这里的操作并不是固定的套路,大家完全可以按照自己的方式初始化游戏。
可能大家注意到了一个VarInt类型,它其实就是int类型(最终),但是框架作者为了避免一些bug,在某些情况下需要用到封装后的类型。具体请参考:http://gameframework.cn/archives/227
3.游戏逻辑(GameBase)
上一步我们已经看到了,在OnInit的时候会获取SurvivalGame类对游戏进行初始化。
如果大家有认真听我讲,并按我说的去做的话,应该已经发现了,SurvivalGame是继承了GameBase的(旁白:完全没有讲!压根没提到过!别瞎忽悠。)
所以我们要先来看看GameBase,它是StarForce的一个类,并不是框架自带的,所以,GameBase里做的所有事情,大家都可以按照自己的方式来实现,不要被框住了。
GameBase的函数有好几个,其他都不重要,我只和大家说一下初始化函数:
public virtual void Initialize()
{// 订阅显示实体的消息GameEntry.Event.Subscribe(ShowEntitySuccessEventArgs.EventId, OnShowEntitySuccess);GameEntry.Event.Subscribe(ShowEntityFailureEventArgs.EventId, OnShowEntityFailure); SceneBackground = Object.FindObjectOfType<ScrollableBackground>();if (SceneBackground == null){Log.Warning("Can not find scene background.");return;} SceneBackground.VisibleBoundary.gameObject.GetOrAddComponent<HideByBoundary>(); // 重点!显示玩家的飞机实体,这里是做了几层封装的GameEntry.Entity.ShowMyAircraft(new MyAircraftData(GameEntry.Entity.GenerateSerialId(), 10000){Name = "My Aircraft",Position = Vector3.zero,}); GameOver = false;m_MyAircraft = null;
}
关于初始化函数,我只想说一个——它是如何加载玩家的飞机的?
代码中我已经做了注释,加载飞机是调用了ShowMyAircraft函数,这也不是框架的函数,而是StarForce的函数。
一层层跟进后,大家应该能找到,该函数最终调用的是EntityExtension.cs里的ShowEntity函数:
private static void ShowEntity(this EntityComponent entityComponent, Type logicType, string entityGroup, EntityData data)
{if (data == null){Log.Warning("Data is invalid.");return;} IDataTable<DREntity> dtEntity = GameEntry.DataTable.GetDataTable<DREntity>();DREntity drEntity = dtEntity.GetDataRow(data.TypeId);if (drEntity == null){Log.Warning("Can not load entity id '{0}' from data table.", data.TypeId.ToString());return;} entityComponent.ShowEntity(data.Id, logicType, AssetUtility.GetEntityAsset(drEntity.AssetName), entityGroup, data);
}
重点是GetDataRow和ShowEntity两个函数。
这里大致是做了这么两件事情:
a.通过玩家飞机的ID读取配置文件
b.根据配置文件的配置加载实体
至于配置文件是如何加载的,这里不深入研究,但是我们可以看看配置文件长什么样的(Assets\GameMain\DataTables目录):
此时再来回忆一下GameBase的初始化函数:
是不是想起了什么神奇的事情?(旁白:完全没有)
我们再来理一遍,整个玩家飞机实体的创建过程:
a.GameBase里的初始化函数,调用了ShowMyAircraft函数,并且参数是一个MyAircraftData类型,指定了配置文件id(typeID:10000)
b.根据typeID从Entity.txt配置文件里读取数据
c.根据读取的配置数据调用框架的ShowEntity函数加载实体
d.至于实体是如何被加载的,这里就暂不深入了
这是一个很简单的流程,大家多看看代码,就能理解了。
如果看不懂的话…可能是你还没有到达需要学习框架的程度,这种情况的话,可以先去多写几个游戏。
4.SurvivalGame处理类
GameBase只是基础类,它是所有游戏模式的基础,因为所有游戏模式都需要创建玩家飞机实体,所以它才做了这件事情。
我们要研究的是生存模式下游戏逻辑是如何处理的,所以,我们现在来看SurvivalGame类(继承了GameBase)。
SurvivalGame很简单,只有一个Update函数:
public override void Update(float elapseSeconds, float realElapseSeconds)
{base.Update(elapseSeconds, realElapseSeconds); m_ElapseSeconds += elapseSeconds; // 每隔1秒创建一个怪物if (m_ElapseSeconds >= 1f){m_ElapseSeconds = 0f;IDataTable<DRAsteroid> dtAsteroid = GameEntry.DataTable.GetDataTable<DRAsteroid>(); // 随机的x、z坐标float randomPositionX = SceneBackground.EnemySpawnBoundary.bounds.min.x + SceneBackground.EnemySpawnBoundary.bounds.size.x * (float)Utility.Random.GetRandomDouble();float randomPositionZ = SceneBackground.EnemySpawnBoundary.bounds.min.z + SceneBackground.EnemySpawnBoundary.bounds.size.z * (float)Utility.Random.GetRandomDouble();// 加载怪物实体GameEntry.Entity.ShowAsteroid(new AsteroidData(GameEntry.Entity.GenerateSerialId(), 60000 + Utility.Random.GetRandom(dtAsteroid.Count)){Position = new Vector3(randomPositionX, 0f, randomPositionZ),});}
}
SurviValGame只做一件事情——定时创建怪物。
创建怪物的方式很简单,和创建玩家飞机实体是一样的。
每隔1秒钟,获取一个随机坐标,然后调用ShowAsteroid函数创建怪物实体(typeID为60000)。
ShowAsteroid函数我们不需要跟进去就能知道它做了什么事情了(读取配置文件,根据配置加载实体)。
5.唠叨一下
从以上的介绍中,我们大致发现了框架作者的一个秘密——游戏中所有对象(如怪物、玩家)都是从配置文件中加载配置,然后再创建出来。(旁白:是的,框架作者在一开始就说过了,然而你花了一篇的时间来解释)
到目前为止,我们还没进入最重要的部分,下一篇,我们就一起来看看玩家飞机的逻辑处理类是怎么和飞机对象绑定的吧。
[Game Framework之StarForce解读]04.游戏场景相关推荐
- [Game Framework之StarForce解读]02.游戏入口
本文 Game Framework 版本:3.1.0 本文 Unity3D 版本:2017.3 更多GF教程和实例:https://github.com/mutouzdl/gameframework_ ...
- [Game Framework之StarForce解读]01.StarForce下载运行
本文 Game Framework 版本:3.1.0 本文 Unity3D 版本:2017.3 更多GF教程和实例:https://github.com/mutouzdl/gameframework_ ...
- Unreal Engine+Houdini创造程序性游戏场景视频教程
Unreal Engine+Houdini创造程序性游戏场景视频教程 大小解压后:27.4G 持续时间14小时30分 包括项目文件 1920X1080 高清视频 程序游戏环境--虚幻引擎和Houdin ...
- 实验二 建立基本的游戏场景
实验二 建立基本的游戏场景 一.实验内容: 1. 建立一个简单的游戏场景: 2. 通过摄像机实现场景的切换: 3. 使用不同的光照实现阴影效果: 二.实验目的: 1. 了解Ogre程序的工作方法和Og ...
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通常会使用方法 Application.LoadLevel("yourSc ...
- 20190324游戏场景百度地图150次联网耗电
2D1Z 2D1N 2D1F 项目 第一轮 第二轮 第一轮 第二轮 第一轮 第二轮 1 30 Mins Game 378.38 294 277.65 272.25 2 30 Mins Music Pl ...
- 基于边缘计算的云游戏场景实践
云游戏并不是一个新兴事物,相关的构想早在本世纪初就已经提出.近年来,随着云计算的不断演进,光纤入户的普及和5G网络的铺开,云游戏逐渐从技术成熟阶段走向了商业可行和商业腾飞阶段[1].根据相关咨询公司的 ...
- UE5废墟破坏游戏场景创建学习教程
为游戏创建毁坏的资产–深入教程课程 了解一个专业的环境艺术家在为游戏创建毁坏的资产时是如何工作的.您将学习正确的资产规划.创建模块化资产.创建损坏的混凝土和柱子.创建损坏的木材/地板.创建碎石堆.模拟 ...
- UE卡通风格游戏场景制作视频教程
UE卡通风格游戏场景制作视频教程 UE卡通风格游戏场景制作视频教程 教程大小:4.53G 含项目文件 3840X2160 mp4 语言:英语+中英字幕(机译) 本教程是关于UE4卡通渲染游戏环境场景制 ...
最新文章
- 一次愉快的 bug 修复经历
- Python叠加装饰器,三元表达,生成,调用,递归
- stk 坐标系_STK中文用户手册.pdf
- 三、Git多人开发:不同人修改了同文件的不同区域如何处理
- [转载] java 计算协方差_Java的深度:通过协方差暴露的API泄漏
- 2018下半年初级程序员考试时间
- cs61b-Java数据结构(一)autograder配置
- 计算机制谱软件finale+2011应用教程,Finale2014(打谱软件)
- 6.4.10 删除电子邮件
- 计算机网络常见简答题
- 包误差率(PER)与BER相关
- 80后 程序猿 单恋10年,是一种怎样的体验?
- StrokeIt-单手摸鱼的快乐你想象不到
- 督查督办系统在企业能发挥哪些作用?
- 解决to_csv循环追加数据不会覆盖前面的数据
- Python人脸识别签到考勤系统
- 多张mbtitles合并为一张mbt
- 记录解决问题--ie闪退
- Visual Studio Code之xml编辑器安装
- [RPI2]wiringPi驱动5110