วิธีสร้างเครือข่ายถนนในเมือง


16

ฉันต้องการสร้างตัวสร้างเมืองสำหรับเกม แต่ฉันกำลังประสบปัญหาในช่วงเริ่มต้นของรุ่น: ระบบถนน

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

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

ฉันไม่ได้ตัดสินใจขนาดหรือการจัดการที่แน่นอนสำหรับเมืองของฉันดังนั้นหากคุณมีวิธีแก้ปัญหาที่จะทำงานกับเมืองที่มีรูปแบบที่แม่นยำเท่านั้น (สี่เหลี่ยมจัตุรัสวงกลมสี่เหลี่ยม ฯลฯ ) ฉันจะรับมัน


2
คุณอาจต้องการดูเครื่องมือสร้างเมืองตามขั้นตอนโดยซอฟต์แวร์ Introversion ที่พวกเขาสร้างขึ้นเพื่อการโค่นล้ม ในขณะที่ตัวเกมถูกยกเลิกมีภาพมากมายรอบตัวจากตัวสร้าง
ฟิลิปป์

คุณมีตัวอย่างของสิ่งที่คุณต้องการ (ตัวอย่างชีวิตจริงจากช่วงเวลาเป้าหมายของคุณตัวอย่างจากเกมอื่นแบบร่าง ฯลฯ ) หรือไม่ มีตัวเลือกมากมายระหว่าง 'ไม่ใช่กริด' และ 'ไม่ใช่เขาวงกตที่สมบูรณ์'
Pikalek

@Pikalek ฉันไม่ได้ให้ความแม่นยำมากขึ้นเพราะฉันไม่มี ฉันไม่ได้มองหาบางอย่างที่เฉพาะเจาะจงตัวอย่างของการสร้างที่ไม่สร้างเขาวงกตหรือแผนกริดสามารถทำให้ฉันพึงพอใจ
Aracthor

คำตอบ:


21

สถานที่ที่ดีที่จะเริ่มต้นกับการสร้างเมืองที่เป็นขั้นตอนและตำบลMüllerของการสร้างแบบจำลองกระบวนการของเมือง กระดาษของพวกเขานำเสนอระบบLที่กฎเกี่ยวกับความหนาแน่นของประชากรและรูปแบบถนน (ตารางสี่เหลี่ยมรัศมีและการเปลี่ยนแปลงระดับความสูงน้อยที่สุด) จะถูกรวมเข้าด้วยกันจากนั้นจับจ้องไปที่เพื่อรองรับข้อ จำกัด ในท้องถิ่น ขณะที่ผลของระบบนี้เป็นที่น่าประทับใจจะได้รับการวิพากษ์วิจารณ์ว่าเป็นความซับซ้อนโดยไม่จำเป็น โซลูชั่นทางเลือกของ Barrett ได้รับการปรับปรุงใหม่ในบล็อกอะไหล่ของ Rudzicz ดังนี้:

  • บำรุงรักษารายการถนนที่ "เสนอ"
  • ประเมินพวกเขาในบางคำสั่ง
  • ถ้ายอมรับได้ (มีหรือไม่มีการดัดแปลงเล็กน้อย)
  • เก็บถนนที่ได้รับการยอมรับแต่ละแห่งในขณะที่ "กำลังเสนอ" กิ่งที่แยกออกจากกันจำนวนหนึ่ง

วิธีการนี้จะกำจัดการดูแลทำความสะอาดสัญลักษณ์ส่วนใหญ่ที่สืบทอดใน Parish and Müller's L-System คุณสามารถดูการสาธิตของวิธีการนี้ที่นี่

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

ในบางส่วนคุณสามารถปรับได้โดยเปลี่ยนกฎการแยกถนนหลีกเลี่ยงมุม 90 องศา ฯลฯ หากเลย์เอาต์ของคุณยังปกติเกินไปนี่คือการแก้ไขของฉัน:

แปลงตารางเมืองของคุณเป็นกราฟโดยที่ถนนแต่ละเส้นมีขอบ & แต่ละแยกเป็นโหนด ถัดไปใช้สิ่งที่ขั้นตอนวิธีที่คุณต้องการในการแปลงกราฟเข้าไปในเขาวงกต นี่คือตัวอย่างสุดท้ายกลายเป็นเขาวงกต: ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้เอาต์พุตมีปัญหาตรงข้ามมันเหมือนเขาวงกตมากเกินไป แต่ตอนนี้เราสามารถนำไปใช้คู่ของเทคนิคจากผลงานลับของ Jamis บั๊ก Dungeon ปั่นไฟ ขั้นแรกให้เพิ่มการกระจัดกระจายโดยการลบทางเดินส่วนปลายตาย ถัดไปเพิ่มการเชื่อมต่อโดยการเพิ่มถนนที่สร้างลูป (เช่นแนะนำวงรอบกราฟ) นี่คือตัวอย่างผลลัพธ์: ป้อนคำอธิบายรูปภาพที่นี่

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


6

หากคุณมองหาผังเมืองยุคกลาง / เก่าใน Googleคุณจะพบความหลากหลายที่แตกต่างกันไปส่วนใหญ่มาจากต้นกำเนิดของเมือง (เช่นการตั้งถิ่นฐานแบบสุ่มเทียบกับตำแหน่งทางทหารที่มีการจัดระเบียบ)

ฉันคิดว่าคุณกำลังมองหาการตั้งถิ่นฐานที่เป็นธรรมชาติ / วุ่นวายมากขึ้น

สำหรับสิ่งเหล่านี้ฉันจะลองวิธีเช่นนี้

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

3

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

จะหลอกรหัสใน JS เพราะเข้าใจง่ายกว่า

1ºกำหนดจุดเริ่มต้นในขณะที่คุณต้องการสร้างเมืองยุคกลางที่เราจะเริ่มต้นด้วยสี่เหลี่ยมดังนั้นสมมติว่าเมืองของคุณจะมี 300 หน่วยกำลังสองและสี่เหลี่ยมจะอยู่ตรงกลาง (แสดงด้วย X)

       300
________________
|               |
|               |
|               | 300
|       X       |
|               |
|               |
|_______________|

const square = [ 150, 150 ];

2ºตอนนี้เราจะลู่ทาง, จะมีจำนวนสุ่ม, พวกมันจะตรงและจะเริ่มจากจัตุรัสกลางหรือจากลู่ทางอื่น

let avenues = [] // will contain start and end [[sx,sy],[ex,ey]]
const n_avenues = RANDOM(4, 8); // number of avenues
const n_av_from_square = RANDOM(0, avenues); // starting in the square

for av in av_from_square
  avenues.push(square, [RANDOM(0, 200) + 100, RANDOM(0, 200) + 100])
  // we want avenues to have, at least 100 units length, thats why we randomize just te last 200 units of the whole town size

สิ่งนี้ควรให้ถนนและจตุรัสหลักสองสามอันแก่คุณ

       300
________________
|   \\          |
|    \\         |
|     \\        | 300
|       X=====  |
|               |
|               |
|_______________|

ตอนนี้เราต้องตั้งค่าลู่ทางที่ไม่ได้เริ่มในจตุรัสหลักพวกเขาจะตัดกันลู่ทางอื่น

for av in (n_avenues - av_from_square){
  const av_to_intersect = avenues[RANDOM(0,avenues.length)];

  //check av_to... and get a perpendicular vector (explained bellow)
  av[0] = [ av_to_intersect[0][1], - av_to_intersect[0][0] ];
  av[1] = [ av_to_intersect[1][1], - av_to_intersect[1][0] ];

}

ในการรับเวกเตอร์ตั้งฉากคุณต้องสลับ x, y cords และทำให้ y ใหม่:

swiped == x: noswiped.y, y: -1 * (noswiped.x)

ตอนนี้คุณควรมีสิ่งที่คล้ายกับที่นี่ดูเหมือนเมืองหรือไม่? : P

       300
________________
|   \\  //      |
|    \\//  ||   |
|     \\   ||   | 300
|    //\X=====  |
|   //     ||   |
|          ||   |
|_______________|

3ºตอนนี้คุณเพียง แต่ต้องเชื่อมต่อระหว่างถนนกับถนนสายสั้น ๆ เท่านั้นคุณยังสามารถวางไข่แบบสุ่มทั่วเมืองและทำแบบเดียวกันกับข้างต้นสำหรับพวกเขาทั้งหมดหรือแค่วางไข่บนถนนเล็ก ๆ

โปรดจำไว้ว่าถนนที่สั้นที่สุดของคุณคือเมืองที่วุ่นวาย

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