วิธีที่ง่ายที่สุดในการสร้างภูมิประเทศที่ราบรื่นสำหรับเกม 2d คืออะไร?


23

วิธีที่ง่ายที่สุดในการสร้างภูมิประเทศที่ราบรื่นสำหรับเกม 2d เช่น "Moon Buggy" หรือ "Route 960" คืออะไร?

ฉันได้รับคำตอบที่ stackoverflow.com เกี่ยวกับการสร้างอาเรย์ของความสูงแบบสุ่มและเบลอในภายหลัง ใช่มันค่อนข้างโอเค แต่มันจะเป็นการดีกว่าถ้าคุณให้คะแนนและรับโค้งที่ราบรื่น

คำตอบ:


13

วิธีหนึ่งที่คุณสามารถทำได้ดังนี้:

  • สร้างจุดที่อยู่ตรงกลางของหน้าจอด้วยความสูงแบบสุ่ม ตอนนี้คุณมีสองส่วนโดยแต่ละด้านของจุดนี้
  • สำหรับทุกส่วนให้แบ่งเป็นสองจุดวางไว้ตรงกลางของส่วนนี้โดยมีความสูงแบบสุ่ม (เรียงลำดับ) ระหว่างสองประเทศ
  • ทำซ้ำ n ครั้ง

สิ่งที่เกิดขึ้นคือรายละเอียดในฉากนั้นดีขึ้นในแต่ละรอบ

วิธีที่คุณจัดการกับกรณีขอบเขตขึ้นอยู่กับคุณ: คุณสามารถสมมติคะแนนที่ (0, ความสูง / 2) และ (ความกว้างความสูง / 2)

หวังว่านี่จะช่วยได้!

แก้ไข: นี่คือภาพที่ฉันทำสำหรับภาพประกอบ:

terraingen

นี่เป็นความคิดเดียวกัน!


12

สมมติว่าคุณต้องการภูมิประเทศที่ราบรื่นจริง ๆ ฉันขอแนะนำให้ย้อนกลับไปจากคำตอบที่เป็นเสียงรบกวนและความเข้าใจว่ามาจากไหน สัญญาณ 'เสียง' เป็นหลักผลรวมของหลายอย่างมากมายไซน์ของช่วงกว้างของคลื่นสุ่มกับ 'เฉลี่ย' กว้างความถี่ที่ได้รับที่ได้รับจากการทำงานของความถี่ฉ คุณจะได้คำจำกัดความ 'เสียง' ที่พบบ่อยที่สุดด้วยวิธีนี้ ยกตัวอย่างเช่นการเคลื่อนไหวแบบบราวเนียนมี1 / f ^ 2การตอบสนองความถี่ (นั่นคือแอมพลิจูดเฉลี่ยที่ความถี่ที่กำหนดนั้นแปรผกผันกับกำลังสองของความถี่): นี่หมายความว่าจุดที่อยู่ใกล้เคียงมีความสัมพันธ์ที่ยุติธรรมกันเล็กน้อยเนื่องจากส่วนประกอบความถี่สูงของสัญญาณมีค่ามาก หดหู่ ในทางตรงกันข้ามเสียงแฟร็กทัลคลาสสิก (จุดกึ่งกลาง, เสียงเพอร์ลินและอื่น ๆ ) มีการตอบสนองความถี่1 / f มีความแปรปรวนระหว่างจุดใกล้เคียงมากขึ้น แต่ก็ยังมีความสัมพันธ์ค่อนข้างน้อย เสียงรบกวนสีขาวจะมีการตอบสนองความถี่คงที่ - ไม่มีความสัมพันธ์ระหว่างจุดใด ๆ เลย

