1.道路的自动生成

道路自动生成概述:

3D跑酷游戏的核心就是跑,在跑这一过程中增加趣味性使得游戏具有更多的可玩性。道路的自动生成和自由拼接,为游戏增设了更多的不可预见性。这种不可预见性使得玩家在游戏中更多的体验到探索精神,进而开发玩家对游戏的兴趣。因此在跑酷游戏中,并不建议开发者设定好固定的场景道路,道路的自动生成模式更能吸引玩家。开发者可以通过不同的方式来实现道路的自动生成,将角色固定点场景后移的方式实现;或者固定道路的坐标,通过角色的向前奔跑产生位移变化。

原理:

通过使角色不断奔跑,产生相应位移变化,来达到道路的自动生成为例。将道路抽象的想象成一块块的板子,道路的不同场景转换和消失就如同板子的拼接和掉落。其原理流程,如图1-1所示。


图1-1

实现方法:

步骤1:

导入美术资源。将制作好的道路美术资源导入Genesis-3D引擎中。以shanggu01.fbx为例。将shanggu01.fbx文件导入项目文件夹->将项目文件里的资源文件拖入场景->附材质。这里需要注意,为了使道路可以完美拼接,道路场景制作接口处尺寸应该一样。并将文件转换为template。方便重复利用资源,方法如下图1-1-1所示。


图1-1-1

步骤2:

道路的拼接原理及实现:

2.1拼接原理:以两个道路拼接为例,抽象理解为板子A、B。

引擎中在板首尾的同侧方向创建两个空对象,按照下图原则,将所有道路场景文件都标记好。如图1-2-1-1所示


图1-2-1-1

通过创建Template,把下一个板的中心点,放到前一个板的连接点就可以了,即将当前游戏角色所在A板的连接点坐标覆盖为下一块板B中心点的坐标。


图1-2-1-2

2.2道路的拼接与生成实现。道路自动生成与拼接的相关代码框架,如下所示。。

在RunTimeBoardMgr文件中,Init初始化函数里加上你要新添加的模板类型:

01 public void Init ()
02 {                    
03  AddTemplate("ShanDong_01.template", GroundBoardType.Beginner, 0, 0);
04  AddTemplate("ShanDong_01.template", GroundBoardType.ShanDong1, 0, 0);
05  AddTemplate("ShanDong_02.template", GroundBoardType.ShanDong2, 0, 0);
06  AddTemplate("ShanDong_03.template", GroundBoardType.ShanDong3, 0, 0);
07  AddTemplate("ShanGu_01.template", GroundBoardType.ShanGu, 0, 0);
08  AddTemplate("ShanGu_02.template", GroundBoardType.ShanGu, 0, 0);
09  _boardConnectionMgr.Init();
10  Reset();
11  Preload();
12 }

其中AddTemplate()函数的参数分别是你要添加的模板名字、地形块儿类型、地形块儿等级以及地形块儿的障碍物类型。

01  void AddTemplate (string templateName, GroundBoardType type, int level, int barrierType)
02 {
03  nt templateListIndex = (int)type;
04  if (templateListIndex < 0 || templateListIndex >= _templateList.Length)
05  {
06   return;
07  }
08  if (_templateList[templateListIndex] == null)
09  {
10   _templateList[templateListIndex] = new BoardTemplateGroup();
11  }
12   BoardTemplate newTemplate = new BoardTemplate(templateName, level, barrierType);
13   _templateList[templateListIndex].Add(newTemplate);
14 }

AddTemplate()函数会创建一个新的BoardTemplate对象,并把它放到模板列表中,BoardTemplate类,如下所示。

01 public class BoardTemplate
02 {
03  string _templateName;// 模板名字
04  int _level;//板子的等级
05  int _barrierType;//障碍物类型
06  public BoardTemplate(string name, int level, int barrierType)
07  {
08   _templateName = name;
09   _level = level;
10   _barrierType = barrierType;
11  }
12  
13  public string Name
14  {
15   get{return _templateName;}
16  }
17  public int Level
18  {
19   get{return _level;}
20  }
21  public int BarrierType
22  {
23   get{return _barrierType;}
24  }
25 }

接着在LogicMgr.cs的Tick里面,每一帧都会用角色的位置信息,去判定是否要更新地形块儿。

1 public void Tick (float elapseTime)
2 {
3  …………
4  …………
5  _runtimeBoardMgr.CheckUpdateBoard(PlayerDataMgr.Singleton.Pos.Z);
6  …………
7  …………
8 }

当满足判定条件时,就会自动的创建一块儿新板子拼接上去。

01 public void CheckUpdateBoard (float playerPosZ)
02 {
03  if (playerPosZ > _EndPos - StaticData.CreateBoardDistance)
04  {
05   if(LogicMgr.Singleton.IsBeginner && _boardList.Count > 0)
06   {
07    CreateNewBorad (RandomBoardType.Beginner);
08   }
09   else
10   {
11    CreateNewBorad (RandomBoardType.Normal);
12   }
13  }
14  …………
15  …………
16 }

创建新板子的代码,如下所示。

