Libgdx游戲開發系列教程(3)——通過柏林噪音算法地圖隨機地形

在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, "")
}

生成的截圖如下所示:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896923.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896923.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896923.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LeetCode熱題100JS(20/100)第四天|?41. 缺失的第一個正數?|?73. 矩陣置零?|?54. 螺旋矩陣?|?48. 旋轉圖像?

41. 缺失的第一個正數 題目鏈接&#xff1a;41. 缺失的第一個正數 難度&#xff1a;困難 刷題狀態&#xff1a;1刷 新知識&#xff1a; 解題過程 思考 示例 1&#xff1a; 輸入&#xff1a;nums [1,2,0] 輸出&#xff1a;3 解釋&#xff1a;范圍 [1,2] 中的數字都在數組中…

e2studio開發RA2E1(17)---- ADC掃描多通道采樣

e2studio開發RA2E1.17-- ADC掃描多通道采樣 概述視頻教學樣品申請硬件準備參考程序源碼下載ADC屬性配置回調函數主程序演示結果 概述 在嵌入式系統中&#xff0c;ADC&#xff08;模數轉換器&#xff09;是一個非常重要的組件&#xff0c;它將模擬信號轉換為數字信號。為了提高…

FPGA標準庫-Open Logic

在現代技術發展的浪潮中&#xff0c;開源項目已經成為了推動技術創新和發展的核心力量。無論是人工智能、區塊鏈、云計算&#xff0c;還是傳統的嵌入式開發、操作系統&#xff0c;開源項目都在其中扮演著至關重要的角色。它們不僅促進了技術的快速迭代&#xff0c;也為全球開發…

FineReport 操作注意

1.父單元格重復的時候&#xff0c;如何取消合并 效果如下&#xff1a; 只需要在單元格中&#xff0c;將數據設置為【列表】即可。 2.待定

開源之夏經驗分享|Koupleless 社區黃興抗:在開源中培養工程思維

開源之夏經驗分享&#xff5c;Koupleless 社區黃興抗&#xff1a;在開源中培養工程思維 文|黃興抗 電子信息工程專業 Koupleless 社區貢獻者 就讀于南昌師范學院&#xff0c;電子信息工程專業的大三學生。 本文 2634 字&#xff0c;預計閱讀 7? 分鐘? 今天 SOFAStack 邀…

Ollama存在安全風險的情況通報及解決方案

據清華大學網絡空間測繪聯合研究中心分析&#xff0c;開源跨平臺大模型工具Ollama默認配置存在未授權訪問與模型竊取等安全隱患。鑒于目前DeepSeek等大模型的研究部署和應用非常廣泛&#xff0c;多數用戶使用Ollama私有化部署且未修改默認配置&#xff0c;存在數據泄露、算力盜…

線代[9]|線性代數主要內容及其發展簡史(任廣千《線性代數的幾何意義》的附錄1)

文章目錄 向量行列式矩陣線性方程組二次型 向量 向量又稱為矢量&#xff0c;最初應用與物理學。很多物理量如力、速度、位移以及電場強度、磁感應強度等等都是向量。大約公元前350年前&#xff0c;古希臘著名學者亞里士多德就知道了力可以表示成向量&#xff0c;兩個力的組合作…

H20半精度推理報錯:Floating point exception (core dumped)

Nvidia H20 顯卡在執行bf16&#xff0c;f16推理時程序異常中斷 時間是 2025年3月4日 課題組新到的8卡H20服務器在使用過程中&#xff0c;torch加載模型進行bf16的推理時&#xff0c;出現Floating point exception (core dumped)錯誤 當時一頭霧水&#xff0c;后來苦苦尋找&…

服務是否設置為開機自啟動

在 Linux 系統中&#xff0c;可以通過以下幾種方法檢查服務是否設置為開機自啟動&#xff1a; 方法 1&#xff1a;使用 systemctl 命令&#xff08;適用于 systemd 系統&#xff09; systemctl 是 systemd 系統的命令行工具&#xff0c;用于管理系統服務。以下是具體步驟&…

QT——基于 QListWidget 和 QStackedWidget 的頁面切換

Qt 練習題&#xff1a;基于 QListWidget 和 QStackedWidget 的頁面切換 Qt 練習題&#xff1a;基于 QListWidget 和 QStackedWidget 的頁面切換 題目描述&#xff1a; 請使用 Qt 設計一個窗口&#xff0c;其中包含一個 QListWidget 和一個 QStackedWidget。要求實現以下功能&a…