คุณทำอะไรที่ดี ทีนี้คุณสามารถรับสัญญาณที่ราบรื่นซึ่งยังคงมีสัญญาณรบกวนอยู่บ้างโดยการสรุปไซนัสเพียงเล็กน้อย แต่ให้แน่ใจว่าพวกมันมีแอมพลิจูดที่เหมาะสมตามความถี่ที่กำหนด คุณต้องการให้ความถี่เป็น 'สุ่ม' เพื่อไม่ให้สองคนมีความถี่ทั่วไป (ไม่เช่นนั้นคุณจะได้รับองค์ประกอบเป็นระยะตามรูปร่างโดยรวมของเนินเขา) ดังนั้นฉันขอแนะนำบางอย่างเช่นขั้นตอนต่อไปนี้ (สมบูรณ์ ด้วยตัวอย่างการทำงาน):

  1. เลือก 4 (จริง) ตัวเลขโดยการสุ่มในช่วง [1..10] - สิ่งเหล่านี้จะเป็นความถี่ของคลื่นไซน์ของคุณ ฉัน 'ทอยลูกเต๋า' ที่ random.org และได้รับ: f 0 = 1.75, f 1 = 2.96, f 2 = 6.23, และf 3 = 8.07 ไม่มีอะไรมหัศจรรย์เกี่ยวกับหมายเลข 4 (คุณสามารถใช้มากขึ้น แต่การใช้น้อยลงจะเริ่มทำให้คลื่นไซน์แต่ละตัวชัดเจนมากขึ้น) หรือช่วงที่ 1 ถึง 10 ที่นี่ (เป็นเพียงวิธีการทำให้แน่ใจว่าสูงสุดและต่ำสุดของคุณ ความถี่ไม่ได้เกินไปห่างไกลกัน) มันอาจสมเหตุสมผลที่จะเลือกความถี่หนึ่งในช่วง [1..2] และส่วนที่เหลือในช่วง [2..10] เพียงเพื่อให้คุณมีไซน์อยด์ที่โดดเด่น
  2. สำหรับแต่ละเหล่านี้สี่ (หรือ แต่อีกหลายคน) ความถี่ฉันให้เลือกกว้างฉันที่ไหนสักแห่งในช่วงระหว่าง-C / f ฉันและC / f ฉันสำหรับบางคงC ค่าที่คุณเลือกที่นี่ควบคุมคลื่นโดยรวมของคุณ - เพื่อความสะดวกฉันเลือกC = 1 จากนั้นฉันต้องการตัวเลขสุ่มในช่วง [-1 / 1.75 (= -0.571) .. 1 / 1.75 (= 0.571) ] และใกล้เคียงกันในช่วง [-0.338 .. 0.338], [-0.161 .. 0.161] และ [-0.124 .. 0.124] กลิ้งลูกเต๋าสี่ครั้งอีกครั้งผมได้0 = -0.143, 1 = -0.180, 2 = -0.012 และa 3 = 0.088 (โปรดทราบว่านี่อาจไม่ใช่วิธีที่ดีที่สุดในการทำขั้นตอนนี้ - เนื่องจากค่าสูงสุดที่เป็นไปได้ของฟังก์ชันคือผลรวมของแอมพลิจูด abs ( a 0 ) + abs ( a 1 ) + abs ( a 2 ) + abs ( 3 ) ก็อาจทำให้รู้สึกมากขึ้นที่จะแบ่งแต่ละสี่ของคุณฉันค่าด้วยผลรวมนี้เมื่อคุณได้สร้างพวกเขาแล้วคูณหนึ่งโดยแต่ละCเพื่อให้คุณสามารถตรวจสอบได้อย่างแม่นยำสูงสุดฟังก์ชั่นสามารถที่จะบรรลุเป็นC .)
  3. เลือกสี่ 'ชดเชย' o ฉันในแต่ละช่วง [0..2π] (0..6.28) - เหล่านี้จะปรับแต่งจุดเริ่มต้นของคลื่นของคุณเพื่อให้พวกเขาไม่ได้ทั้งหมดเริ่มต้นที่ 0 ผมได้o 0 = 1.73, o 1 = 4.98, o 2 = 3.17, และo 3 = 4.63
  4. 'เขียน' ฟังก์ชันf (x) = a 0 sin ( f 0 (kx + o 0 ) ) + a 1 sin ( f 0 (kx + o 1 ) ) + a 2 sin ( f 0 (kx + o 0 ) ) + a 3 sin ( f 0 (kx + o 0 ) ) - ที่นี่kคือค่าคงที่อีกค่าหนึ่งที่ควบคุม 'ยืด' แนวนอนของฟังก์ชันของคุณ คุณจะต้องคิดออกว่านี่คืออะไรสำหรับการสมัครของคุณ เพื่อความสะดวกฉันเพิ่งเลือกk= 1 และฟังก์ชั่นโดยรวมของฉันคือf (x) = -0.143 บาป (1.75 ( x + 1.73)) - 0.180 บาป (2.96 ( x +4.98)) - 0.012 บาป (6.23 ( x +3.17)) + 0.088 บาป (8.07 ( x +4.63))

