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. OpenSSL重大漏洞-Heartbleed之漏洞利用脚本POC讲解

    OpenSSL Security Advisory [07 Apr 2014] ======================================== TLS heartbeat read ...

  2. Spark的TorrentBroadcast:概念和原理

    依据Spark 1.4.1源码 SparkContext的broadcast方法 注释 可以用SparkContext将一个变量广播到所有的executor上,使得所有executor都能获取这个变量 ...

  3. Flume的Avro Sink和Avro Source研究之一: Avro Source

    问题 : Avro Source提供了怎么样RPC服务,是怎么提供的? 问题 1.1 Flume Source是如何启动一个Netty Server来提供RPC服务. 由GitHub上avro-rpc ...

  4. Django 后台搭建

    # Django settings for gameadmin project. DEBUG = True TEMPLATE_DEBUG = DEBUG ADMINS = ( # ('Your Nam ...

  5. linux下执行 ls,cat等一些命令报出 -bash: /bin/cat: Cannot allocate memory 有没解决的方法

    环境变量配置出错了cd -- 进入用户目录vim .bash_profile删除以前PATH这一行,把下面的粘帖进去PATH=$PATH:$HOME/bin:/root:/root/snapshot/ ...

  6. 14条建议,使你的IT职业生涯更上一层楼

    摘要:升值为企业IT部门的领导者,是大部分IT技术人员职业生涯的最终追求.但从一般大众中脱颖而出,并非易事.仅仅把本职工作干好远远不够,还需要IT技术人员展示出投身于技术发展的奉献精神及伴随技术发展而 ...

  7. chrome禁用某个网站js脚本的执行

      1 首先打开谷歌浏览器.如下 2 点击右上角,打开菜单进入[设置] 3 打开后,第一个界面是没有这个的,要滚动到最后点击[显示高级设置...] 4 展开第二页后,点击[隐私设置]->[内容设 ...

  8. Dubbo使用解析及远程服务框架

    this is a thub here Spring的Remoting框架 阿里巴巴的dubbo框架 RPC,RMI,JMS,Webservice的区别

  9. poj2192

    初看这道题,以为是先用SA和SC求LCS,再从SC中把SA剔除,看剩下来的是不是SB(……) 显然不对;因为SC与SA的公共子串不止一种,判断不一定正确. 于是考虑SC中每一个字符,如果能够匹配,那么 ...

  10. javascript 一些需要知道的东西

    这里我直接贴出代码,注释已经补全,欢迎指正: <script type="text/javascript"> /** 1,js中一切皆是对象,函数也是, 2,当定义变量 ...