【unity】关于一个简单跑酷地图自动生成的思路与实现

【unity】关于一个简单跑酷地图自动生成的思路与实现前言 最近在开发一款跑酷类小游戏 考虑到地编很麻烦 决定写一段随机生成地图的程序 由于项目时间紧张 本文内容比较简单 不适用于复杂的跑酷地图生成 如有错误 请斧正 地图设计 一 设计地图样式 选取了类似地铁跑酷的地图 当然比它要简单得多

大家好,我是讯享网,很高兴认识大家。

前言

        最近在开发一款跑酷类小游戏,考虑到地编很麻烦,决定写一段随机生成地图的程序。由于项目时间紧张,本文内容比较简单,不适用于复杂的跑酷地图生成,如有错误,请斧正。

地图设计

        一、设计地图样式

        选取了类似地铁跑酷的地图(当然比它要简单得多),分为三条跑道,玩家通过切换跑道、跳跃、滑铲等方式避开障碍物。可将跑道看作一个3行n列的网格,每个障碍物占一格空间。

        二、障碍物类型

        1、柱型障碍物。即玩家不可跳跃或滑铲躲避的障碍物,只能通过切换跑到躲开。

        2、低矮型障碍物。即玩家可以跳过或切换跑道躲避的障碍物。

        3、悬挂型障碍物。即玩家可以滑铲或切换跑道躲避的障碍物。

        4、可消除型障碍物。即玩家可通过某个操作使其消除的障碍物,同时也可以切换跑道躲避。

        三、添加生成限制

        为了简化地图生成方法,并保证不出现死路,为障碍物的生成添加两个限制:

        1、每种类型的障碍物在每一列至多生成一个。

        2、在每一行(即每条跑道)中每个障碍物的前后两格内不能生成障碍物。

实现过程

        一、总体思路

        首先将地图3行n列的网格储存为一个字符类型的二维数组,用不同符号表示不同的障碍物类型以及通路。

        定义四个障碍物类实现同一个接口,并在类中提供生成本类障碍物的方法。

        再定义一个地图生成类,然后依次调用每类障碍物中的方法,生成每种障碍物,例如先生成地图上所有的柱型障碍物,再生成所有的低矮型障碍物,以此类推生成四种类型的障碍物。

        最后遍历该数组,在场景中绘制出完整的地图。

        二、程序设计

        UML类图如下:


讯享网

        首先定义一个障碍物接口,包含四个方法:创建障碍物(createBarrier)、间隔数增加(intervalIncrease)、重置间隔数(intervalReset)、是否可以放置障碍物(isCanBeBarrier)。

using System.Collections; using System.Collections.Generic; using UnityEngine; public interface Barrier { public char[,] createBarrier(char[,] map, int mapLength); public int intervalIncrease(int interval); public void intervalReset(); public bool isCanBeBarrier(); }

讯享网

       

        其次分别定义四种障碍物类实现该接口。此处以柱型障碍物为例。使用三个参数控制随机生成,分别为:最小生成间隔(minInterval)、最大生成间隔(maxInterval)、生成概率(rate)。并定义两个属性:当前间隔数(currInterval)、代表字符(barrierChar)。

        重写接口中的方法:

        先判断是否满足三个参数所控制的条件,当当前间隔数大于最小生成间隔且随机数落在概率区间时,表示可以生成障碍物,当当前间隔数大于最大间隔数时不论概率,都可以生成障碍物。代码如下:

讯享网 public bool isCanBeBarrier() { System.Random random = new System.Random(); //当该位置与上一放置位置的间隔大于等于最小间隔时,按照概率生成障碍物 if (random.Next(1, 101) <= rate && currInterval >= minInterval || currInterval >= maxInterval) return true; else return false; }

        基于上面的函数返回值,再加上上文提到的两个限制条件,即可得到障碍物生成函数,代码如下:

public char[,] createBarrier(char[,] map, int mapLength) { //每行生成一个该类型的障碍 for (int i = 0; i < mapLength; i++) { System.Random random = new System.Random(); if (isCanBeBarrier()) { int idx = random.Next(0, 3); //当该位置是通路且前面两格内没有障碍物时则可放置障碍物 if (map[idx, i] == 'o' && map[idx, i - 1] == 'o' && map[idx, i - 2] == 'o' && map[idx, i + 1] == 'o' && map[idx, i + 2] == 'o') { //在数组中生成一个障碍物 map[idx, i] = barrierChar; //重置间隔 intervalReset(); } } else { currInterval = intervalReduce(currInterval); } } //返回生成后的地图 return map; }

       剩余两个方法的重写较为简单,这里就不多做赘述。

        然后定义生成地图类,该类中定义了一个静态变量map,是一个储存地图的二位数组。定义一个Barrier类型长度为四的数组barriers,分别用四种障碍物的构造函数实例化,这样做的好处是方便对其统一操作。

        生成地图时只需要遍历barriers数组,分别调用其中的createBarrier(map, mapLength)方法,代码如下:

讯享网 public void createMap(int mapLength) { for(int i = 0; i < 4; i++) { map = barriers[i].createBarrier(map, mapLength); } }

        当然别忘了将地图全部初始化为通路,可将数组全部元素初始化成“o”。

        最后定义地图绘制类绘制地图。

        获取每种障碍物的预制体,遍历map数组并将预制体实例化。代码如下:

public void drawMap() { //实例化地图 for(int i = 0; i < mapLength; i++) { for(int j = 0; j < 3; j++) { Vector3 position = new Vector3(j - 1, 0, i); switch (MapCreater.map[j, i]) { case 'o': //通路 break; case '#': //柱形障碍 Instantiate(barrier_high, position, barrier_high.transform.rotation); break; case '_': //低矮型障碍 Instantiate(barrier_down, position, barrier_down.transform.rotation); break; case '^': //悬挂型障碍 Instantiate(barrier_up, position, barrier_up.transform.rotation); break; case '!': //活动型障碍 Instantiate(barrier_active, position, barrier_active.transform.rotation); break; default: Debug.LogError("地图错误!!!"); break; } } } }

        该方法只负责生成障碍物,别忘了生成地面哦。

        上述内容只介绍了每个类的主要方法,还有例如初始化等简单的方法没有过多赘述,诸位可自行探索。

最终效果

        仅作为演示用,所以没有添加美术素材,有点抽象请见谅。

        障碍物基本均匀分布,密度和频率可由最小间隔数、最大间隔数、概率三个参数决定,实例中每个障碍物的参数均相同,可改变参数使其不同来增加随机性。

小结

        本文中的每种障碍物的生成方法完全相同,为增加其多样性,可为每种障碍物“量身定制”这些方法。同时本文的障碍物均占地一格,如果想生成占一个跑道的多格或者多个跑道的障碍物,可在对应障碍物类中createBarrier(char[,] map, int mapLength)方法的基础上修改,希望本文可以给你一些灵感。

小讯
上一篇 2025-03-31 22:56
下一篇 2025-03-09 18:47

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/136131.html