Libgdx游戏开发(3)——通过柏林噪音算法地图随机地形

news/2024/9/29 15:30:04

原文: Libgdx游戏开发(3)——通过柏林噪音算法地图随机地形-Stars-One的杂货小窝

在B站刷到了随机地图生成的视频,随手学习下并做下记录

注: 本篇使用javafx应用作演示,算是了解这个算法的使用,后续会再出篇libgdx生成地图的示例

说明

抛开算法实现,首先认知柏林噪音算法

一般我们想要随机数,会指定个范围,如0.0-1.0之间任意小数,而柏林算法的结果范围就是[-1,1]

柏林算法已经实现了对应一维到四维的算法,本文以二维来进行讲解,实现我自己的一个游戏随机地图效果,我以五种颜色区分不同地形,通过javafx应用展示出一个600*600的游戏地图地形,如下图所示

代码实现

需求如下:

使用一个二维数组来进行存储当前地图,每个数值里存放一个int类型,用来标明地图的地形,类型有0-4(即int数值可取[0,4]范围)

我们如果使用单纯的随机算法,地形可能就会很乱,所以我们采用柏林噪音算法来得到我们的对应地形,使其有个平滑的过渡效果,方法如下:

//这里我使用的是java实现版本,FastNoiseLite这个类可见下文列出的参考链接val noise = FastNoiseLite()
noise.SetNoiseType(FastNoiseLite.NoiseType.OpenSimplex2)
noise.SetSeed(1000)
val result = noise.GetNoise(1f, 2f)

柏林算法最初是由Ken Perlin,算法的命名由此得来,然后后续发展又继续了优化,所以有以下几种类型,对应着 FastNoiseLite.NoiseType这个枚举类型,具体介绍如下:

  • OpenSimplex2:OpenSimplex2 是关于 OpenSimplex 噪声的一种改进版本,提供更好的性能和质量。它通常用于生成连续、无缝的噪声,适用于图形学和自然模拟等领域。
  • OpenSimplex2S:OpenSimplex2S 是 OpenSimplex2 的另一个改进版本,其主要目标是在保持质量的同时提高性能。它通常比 OpenSimplex2 更快速、效率更高,适合需要大量计算的场景。
  • Cellular:Cellular Noise 是一种基于 Voronoi 图的噪声算法,产生类似于细胞结构的噪声效果。它常用于生成有规律排列的点、线或区域,以及模拟生物组织和自然纹理。
  • Perlin:Perlin Noise 是由 Ken Perlin 发明的一种经典噪声算法,用于生成自然风格的连续噪声图案。它被广泛应用于图形学、游戏开发和计算机模拟等领域。
  • ValueCubic:ValueCubic Noise 是一种基于立方插值的噪声算法,通常用于生成平滑的、无缝的噪声效果。它提供了更细致的控制和调整选项,适合需要更多定制化的噪声生成需求。
  • Value:Value Noise 是一种简单的噪声算法,通过对噪声值进行插值来生成连续的、均匀分布的噪声效果。虽然相对简单,但它在一些场景中也有其应用,如生成地形、纹理等。

柏林算法最终生成的结果数值与输入的x,y,还有seed(随机种子)有关,如果三者固定相同,则得到的数值是相同的;

一般来说我们拿一个随机数来作为随机种子(如使用Random.nextInt(1000)方法,获取1000以内的一个随机数)

但这样还不是最优的,我们还可以使用正弦叠加的方法继续优化得到的数值,使其可以更加平滑

数学函数: result =noise(x,y) + (1/2) * noise(2x,2y) + (1/4) * noise(4x,4y) + (1/8) * noise(8x,8y)

这里我只叠加到8,当然还可以继续叠加下去,平滑过渡的效果就越好

转为代码:

val noise = FastNoiseLite()
noise.SetNoiseType(FastNoiseLite.NoiseType.OpenSimplex2)
noise.SetSeed(1000)
val result =  noise.GetNoise(1f , 2f  ) +(1/2 )* noise.GetNoise(1f *2, 2f * 2)+ (1/4 )* noise.GetNoise(1f *4, 2f * 4)+(1/8 )* noise.GetNoise(1f *8, 2f * 8)

对上面方法封装下,得到下面代码:

