作为一个游戏狂热的爱好者,笔者从3年级接触《红色警戒》开始便疯狂的爱上了电子游戏,从Rts到Moba,从网游到单机,笔者接触了非常非常多的游戏,作为一个玩家,和因为爱好不幸加入游戏行业的菜鸡程序员,笔者也在无聊之余尝试自己写一些辣鸡独立游戏,均因为水平不足而只能中途弃坑,最近在读书学习之余又开一新坑,emmmm,想写一些不知所云的东西,希望在弃坑之后能留一些东西,受限于笔者在编程水平上的水平,可能只能博大家一笑,望轻喷。
笔者曾经玩过一些还算是有趣的手机游戏,比如曾经大火的贪婪洞窟,又或者是最近大火的伊洛纳手游,均使用了随机地图的算法。关于这两款游戏的算法笔者大约有一些猜测和了解,如果有时间可能会去复刻一下,但是笔者在接触了细胞自动机之后,觉得如果搭配上A*算法,那么其实是与上两作不同的地图生成算法,在其之上再略作修饰,没准能做成一个很不错的RougueLike(新)游(坑)戏,所以在简单的代码尝试之后,又开始挖一个新坑。
首先,我们需要一个随机数生成类,
using System.Collections;
using System.Collections.Generic;
using Random = System.Random;
public class RandomCreater {
static Random _random;
public static Random random {
get {
if (_random == null) {
_random = new Random(UnityEngine.Random.Range(-100000, 100000));
}
return _random;
}
}
}
实际上Unity是自带随机数生成的,但是我不太喜欢用,可能以后会记录下随机数生成的种子,毕竟引擎自带的是和时间有关系的
接下来是生成细胞自动机的环节,最终输出的结果是一个二维数组
using System.Collections.Generic;
using UnityEngine;
using Random = System.Random;
namespace GameMapCreater
{
public class Cellular{
static List<Vector2Int> neibors ;
static Cellular() {
neibors = new List<Vector2Int>();
for (int i = -1; i <= 1; i++)
for (int j = -1; j <= 1; j++) {
if (i != 0 || j != 0) {
neibors.Add(new Vector2Int(i, j));
}
}
}
//生成最原始的细胞自动机,1为墙,0为可行走部分
public static int[,] CreateCellular(int weight,int height,int smoothTime,int percent) {
Random random = RandomCreater.random;
int[,] initData = new int[weight, height];
//初始化数据
for (int i = 0; i < weight; i++)//为边界时生成墙,随机出一半的格子位墙
for (int j = 0; j < height; j++) {
if (i == 0 || j == 0 || i == weight - 1 || j == height - 1) {
initData[i, j] = 1;
}
else{
initData[i, j] = random.Next(0, 100) < percent ? 0 : 1;
}
}
for (int i = 0; i < smoothTime; i++) {
initData = IterationCellular(initData);
}
return initData;
}
static int[,] IterationCellular(int[,] data) {
int weight = data.GetLength(0);
int height = data.GetLength(1);
int[,] newData = new int[weight, height];
for (int i = 0; i < weight ; i++)
for (int j = 0; j < height; j++) {
if (i == 0 || j == 0 || i == weight - 1 || j == height - 1) {
newData[i, j] = 1;
continue;
}
int count = 0;
foreach (var neibor in neibors) {
int indexX = i + neibor.x;
int indexY = j + neibor.y;
if (data[indexX, indexY] == 1) {
count++;
}
}
newData[i, j] = count > 4 ? 1 : 0;
}
return newData;
}
}
}
这样一个随机地图的基础雏形就做好了,接下来我们要根据这个雏形来渲染我们的地图,我的想法是地图上会有若干的密室,每一个密室的门口有一个门需要玩家撬开(开锁方法抄袭滚5预定),密室里面会有一个宝藏箱,以及其他的想法若干
原文:https://www.cnblogs.com/muyuweiyi/p/12093323.html