DeepSeek 助力 Vue3 開發:打造絲滑的表格(Table)示例2: 分頁和排序

前言:哈嘍,大家好,今天給大家分享一篇文章!并提供具體代碼幫助大家深入理解,徹底掌握!創作不易,如果能幫助到大家或者給大家一些靈感和啟發,歡迎收藏+關注哦 ?? 目錄 DeepSeek 助力 Vue3 開發:打造絲滑的表格(Table)示例2: 分頁和排序??前言??頁面效果??指令…

C語言文件操作學習筆記:從基礎到實踐

在C語言的知識體系中&#xff0c;文件操作是極為關鍵的一環&#xff0c;它賦予了程序存儲和讀取外部數據的能力&#xff0c;對于開發各類實用程序至關重要。近期&#xff0c;借助課程的學習&#xff0c;我對C語言文件操作進行了系統且深入的學習&#xff0c;下面將我的學習心得…

VLM-E2E:通過多模態駕駛員注意融合增強端到端自動駕駛

25年2月來自香港科大廣州分校、理想汽車和廈門大學的論文“VLM-E2E: Enhancing End-to-End Autonomous Driving with Multimodal Driver Attention Fusion”。 人類駕駛員能夠利用豐富的注意語義&#xff0c;熟練地應對復雜場景&#xff0c;但當前的自動駕駛系統難以復制這種能…

第十天-字符串:編程世界的文本基石

在編程的廣闊領域中&#xff0c;字符串是極為重要的數據類型&#xff0c;它就像一座橋梁&#xff0c;連接著人類的自然語言和計算機能夠理解與處理的數字信息。下面&#xff0c;讓我們深入探索字符串的世界。 一、字符串簡介 字符串是由零個或多個字符組成的有序序列&#xff…

《基于HarmonyOS NEXT API 12+,搭建新聞創作智能寫作引擎》

在信息爆炸的時代&#xff0c;新聞行業對于內容生產的效率和質量有著極高的要求。AI技術的發展為新聞創作帶來了新的變革契機&#xff0c;借助AI智能寫作助手&#xff0c;新聞工作者可以快速生成新聞稿件的初稿&#xff0c;大大提高創作效率。本文將基于HarmonyOS NEXT API 12及…

基于STM32的環境監測系統(自制藍牙APP)

目錄 項目概述 實物圖 演示視頻 概述 硬件模塊 原理圖以及PCB 0.96寸OLED屏幕&#xff08;SSD1306&#xff09; CubeMX配置 初始化代碼 MQ-2煙霧傳感器 CubeMX配置 初始化代碼 DHT11溫濕度模塊 驅動代碼 HC-05藍牙模塊 CubeMX配置 ?編輯 空閑中斷回調函數 有…

linux離線安裝ollama并部署deepseek-r1模型 指南

這篇文章主要分為兩部分&#xff1a; (1)離線環境下如何部署Ollama&#xff1b; (2)在離線環境下如何配置大模型&#xff0c;其中這一步又分為&#xff1a; ?1)部署完整的deepseek大模型&#xff0c;如&#xff1a;deepseek-r1:32B; ?2)部署蒸餾版模型&#xff0c;如&#xf…

坐標變換介紹與機器人九點標定的原理

【備注】本文的C#代碼在下面鏈接中可以下載:Opencv的C#九點標定代碼資源-CSDN文庫 https://download.csdn.net/download/qq_34047402/90452336 一、坐標變換的介紹 1.繞原點旋轉的坐標變換 一個點(x,y)繞原點旋轉u度,其旋轉后的坐標(x1,y1)如何計算? 2.繞任意點的坐標變…

大語言模型 智能助手——既能生成自然語言回復,又能在必要時調用外部工具獲取實時數據

示例代碼&#xff1a; import json from langgraph.graph import Graph, END,StateGraph from langchain_core.utils.function_calling import convert_to_openai_function from langchain_community.tools.openweathermap import OpenWeatherMapQueryRun from langchain_core…

FPGA學習(一)——DE2-115開發板編程入級

FPGA學習&#xff08;一&#xff09;——DE2-115開發板編程入級 一、實驗目的 通過 1 位全加器的詳細設計&#xff0c;深入掌握原理圖輸入以及 Verilog 的兩種設計方法&#xff0c;熟悉 Quartus II 13.0 軟件的使用流程&#xff0c;以及在 Intel DE2-115 開發板上的硬件測試過…