01 void CreateNewBorad (RandomBoardType randomBoardType)
02 {
03  //是否是第一块儿板子
04  bool firstBoard = _boardList.Count > 0 ? false true;
05  //创建一个新的GroundBoardBase
06  GroundBoardBase newBoard = null;
07  //根据板子的随机类型调用不同的随机板子函数
08  if (randomBoardType == RandomBoardType.Beginner)
09  {
10   newBoard = RandomBeginnerBoard ();
11  }
12  else
13  {
14   newBoard = RandomNextBoard (firstBoard);
15  }
16  if (newBoard == null)
17  {return; }
18  //初始化这个newBoard上面的Item
19  GroundBoardBase.InitData initData = new GroundBoardBase.InitData ();
20  initData.PlayerZSpeed = PlayerDataMgr.Singleton._zSpeed;
21  if (newBoard.IsHaveItem)
22  {
23   initData.RandomItemType = _randomItemMgr.RandomItem ();
24  }
25  else
26  {
27   initData.RandomItemType = Item.ItemType.Nothing;
28  }
29  newBoard.Init(initData);
30  newBoard.ResetBoard();
31  //根据上一块板子的连接点位置,来摆放这块儿新板子
32  if (firstBoard)
33  {
34   newBoard.SetPos (StaticData.kBoardWidth / 2, 0, 0);
35  }
36  else
37  {               
38   GroundBoardBase preBoard = _boardList [_boardList.Count - 1];
39   newBoard.SetPos(preBoard.EndPos.X,preBoard.EndPos.Y,preBoard.EndPos.Z);
40  }
41   _EndPos += newBoard.Length;
42   _boardList.Add (newBoard);
43 }

创建普通板子举例:

01 GroundBoardBase RandomNextBoard (bool firstBoard)
02 {
03  //根据自行定义的拼接规则,随机出一个下一块板子的模板文件
04  AreaType nextBarrierType = AreaType.Rest;
05  if (firstBoard)
06  {
07   _lastBoardType = StaticData.FirstBoardType;
08  }
09  else
10  {
11   _lastBoardType=_boardConnectionMgr.RandomNextBoardType (_lastBoardType);
12   nextBarrierType = RandomNextAreaType();
13  }
14   BoardTemplateGroup boardGroup = _templateList[(int)_lastBoardType];
15   BoardTemplate template = boardGroup.Random (nextBarrierType);
16   //根据模板文件的名字创建新板子
17   if (template == null)
18   {return null;}
19   GroundBoardBase newBoard = null;                   
20   newBoard = new GroundBoardFlat (template.Name, _lastBoardType);
21   eturn newBoard;
22 }

这里创建一个新的GroundBoardBase的时候,会根据模板文件的名字来创建这个Actor:

1 public GroundBoardBase (string templateName)
2 {
3  _groundActor=ActorManager.CreateFromTemplate (StaticData.BoardTemplatePath + templateName,false);
4   }

如果开发者的设计思路,与游戏DEMO相同的话,可以直接套用上面的代码,只需要在最上面的AddTemplate(模板文件名, 板子类型, 板子等级, 障碍物类型);稍作修改,即可使用。


引擎官方网站:http://www.genesis-3d.com.cn/

官方论坛:http://bbs.9tech.cn/genesis-3d/

官方千人大群:59113309   135439306

YY频道-游戏开发大讲堂(完全免费,定期开课):51735288

Genesis-3D开源游戏引擎:游戏起源,皆因有我!!!

 


《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇01:道路的自动生成》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. 团体程序设计天梯赛-练习集L1-022. 奇偶分家

    L1-022. 奇偶分家 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定N个正整数,请统计奇数和偶数各有多少个? 输入格式 ...

  2. gcc: error trying to exec 'cc1plus': execvp: 没有该文件或目录 解决方案

    一般来说,装完linux系统(ubuntu)后,要自己安装java或者c/c++的环境. 这个提示就是说你的系统缺少 g++ 包. 请执行:sudo apt-get install g++  (在ub ...

  3. tomcat context 配置 项目部署

    将tomcat/conf/server.xml文件打开, 在</Host>标签之前添加: <Context path = "" docBase = "F ...

  4. ZOJ Monthly, November 2014

    做了一次月赛,没想到这么难,加上后来补上的题目也只有3个题.第一名也只有4个题啊啊啊啊~.其中两道还是水题.留坑慢慢补上来. 3832 Tilt Cylinder 给定如图所示有盖圆柱体,R,H,水面 ...

  5. Qt之显示网络图片(可以改成升级模块)

    http://blog.csdn.net/u011012932/article/details/50773382

  6. editplus的配置文件来支持sql语法高亮【转】

      editplus默认是没有sql语法高亮的,原因是它的内部没有sql.stx的这样一个语法文件 我们自己在 EditPlus 的安装目录下面新建一个文件名为sql.stx,然后打开editplus ...

  7. Git教程之使用GitHub

    我们一直用GitHub作为免费的远程仓库,如果是个人的开源项目,放到GitHub上是完全没有问题的.其实GitHub还是一个开源协作社区,通过GitHub,既可以让别人参与你的开源项目,也可以参与别人 ...

  8. SGU 101

    SGU 101,郁闷,想出来算法,但是不知道是哪个地方的问题,wa在第四个test上. #include <iostream> #include <vector> #inclu ...

  9. 绕过图片格式限制上传木马获取WebShell

    思路: 图片上传功能中,前端页面上传的是.png格式的图片文件,但是抓包Request中修改图片后缀为.php 可以绕过对上传文件格式的限制,文件的上传路径可以在上传后的页面或查看上传成功后的resp ...

  10. 无效的 URI: 未能分析证书颁发机构/主机

    出 现该错误的原因是URL中少了一个斜杠,正常的URL是“http:”后边有两个斜杠,而我在修改配置文件中的URL的IP地址部分时,不小心删掉了一个 斜杠,例如:http:/blog.csdn.net ...