RougueLike游戏随机地图生成(1)

作为一个游戏狂热的爱好者,笔者从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预定),密室里面会有一个宝藏箱,以及其他的想法若干

猜你喜欢

转载自www.cnblogs.com/muyuweiyi/p/12093323.html