อัลกอริทึมเส้นทางแบบไดนามิกสำหรับเกมป้องกันหอ


16

ฉันสร้าง Tower Defense และฉันต้องการอัลกอริทึม pathing ที่ดีสำหรับมัน

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

ฉันกำลังเขียนโปรแกรมใน C # ถ้ามันช่วย

คำตอบ:


8

โดยทั่วไปคุณจะต้องการใช้ A * ยกเว้นว่ามีบางสิ่งที่แตกต่างที่สำคัญที่คุณต้องการ


ถ้าฉันไม่คุ้นเคยกับ A * ฉันจะจัดการกับสภาพแวดล้อมที่เปลี่ยนแปลงแบบไดนามิกได้อย่างไร คำนวณซ้ำทุกเฟรมหรือไม่ ที่ชน?
Justin L.

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

6
ถ้ามันช้าคำแนะนำของฉัน: อย่าคำนวณเส้นทางสำหรับฝูงชนทุกคน ดูเหมือนว่าพวกเขาทั้งหมดกำลังไปในเส้นทางเดียวกัน ฉันเพียง ReCalc ในตำแหน่งหอใหม่และหอนั้นอยู่ในเส้นทางปัจจุบัน ถึงกระนั้นก็ตามให้ทำการคำนวณใหม่อีกครั้งสำหรับมอนสเตอร์ที่จุดในเส้นทางก่อนสี่เหลี่ยมจัตุรัสบล็อกไม่ใช่สำหรับ mobs ที่ผ่านมาแล้วดังนั้นจึงไม่สนใจ จากนั้นหากต้องการทำให้การค้นหาเส้นทางสั้นลงคุณสามารถ จำกัด การค้นหาเส้นทางไปยังจัตุรัสหลังจัตุรัสที่ถูกบล็อกเนื่องจากคุณรู้เส้นทางจากที่นั่น
seanmonstar

4
อันที่จริง "ม็อบ" เป็นอุตสาหกรรม (และผู้เล่น MMO / MUD) ศัพท์แสงสำหรับ "วัตถุมือถือ"

3
ไม่ว่าจะนานมาแล้วก็ย้อนหลังไปที่ MUD1 และมาตรฐานพอที่จะปรากฏในสิ่งพิมพ์หลายฉบับ en.wikipedia.org/wiki/Mob_%28computer_gaming%29

19

ฉันจำเป็นต้องแก้ปัญหาที่คล้ายกัน: ค้นหาเส้นทางบนกริดเหมือนเขาวงกตขนาดใหญ่ที่มี "ต้นทุน" และอุปสรรคที่เปลี่ยนแปลงตลอดเวลา

สิ่งที่เป็นในเกมป้องกันหอจำนวนหน่วยงานที่ต้องมีการแก้ไขเส้นทางสำหรับพวกเขามักจะมีขนาดใหญ่กว่าจำนวนโหนดในกราฟ A * ไม่ใช่อัลกอริทึมที่เหมาะสมที่สุดในการจัดการกับสิ่งนี้เพราะคุณจะต้องแก้ปัญหาใหม่ทุกครั้งที่มีการเปลี่ยนแปลง เป็นเรื่องที่เหมาะสมหากคุณต้องการค้นหาเส้นทางเดียว แต่ในกรณีของฉันฉันต้องสามารถจัดการเอนทิตีที่สามารถปรากฏในสถานที่ต่างกันและแต่ละเส้นทางมีเส้นทางของตัวเอง

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

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

อัลกอริทึมของฉันเป็นพื้นคล้าย (รหัสหลอก):

update_node method in Node class:
    $old <- $my_score
    find $neighbor node among all neighbors such that
        $neighbor.score + distance_to($neighbor) is minimal
    $my_score <- $neighbor.score + distance_to($neighbor)
    $next_node <- $neighbor
    if ($my_score != $old)
        for each $neighbor
            $neighbor.update_node()

ด้วยคะแนนเริ่มต้นขึ้นอยู่กับว่าโหนดนั้นเป็นเป้าหมายหรือสิ่งกีดขวางบางประเภท


1
นอกจากนี้ยังง่ายต่อการแพร่กระจายสิ่งนี้บนเฟรมแบบไดนามิกเมื่อโหลด CPU เปลี่ยนแปลง
tenpn

+1 สำหรับ A * ไม่ใช่อัลกอริธึมที่เหมาะสมที่จะใช้
Ricket

5

อัลกอริทึมเส้นทางที่ฉันใช้กับ TD ของฉันนั้นย้อนกลับจากปกติ A * เส้นทางเนื่องจากจำนวนหน่วยงานที่ฉันมีในเกม แทนที่จะกำหนดเส้นทางจากเป้าหมายไปยังคนร้ายฉันส่งเส้นทางจากเป้าหมายไปยังทุกช่องว่างบนกระดาน

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

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

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

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


4