object MyUtil{val noise by lazy {val noise = FastNoiseLite()noise.SetNoiseType(FastNoiseLite.NoiseType.OpenSimplex2)//1000以内随机,可以自行更改noise.SetSeed(Random.nextInt(1000))noise}//size默认为4,表明进行3次叠加,如上面示例fun noiseData(x: Float, y: Float, size: Int = 4): Double {val result = (0 until size).sumOf {//位与操作,相当于的2的n次方// 1 shr 0 = 1// 1 shr 1 = 2val num = 1 shl it1.0 * (1 / num) * noise.GetNoise(x * num, y * num)}return result}
}

这里需要注意的是,我们封装得保证我们的每次调用函数的时候FastNoiseLite用的是同个对象,否则就会出现其他效果,和我们预期不符,所以上面封装我使用了单例模式

使用:

fun main(){//4*4的二维数据val size = 4 val re = Array(size) { IntArray(size) }(0 until size).forEach {x->var buffer = StringBuffer()(0 until size).forEach {y->val data = noiseData(x.toFloat(),y.toFloat())//todo 这里还需要将data转为0-4的int数值并存放在二维数组中buffer.append(data.toString()+",")}println(buffer.toString())buffer=StringBuffer()}
}

上面只是得到的对应的噪音数据,而我们按照范围,将其转为对应的0-4数值,代码如下:

fun getType(result: Double): Int {return when {result >= -1 && result < -0.6 -> 0result >= -0.6 && result < -0.2 -> 1else -> 3}
}

result的数据范围在[-1,1]之间,所以可以根据自己的需求,符合对应范围,自行给数值即可,上面代码只是一个简单的示例,你可以随意划分;

于是按照我的需求,我自行封装成下面的方法(可能有些难以理解,大概解释就是划分为n等分,每个区间有个下标,然后数值符合对应区间的,则返回对应区间下标)

fun getType(result: Double): Int {//划分为5等分val size = 5val temp = 2.0 / sizefor (i in (0 until size)) {val it = ival start = -1.0 + (it * temp)val end = -1.0 + (it + 1) * tempif (result >= start && result < end) {return it}}return size-1
}

最终这里我是使用一个简单的javafx应用来展示地图数据(每个地形则是不同颜色)

import javafx.application.Application
import javafx.scene.Scene
import javafx.scene.layout.HBox
import javafx.scene.layout.VBox
import javafx.stage.Stage
import site.starsone.demo.MyUtil.noiseData
import kotlin.random.Randomclass MyApp : Application() {override fun start(primaryStage: Stage?) {val root = VBox().apply {prefWidth = 600.0prefHeight = 600.0}val scene = Scene(root, 600.0, 600.0)val array = getData()array.forEach {val hbox = HBox()it.forEach { resultType ->val node = VBox().apply {prefWidth = 1.0prefHeight = 1.0style = "-fx-background-color: ${getColor(resultType)};"}hbox.children.add(node)}root.children.add(hbox)}primaryStage!!.title = "Hello World Example"primaryStage!!.scene = sceneprimaryStage!!.show()}val list = listOf("#FF0000", // Red"#00FF00", // Green"#0000FF", // Blue"#FFA500", // Orange"#800080"  // Purple)fun getColor(type: Int): String {return list[type]}fun getData(): Array<IntArray> {val size = 600val re = Array(size) { IntArray(size) }(0 until size).forEach { x ->(0 until size).forEach { y ->val data = noiseData(x.toFloat(), y.toFloat())re[x][y] = getType(data)}}return re}fun getType(result: Double): Int {val size = 5val temp = 2.0 / sizefor (i in (0 until size)) {val it = ival start = -1.0 + (it * temp)val end = -1.0 + (it + 1) * tempif (result >= start && result < end) {return it}}return size-1}}fun main() {Application.launch(MyApp::class.java, "")
}

生成的截图如下所示:

参考

  • 《地图随机生成》如何实现属于自己的开放世界_哔哩哔哩_bilibili
  • 柏林噪声:程序化生成算法 - 掘金
  • 算法工具类代码实现 - Auburn/FastNoiseLite: Fast Portable Noise Library - C# C++ C Java HLSL GLSL JavaScript Rust Go

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/45402.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis 关于查询语句上配置的详细内容

1. MyBatis 关于查询语句上配置的详细内容 @目录1. MyBatis 关于查询语句上配置的详细内容2. 准备工作3. SQL查询结果,返回为POJO实体类型4. SQL查询结果,返回为List<POJO> 集合类型5. SQL查询结果,返回为Map 集合6. SQL查询结果,返回为List<Map>集合7. SQL查询…

PC端抓包-.exe程序

一、工具 Proxifier:https://files.cnblogs.com/files/blogs/679179/Proxifier-Lit.zip?t=1717655967&download=true+ Charles:https://www.charlesproxy.com二、配置 1、Charles配置 ➭ 勾选Windows Proxy ➭ 点击Proxy Settings,定义一个代理端口(默认8888) 2、Pr…

C# ComboBox 使用示例

效果图 form1.Designer.csprivate System.Windows.Forms.ComboBox cmbInstallResult;// // cmbInstallResult // this.cmbInstallResult.Cursor = System.Windows.Forms.Cursors.Hand; this.cmbInstallResult.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.cmbInst…

开源可视化表单可以用在哪些行业中?

针对客户的问题,我们今天一起来了解开源可视化表单可以应用的领域以及它都有哪些优势特点吧。很多客户朋友会询问我们,什么样的行业可以使用低代码技术平台及开源可视化表单?其实,随着社会的进步和发展,很多中小型企业都希望通过低代码技术平台能够让企业实现提质增效的目…

Office 2021 mac/win版:智慧升级,办公新风尚

Office 2021是微软公司推出的一款高效、智能且功能丰富的办公软件套件。它集成了Word、Excel、PowerPoint等多个经典应用程序,旨在为用户提供更出色的办公体验。 →→↓↓载Office 2021mac/win Office 2021在继承了前代版本优点的基础上,进行了大量的优化和创新。首先,在界…

龙哥量化:我工作用到的网站,截图分享给各位朋友

如果您需要代写公式, 请联系我。 龙哥QQ:591438821 龙哥微信:Long622889 浏览器收藏的网址, 基本都是官网, 有空逛逛吆

2.4G低功耗无线收发SOC芯片

Si24R03 是一款高度集成的低功耗SOC芯片, 其集成了基于RISC-V核的低功耗MCU和工作在2.4GHz ISM频段的无线收发器模块Si24R03 这款 SOC 芯片确实展现了高度集成和低功耗的特性,同时其丰富的外设和内核性能也为其增添了不少亮点。以下是对这款芯片的一些详细分析: 1. **高度集…

【mongoDB】ubuntu安装mongosh

一、场景测试过程需要增删改查查询MongoDB数据,并对比结果二、官网https://www.mongodb.com/try/download/shell选择对应的系统和版本,下载即可 三、安装sudo dpkg -i mongodb-mongosh_2.2.6_amd64.deb检查安装结果$ mongosh --help$ mongosh [options] [db address] [file …