游戏中随机地图的实现

很多游戏都用到了随机地图,比如矮人要塞,CDDA,MineCraft,RimWorld。
随机地图带给游戏更多的趣味性,每一次新建游戏都有不同的体验。
一般游戏中生成随机地形都是使用柏林噪声,接下来我们就来看看怎么实现。
  • 游戏中随机地图的实现

    • 白噪声
    • 柏林噪声
    • 柏林噪声的应用
    • 随机地图的生成
    • 参考

白噪声

首先我们先来使用一个白噪声函数试试生成一张完全随机的图片。
public float[][] GenerateWhiteNoise(int width,int height,int seed){Random r = new Random(seed);float[][]noise=new float[width][];for (int i = 0; i < width; i++){noise[i] = new float[height];}for (int i = 0; i < width; i++){for (int j = 0; j < height; j++){noise[i][j] = (float)r.NextDouble() % 1;}}return noise;}
private void mapPanel_Paint(object sender, PaintEventArgs e){Graphics g = e.Graphics;Bitmap bm = new Bitmap(500, 500);float[][] noises = GenerateWhiteNoise(500, 500,6527);for (int i = 0; i < 500; i++){for (int j = 0; j < 500; j++){int co = (int)(noises[i][j] * 256);bm.SetPixel(i, j, Color.FromArgb(co, co, co));}}Pen p = new Pen(Color.Black, 1);g.DrawImage(bm,new Point(0,0));}

完全随机的话,貌似并不能到到我们要的效果,接下来,我们就试试加一些平滑过渡。

柏林噪声