นี่คือผลลัพธ์ของการเรียกใช้ตัวอย่างของฉันดังที่พล็อตใน Wolfram Alpha - โปรดทราบว่ามันจะแก้ไขขนาดของกราฟเพื่อวัตถุประสงค์ในการแสดงผล แต่คุณควรควบคุมการยืดแนวนอนและแนวตั้งของผลลัพธ์ผ่านค่าคงที่ที่ฉันกล่าวไว้ข้างต้น :

ไซนัสอยด์สุ่มแบบง่าย


10

ขั้นตอนวิธีการจุดกึ่งกลางกระจัดสามารถสร้างภูมิประเทศที่สวยงาม 2d

ตัวอย่างภูมิประเทศ

มีความแตกต่างกันเล็กน้อยระหว่างการกำจัดจุดกึ่งกลางและสิ่งที่ @tykel แนะนำ อัลกอริธึมของ Tykel แบ่งขอบฟ้าและเลือกความสูงใหม่ สิ่งนี้จะสร้างภูมิประเทศที่มีระยะห่างสูงสุดเท่ากัน มนุษย์เป็นคนที่ยอดเยี่ยมในการเลือกกฎเกณฑ์ดังนั้นภูมิประเทศที่สร้างจะดูเหมือนสร้างขึ้นไม่ใช่ธรรมชาติ

พลังของ Midpoint นั้นมาจากการเลือกจุดกึ่งกลางจากนั้นแทนที่ตามปกติของเส้นนั้น นี่เป็นสาเหตุให้ยอดเขาแตกต่างกันไปขึ้น ๆ ลง ๆ ตลอดจนด้านข้าง ภูมิประเทศที่เป็นผลลัพธ์นั้นเป็นเศษส่วนและมนุษย์รับรู้เศษส่วนเป็นธรรมชาติ

การกำจัดความสูงแบบสุ่มอาจส่งผลให้เกิดภูมิประเทศที่สืบเชื้อสายมาหากคุณโยนพารามิเตอร์เพิ่มเติมอีกสองสามรายการ (การกระจัดในแนวนอนความชันสูงสุด ฯลฯ ) นี่เป็นการเน้นจุดแข็งอีกประการหนึ่งของ MPD มันง่ายมากในการปรับแต่ง สองพารามิเตอร์ความผิดพลาดและระดับของรายละเอียด


7

คุณสามารถใช้ฟังก์ชั่นเสียงรบกวนเพื่อสร้างความสูงแบบสุ่ม ที่ง่ายที่สุดของพวกเขาคือเสียงค่าซึ่งทำงานเหมือนกับคำอธิบายของคุณ: คุณสร้างความสูงจำนวนเต็มแบบสุ่มบางส่วนแล้วแทรกความสูงระหว่างพวกเขา วิธีการแก้ไขที่ใช้บ่อยที่สุดคือการแมป S-curve ลูกบาศก์:

สมมติว่าคุณมีความสูงh0ที่จุดx0และความสูงที่จุดh1 x1จากนั้นเพื่อให้ได้ความสูง ณ จุดใดก็ได้x( x0<=x<=x1) คุณใช้

t = (x-x0)/(x1-x0); // map to [0,1] range
t = t*t*(3 - 2*t); // map to cubic S-shaped curve
h = h0+t*h1;

ความสูงที่ได้มาในลักษณะนี้จะราบรื่นสุ่ม แต่ไม่น่าสนใจจริงๆ ที่จะทำให้ภูมิประเทศของคุณดีขึ้นคุณสามารถใช้เสียงเศษส่วน มันใช้งานได้เช่นนี้: สมมติว่าคุณได้สร้างฟังก์ชั่นh(x)ที่ให้ความสูงที่พิกัดที่กำหนด ฟังก์ชั่นนี้มีความถี่พิจารณาจากความถี่ของความสูงของ interger ดั้งเดิม ในการสร้างเศษส่วนจากนั้นคุณรวมฟังก์ชั่นเข้าด้วยกันกับความถี่หลายความถี่:

fbm(x)=h(x) + 0.5*h(2*x) + 0.25*h(4*x) + 0.125*h(8*x);

ในตัวอย่างนี้ฉันรวมสี่ความถี่ - ดั้งเดิม, คู่, 4 ครั้งและ 8 เท่าเดิมด้วยความถี่ที่สูงขึ้นซึ่งให้น้ำหนักน้อยลง ในทางทฤษฎีเศษส่วนไปตลอดทางจนถึงอนันต์ แต่ในทางปฏิบัติมีข้อกำหนดเพียงไม่กี่ข้อเท่านั้น fbmในสูตรหมายถึงการเคลื่อนที่แบบบราวเศษส่วน - นี้เป็นชื่อของฟังก์ชั่นนี้

นี่เป็นเทคนิคที่ทรงพลัง คุณสามารถเล่นกับตัวคูณความถี่ด้วยน้ำหนักของความถี่ที่แตกต่างกันหรือเพิ่มฟังก์ชั่นบางอย่างเพื่อบิดเบือนเสียง ตัวอย่างเช่นหากต้องการความรู้สึก "ยับ" มากขึ้นh(x)สามารถเปลี่ยนเป็น1-abs(h(x))(สมมติว่า-1<=h(x)<=1)

อย่างไรก็ตามในขณะที่ทั้งหมดนี้เป็นสิ่งที่ดีเทคนิคนี้มีข้อ จำกัด ร้ายแรง ด้วยวิธีการตาม "ความสูง" คุณจะไม่มีทาง "ภูมิประเทศยื่น" และฉันคิดว่าพวกเขาจะเป็นคุณสมบัติที่ดีมากที่มีในเกมคล้าย "Moon Buggy"

การเพิ่มระยะยื่นออกที่ดีเป็นงานที่ยาก สิ่งหนึ่งที่ฉันนึกถึง - คุณสามารถเริ่มต้นด้วย "ความสูง" เศษส่วนและ "tessellate" ลงในชุดของเส้นโค้งหรือเส้นโค้ง bezier จากนั้นแนวภูมิประเทศจะถูกกำหนดโดย "ประเด็นสำคัญ" หลายประการ ใช้ความกระวนกระวายใจกับประเด็นสำคัญเหล่านี้ - สิ่งนี้จะส่งผลให้เกิดการเสียรูปแบบสุ่มของภูมิประเทศซึ่งอาจเป็นรูปร่างที่น่าสนใจ อย่างไรก็ตามการตัดกันด้วยตนเองของภูมิประเทศอาจกลายเป็นปัญหาด้วยวิธีนี้โดยเฉพาะอย่างยิ่งเมื่อมีปริมาณกระวนกระวายใจสูง


4

มีวิธีการยอดนิยมสองวิธีในการสร้างแผนที่ความสูงของภูมิประเทศ

บางคำตอบที่ให้ไว้ที่นี่มีพื้นฐานมาจากอัลกอริทึม Diamond-square แล้ว แต่การรู้ชื่อทำให้ง่ายต่อการค้นหาข้อมูลเพิ่มเติม เสียงเพอร์ลินนั้นมีประโยชน์อื่น ๆ เช่นกันดังนั้นจึงเป็นการดีที่จะตรวจสอบ


OP กำลังพูดถึงภูมิประเทศ 2 มิติสไตล์มาริโอ แต่ยังคงเป็นลิงก์ที่ดี
tenpn

1

ความคิดของฉันคือการสร้างฟังก์ชั่นเสียงรบกวนที่ราบรื่น ก่อนอื่นด้วยเมธอด intNoise (int) ซึ่งส่งกลับค่า "สุ่ม" int แต่จะขึ้นอยู่กับอินพุต หากคุณใช้อินพุตเดียวกันสองครั้งผลลัพธ์จะเหมือนกัน

จากนั้นใช้วิธีการปรับให้เรียบเพื่อสร้าง floatNoise (ลอย) ซึ่งใช้จำนวนเต็มสองตัวรอบอินพุตเพื่อสร้างค่าสุ่ม

จากนั้นใช้ตำแหน่ง X เป็นอินพุตและ Y เป็นเอาต์พุต ผลลัพธ์จะเป็นเส้นโค้งเรียบ แต่มีความสูงแบบสุ่ม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.