Pathfinding นั้นรวดเร็วและในบางขนาดของเกมป้องกันหอคอยแบบปกติคุณจะไม่มีปัญหาในการใช้ A * หรือ Dijkstra เต็มเมื่อใดก็ตามที่มีการเปลี่ยนแปลง เรากำลังพูดคุยกันภายใต้มิลลิวินาทีสำหรับการรีเฟรชแบบเต็ม การหาเส้นทางแบบปรับได้ชนิดใด ๆ ก็มีความซับซ้อนอย่างน่ากลัว ทำแบบง่ายๆเว้นแต่คุณจะสร้างตารางป้องกันหอคอยที่ใหญ่ที่สุดในโลก


1
เป็นที่น่าสังเกตว่า Tower Defense ได้รับความนิยมในโทรศัพท์มือถือซึ่งการค้นหาเส้นทางไม่รวดเร็ว โดยเฉพาะอย่างยิ่งในอุปกรณ์รุ่นเก่าเช่นเพื่อนสนิทหรืออุปกรณ์ Android 1.6
seanmonstar

1
นักพัฒนาใช้อัลกอริธึมการบอกทางแบบ A * และ Dijkstra กับฮาร์ดแวร์ที่ทรงพลังน้อยกว่าหลายสิบปี (คิดว่า Game Boy) โทรศัพท์เครื่องใหม่ที่มีหน้าจอเพียงพอสำหรับการเล่นเกมไม่ควรมีปัญหาโดยแน่นอนว่าการใช้งานนั้นมีประสิทธิภาพพอสมควร มีการเพิ่มประสิทธิภาพที่ดีที่กล่าวถึงที่นี่: harablog.files.wordpress.com/2009/06/beyondastar.pdf
Mike Strobel

+1 ฉันมาถึงข้อสรุปเดียวกันเมื่อฉันพัฒนาโคลน DTD ของฉันเอง ฉันพยายามปรับปรุงเส้นทางเพิ่มเติม แต่อัลกอริทึมก็ซับซ้อนเกินไป หลังจากใช้เวลาหนึ่งวันกับมันฉันเปลี่ยนไปใช้การคำนวณใหม่ทั้งหมดในการเปลี่ยนแปลงแต่ละครั้ง การทำงานนั้นและด้วยการปรับแต่งเล็กน้อยฉันสามารถทำให้มันเร็วพอ
finnw


2

นี่อาจเป็นค่าใช้จ่ายที่มากเกินไปสำหรับโซลูชันของคุณ แต่ให้คิดถึงการกำหนดเส้นทางย้อนกลับแทนการส่งต่อ

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


1

การค้นหาเส้นทางของ Waypoint น่าจะดีที่สุดสำหรับเกม td เพราะโดยทั่วไปแล้วจะขึ้นอยู่กับระดับที่ ai ติดตามเส้นทางโดยตรง โดยทั่วไปคุณตั้งค่าโหนดหรือจุดอ้างอิงของคุณจากนั้นมี "ai" ชี้ไปที่ waypoiny และเดินไปที่มันเมื่อมันเข้าใกล้พอที่จะไปที่ waypoint ถัดไปหันหน้าไปทางนั้น


ใช้งานได้กับเกม TD ที่คุณสามารถวางป้อมไว้ที่ด้านข้างของเส้นทางเท่านั้นไม่ใช่เกมที่อนุญาตให้วางหอคอยได้ทุกที่บนกระดาน
Iain

ใช่ตอนแรกผู้เขียนไม่ได้ระบุประเภทที่เขาต้องการดังนั้นฉันคิดว่าไม่ใช่แบบไดนามิก
Loktar

1

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

โปรดทราบว่าเกม TD บางเกมมีเส้นทางที่กำหนดไว้และไม่อนุญาตให้คุณวางหอคอยไว้บนนั้นดังนั้นพวกเขาจึงแก้ปัญหาการหาเส้นทางได้ง่าย ๆ : โดยการเข้ารหัสเส้นทางและไม่อนุญาตให้คุณบล็อก :)


1

ทางออกที่ง่ายคือการโกง

ออกแบบแผนที่ไว้ล่วงหน้าเพื่อให้แน่ใจว่าไม่มีจุดจบ จากนั้นในแต่ละสี่แยกให้เพิ่มทริกเกอร์ที่ทำให้ตัวละครเลือกเส้นทาง (ตัวอย่าง: เลี้ยวซ้ายเสมอเลี้ยวขวาหรือสุ่ม)


1
สมมุติว่าเขากำลังพูดถึงบางอย่างเช่น Desktop TD ที่ผู้ใช้สร้างแผนที่ได้ทันที ยังสำหรับศัตรู "โง่" ที่อาจเป็นทางออกที่ดีดังนั้นคุณสามารถทำให้ศัตรูที่มี AI ดีขึ้นเพิ่มความลำบากเล็กน้อย
coderanger
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.