柏林噪声应用在很多游戏的地形生成上,也应用在图片的处理上。
float Interpolate(float x0, float x1, float alpha){return x0 * (1 - alpha) + alpha * x1;}public float[][] GenerateSmoothNoise(float[][] baseNoise, int octave){int width = baseNoise.Length;int height = baseNoise[0].Length;float[][] smoothNoise = new float[width][];for (int i = 0; i < width; i++){smoothNoise[i] = new float[height];}int samplePeriod = 1 << octave;float sampleFrequency = 1.0f / samplePeriod;for (int i = 0; i < width; i++){//calculate the horizontal sampling indicesint sample_i0 = (i / samplePeriod) * samplePeriod;int sample_i1 = (sample_i0 + samplePeriod) % width; //wrap aroundfloat horizontal_blend = (i - sample_i0) * sampleFrequency;for (int j = 0; j < height; j++){//calculate the vertical sampling indicesint sample_j0 = (j / samplePeriod) * samplePeriod;int sample_j1 = (sample_j0 + samplePeriod) % height; //wrap aroundfloat vertical_blend = (j - sample_j0) * sampleFrequency;//blend the top two cornersfloat top = Interpolate(baseNoise[sample_i0][sample_j0],baseNoise[sample_i1][sample_j0], horizontal_blend);//blend the bottom two cornersfloat bottom = Interpolate(baseNoise[sample_i0][sample_j1],baseNoise[sample_i1][sample_j1], horizontal_blend);//final blendsmoothNoise[i][j] = Interpolate(top, bottom, vertical_blend);}}return smoothNoise;}public float[][] GeneratePerlinNoise(float[][] baseNoise, int octaveCount){int width = baseNoise.Length;int height = baseNoise[0].Length;float[][][] smoothNoise = new float[octaveCount][][]; //an array of 2D arrays containingfloat persistance = 0.5f;//generate smooth noisefor (int i = 0; i <octaveCount; i++){smoothNoise[i] = GenerateSmoothNoise(baseNoise, i);}float[][] perlinNoise = new float[width][];for (int i = 0; i < width; i++){perlinNoise[i] = new float[height];}float amplitude = 1.0f;float totalAmplitude = 0.0f;//blend noise togetherfor (int octave = octaveCount - 1; octave >= 0; octave--){amplitude *= persistance;totalAmplitude += amplitude;for (int i = 0; i <width; i++){for (int j = 0; j < height; j++){perlinNoise[i][j] += smoothNoise[octave][i][j] * amplitude;}}}//normalisationfor (int i = 0; i <width; i++){for (int j = 0; j <height; j++){perlinNoise[i][j] /= totalAmplitude;}}return perlinNoise;}
int o=10;
private void mapPanel_Paint(object sender, PaintEventArgs e){Graphics g = e.Graphics;Bitmap bm = new Bitmap(500, 500);float[][] noises = GenerateWhiteNoise(500, 500,6527);float[][] smooth = GenerateSmoothNoise(noises, 5);float[][] perlins = GeneratePerlinNoise(noises, o);for (int i = 0; i < 500; i++){for (int j = 0; j < 500; j++){int co = (int)(perlins[i][j] * 256);bm.SetPixel(i, j, Color.FromArgb(co, co, co));}}Pen p = new Pen(Color.Black, 1);g.DrawImage(bm,new Point(0,0));}



可以看到 octaveCount为10的时候就有很好的烟雾效果,
不过我应用在生成随机地图的时候,取值为6可以获得最好的效果。

柏林噪声的应用

柏林噪声可以应用在图片中,获得类似烟雾,爆炸,
气体的效果,可以将两张图片用一定的比例合并在一张。
Color GetColor(Color gradientStart, Color gradientEnd, float t){float u = 1 - t;Color color = Color.FromArgb(255,(int)(gradientStart.R * u + gradientEnd.R * t),(int)(gradientStart.G * u + gradientEnd.G * t),(int)(gradientStart.B * u + gradientEnd.B * t));return color;}Color[][] MapGradient(Color gradientStart, Color gradientEnd, float[][] perlinNoise){int width = perlinNoise.Length;int height = perlinNoise[0].Length;Color[][] image = new Color[width][];for (int i = 0; i < width; i++){image[i] = new Color[height];}for (int i = 0; i <width; i++){for (int j = 0; j <height; j++){image[i][j] = GetColor(gradientStart, gradientEnd, perlinNoise[i][j]);}}return image;}
int o = 5;private void mapPanel_Paint(object sender, PaintEventArgs e){Graphics g = e.Graphics;Bitmap bm = new Bitmap(500, 500);float[][] noises = GenerateWhiteNoise(500, 500,6527);float[][] smooth = GenerateSmoothNoise(noises, 5);float[][] perlins = GeneratePerlinNoise(noises, o);Color[][] map = MapGradient( Color.Red,ColorTranslator.FromHtml("#7FFFD4"), perlins);for (int i = 0; i < 500; i++){for (int j = 0; j < 500; j++){int co = (int)(perlins[i][j] * 256);//bm.SetPixel(i, j, Color.FromArgb(co, co, co));bm.SetPixel(i, j, map[i][j]);}}Pen p = new Pen(Color.Black, 1);g.DrawImage(bm,new Point(0,0));}

随机地图的生成

查阅了一些资料,不同的游戏有不同的生成方式。
有的是使用维诺图加上柏林函数来生成世界,有的是生成高度图,再生成降水,再经过腐蚀而生成一个接近真实世界的地貌。
这里的实例是一个最简单的实现方法,使用方块格,根据柏林噪声获取该格的高度(0.1~1),再根据其高度来设定其地形。

public Color GetColorByFloat(float noise){noise = noise * 255;if (noise > 240) return Color.White;if (noise > 210) return ColorTranslator.FromHtml("#AAAAAA");if (noise > 180) return ColorTranslator.FromHtml("#C5C1AA");if (noise > 165) return ColorTranslator.FromHtml("#3CB371");if (noise > 130) return ColorTranslator.FromHtml("#228B22");if (noise > 70) return ColorTranslator.FromHtml("#71C671");return Color.SkyBlue;}
private void button2_Click(object sender, EventArgs e){Random r = new Random();float[][] whiteNoise = GenerateWhiteNoise(100, 100, r.Next());float[][] perlinNoise = GeneratePerlinNoise(whiteNoise, 5);for (int i = 0; i < 100; i++){for (int j = 0; j < 100; j++){SolidBrush sb = new SolidBrush(GetColorByFloat(perlinNoise[i][j]));pbG.FillRectangle(sb, i * width, j * height, width , height );}}pictureBox1.Invalidate();}

生成的效果勉强可以,但是如果添加更多的地形,加入更多的处理,相信可以做出更加好看,更加接近真实的地图。如果你有好的建议,请留言告诉我。

参考

噪声函数
柏林噪声的应用
开发者分享地形生成制作经验
地图生成器

游戏中随机地图的实现相关推荐

  1. 2D游戏中的地图创造

    尽管3D技术成熟的今天,2D游戏以独特的画面风格和趣味性仍有一席之地,开发者们是用什么方法了构建游戏中复杂丰富的2D游戏地图的呢,我大致将其分为以下三方面: 整体绘制 代表游戏:Ori and the ...

  2. 关于“搭桥”游戏生成随机地图的设计思路

    是很久以前写的一个小游戏.名字为:Bridge Puzzle Game. 是一款益智类的小游戏. 游戏链接:http://www.puzzle-bridges.com/ 游戏中最重要的一个功能是随机生 ...

  3. Fifa12游戏中随机退到桌面

    3DM 7G版本. Kick off模式, 踢不完全场,就会退出. 系统: XP  SP3系统, 萝卜家园 精简Ghost. 硬件配置: 速龙4000+ 3G DDR2 667 320G 希捷IDE ...

  4. wp7使用Cocos2d-X for XNA制作一个塔防类游戏 (二)在游戏中加入地图和怪物。(上)

    地图编辑器的使用 首先先来介绍一下使用地图编辑器tIDE Tile Map Editor来生成TMX文件.tIDE Tile Map Editor的下载地址  http://tide.codeplex ...

  5. 游戏中常用的寻路算法(6):地图表示

    在本系列文档大部分内容中,我都假设A*用于某种网格上,其中的"节点"是一个个网格的位置,"边"是从某个网格位置出发的各个方向.然而,A*可用于任意图形,不仅仅是 ...

  6. 《MFC游戏开发》笔记十 游戏中的碰撞检测进阶:地图类型障碍物判定

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9394465 作者:七十一雾央 新浪微博:http:// ...

  7. 从随机性内容看游戏中的AI应用

    事实上,如果把"AI"狭义地定义为"基于机器学习"而非"基于规则脚本"的AI,我们不难发现:虽然学术界的AI,如玩星际的AlphaStar. ...

  8. 23种设计模式在MMORPG游戏中的应用

    设计原则和设计模式是软件工程领域的两个重要概念,设计原则提供了编写高质量.可维护代码的指导思想,而设计模式则为特定问题提供了经过验证的解决方案.下面是7大设计原则和23种设计模式的总结: 7大设计原则 ...

  9. unity3d 2D游戏中摄像机投影类型

    我们盘点一下unity3d 2D游戏中必备的几个元素. 摄像机:无论是3D游戏还是unity3d 2D游戏摄像机都是非常重要的属性,移动摄像机即可更改屏幕中显示的内容,游戏地图的坐标永远都不会发生改变 ...

最新文章

  1. 《从0到1学习Flink》—— Flink Data transformation(转换)
  2. asp开发中存储过程应用全接触 _asp技巧
  3. 新疆大学OJ(ACM) 1099: 数列有序!
  4. shell如何解决mysql交互式_shell脚本与mysql交互方法汇总
  5. Nginx搭建服务器
  6. 如何向 Microsoft 管理控制台添加证书管理器
  7. axis2 json_带有Java和Axis2的JSON Web服务
  8. 递归算法1加到100_五种循环方法计算1加到100
  9. 常用的Oracle命令整理
  10. 基于情感词典的情感值分析
  11. 小程序快速入门:小程序的基本结构
  12. 令牌桶 java_令牌桶算法及实现(三)
  13. 使用短信接口进行通知
  14. 新版二开cp盲盒小纸条月老小程序源码【源码好优多】
  15. electron-builder打包后没生成latest.yml文件问题
  16. 广告行业中静态创意和动态创意区别
  17. ARP 地址解析协议 IP地址到MAC地址的转换过程
  18. 毕业生之瞳——《技术之瞳——叩开阿里之门之在线笔试》
  19. BCM53115交换芯片光口link状态的问题
  20. CU4C字符集检测和转换,C++版本

热门文章

  1. 软件工程 个人学习笔记(第二章)
  2. UE4_关于Roll,Yaw,Pitch,Rotator的理解
  3. 音频基础之麦克风、功放、扬声器
  4. 程序员如何管理自己的代码
  5. 心动不如行动, 盘点职场实干者的10大标志
  6. 哪一个国家耗巨资请熊猫去的_熊猫4.0:一个月过去了,复苏迹象
  7. 锁升级过程(偏向锁/轻量级锁/重量级锁)
  8. 银行数字化转型导师坚鹏:农商行数字化转型案例研究
  9. linux执行ps命令卡住了,linux ps命令的状态说明
  10. 移动开发APP的开发框架