วิธีที่ดีที่สุดในการสร้างแผนที่สำหรับเกม 2D?


16

ฉันขอโทษสำหรับคำหลัก "ดีที่สุด" ที่เป็นอัตนัย

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

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

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

วันนี้เขาบอกฉันว่าเขาต้องการสร้างแผนที่อาเรย์สองมิติแบบง่ายๆ [กว้าง] [ความสูง] ที่มีข้อมูลเกี่ยวกับทุกตารางในเกมและเป็นการดำเนินการบันทึกสู่ดิสก์อย่างต่อเนื่องสำหรับข้อมูลที่เราไม่ต้องการ

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


คุณใช้เครื่องจักรอะไร
David Titarenco

Windows ที่มี C ++ ที่ใช้ SFML จนถึงขณะนี้ (SFML อาจเปลี่ยนแปลงได้ แต่ C ++ ไม่ใช่) เราไม่ได้ตั้งเป้าหมายที่จะพกพา ATM
IAE

2
หากคุณกำลังจะไปโรงเรียนเก่า Zelda บน NES ใช้แผนที่เพียงหน้าจอเดียว แผนที่ขนาดเล็กช่วยให้ผู้เล่นมุ่งเน้นขอบเขตความตั้งใจของพวกเขา (เช่นในคุกใต้ดินคุณจัดการกับห้องของคุณเท่านั้นใน diablo สัตว์ประหลาดไม่ได้เลื่อนขึ้นและลง) และอนุญาตให้พวกเขารู้สึกเสร็จหากพวกเขาค้นหาทั่วทั้งพื้นที่ เกมที่เปิดพื้นที่เช่น FAllout3 และ Oblivion ไม่ได้ให้คุณ
Stephen Furlani

คำตอบ:


27

ก่อนอื่นให้ประมาณขนาดแผนที่ของคุณ อย่าเพิ่งคิดว่า "โลกใบใหญ่" จะไม่เข้ากับความทรงจำ ทุกวันนี้แผนที่ที่มีหน่วยความจำสูงกว่า 10 mb นั้นเป็นที่ยอมรับและคุณสามารถบรรจุสิ่งต่าง ๆ ได้มากถึง 10 mb ในโลก 2 มิติบนพื้นฐานของไทล์

หากคุณมีจริงๆโลกขนาดใหญ่โซลูชั่นที่มีประสิทธิภาพมากที่สุดย่อมเป็นชิ้นใช้งานแผนที่ แบ่งโลกของคุณออกเป็นชิ้นขนาดคงที่ (พูด 64x64) โหลดชิ้นโหลดแบบทันทีทันใดขณะที่ผู้เล่นเคลื่อนที่ไปรอบ ๆ เก็บชิ้นอย่างน้อยหนึ่งชิ้นในทุกทิศทาง (เช่นโหลดชิ้นส่วนที่ผู้เล่นอยู่และเพื่อนบ้านทั้งหมด)

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


6
คณิตศาสตร์ตัวอย่างบางส่วน: Tile ขนาด 10MB ของได้รับสี่เหลี่ยมจัตุรัส 1619 แผ่นต่อด้าน แผนที่ดั้งเดิมของ Zelda นั้นมี 256 ไทล์ที่ด้านยาวและน้อยกว่าครึ่งที่อยู่ทางด้านสั้น - ดังนั้นแผนที่ของคุณอาจใหญ่กว่า 36x แรกของ Zelda ด้วยการใช้หน่วยความจำนั้น คุณพร้อมที่จะสร้างเนื้อหาที่ใช่หรือไม่? (หมายเลข)

@ user744 ความคิดเห็นนั้นทำให้เข้าใจผิดอย่างไม่น่าเชื่อ ในการสร้างแผนที่คุณต้องมีมากกว่าพอยน์เตอร์ไปยังไทล์ คุณต้องจัดเก็บข้อมูลที่ไทล์มีเช่นกัน ไม่ใช่ทุก ๆ เกม 2D ที่มีจำนวนไพ่คงที่ที่กำหนดไว้ล่วงหน้า
Jeroen

5

โดยส่วนตัวฉันจะสร้างแผนที่โดยใช้โปรแกรมแก้ไขแบบเรียงต่อกันที่กำหนดเช่นTileEd วิธีการนี้ให้ประโยชน์หลายประการ:

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

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

การตัดกระเบื้องเป็นหน้าจออาจเป็นวิธีที่เร็วที่สุดในการแสดงแผนที่ของคุณ ฉันไม่รู้จัก SFML แต่จากเอกสารบนเว็บไซต์ของพวกเขาคุณควรมองเข้าไปในSpriteชั้นเรียนหรือใช้Copyฟังก์ชั่นของImageชั้นเรียน

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


1

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


0

ในความคิดของฉันการใช้อาร์เรย์ 2 มิติของแผ่นกระเบื้องแยกกัน คุณสามารถมีทั้งแผนที่ขนาดใหญ่ทั้งหมดเป็นอาเรย์สองมิติและดึงส่วนหนึ่งของมันที่จำเป็นต้องแสดงในเวลาที่กำหนด ต่อไปนี้เป็นตัวอย่างของการใช้อาเรย์แผนที่ 2 มิติกับ tabageos (tbgs.js) ไลบรารีเกม HTML5 http://actiontad.com/tabageosHTML5/Examples/BlitMathCameraAndTravelers/


-3

นอกเสียจากว่าคุณกำลังวางแผนที่จะสร้าง ultima-online (Fallout 3 หรือ Oblivion) ​​ขึ้นมาใหม่ไม่มีเหตุผลที่โลกจะต้องราบรื่น Baldur's Gate และ Icewind Dale เป็นสองเกมที่คำนึงถึงการใช้แผนที่ที่มีประสิทธิภาพซึ่งไม่เบี่ยงเบนจากการเล่นเกม

จริงอยู่ที่คุณมีแรงม้าในการคำนวณมากกว่าที่พวกเขาทำดังนั้นการโหลดหน้าจอควรจะน้อยที่สุด แต่แม้ Fallout และ Oblivion ก็จะมีหน้าจอโหลดสำหรับบางสิ่ง

ทั้งหมดที่ฉันสามารถบอกคุณได้ก็คือสำหรับฉันฉันกำลังเขียน Obj-C lib เล็ก ๆ สำหรับ iPhone ที่ใช้ชุดไพ่ 32x32 และดึงเข้าไปใน NSImage ฉันได้รับประมาณ 10fps ด้วยวิธีนี้และฉันอาจจะใช้ OpenGL แต่ฉันต้องวาดใหม่หากตัวละครย้ายออกจาก rect

คุณควรแบ่งแผนที่ออกเป็น 9 ขนาดหน้าจอ (สำหรับฉันมันเป็น 960x640 บล็อก) ดังนั้นถ้าตัวละครย้ายออกจากบล็อกกลางฉันวาดหน้าจอ 9 หน้าจอใหม่เป็นภาพขนาดใหญ่ (ประมาณ 1.2MB - ให้มาก ห้องภายใต้ขีด จำกัด 20MB บน iPhone 3G) ที่เกิดขึ้นค่อนข้างช้า (ช้ากว่า 10fps) ดังนั้นการวาดภาพซ้ำจะไม่สังเกตเห็นได้ในระหว่างการเล่น

ฉันอาจจะย้ายไปที่ OpenGL ES ในบางจุด แต่ตอนนี้มันใช้งานได้ดี


[แก้ไข]

อนุญาตให้ฉันชี้แจง

อัลกอริทึมการวาดภาพสำหรับพื้นหลัง 9 หน้าจอใช้เวลา 0.1 วินาที (แบน 10fps) ยกเว้นว่าผู้เล่นของคุณสามารถข้ามหน้าจอทั้งหมดในเวลาน้อยกว่าหนึ่งในสิบของวินาทีการวาดใหม่ควรจะไม่สามารถมองเห็นได้ในระหว่างการเล่น


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

@Joe Wreschnig ... ??? ฉันบอกว่ามันเป็นไปตามความต้องการเมื่อผู้เล่นย้ายหน้าจอมิฉะนั้นภาพพื้นหลังสำหรับ UIImageView จะไม่ได้รับการวาดใหม่ดังนั้นจึงประหยัดพลังงานในการประมวลผล ความคิดเห็นของคุณไม่สมเหตุสมผล
Stephen Furlani

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

@ โจฉันยังไม่แน่ใจว่าสิ่งที่คุณพูด มันวาดภาพ จากนั้นภาพจะถูกทิ้งไว้ตามลำพังจนกว่าผู้เล่นจะถึงขอบเขตแล้วจึงดึงภาพใหม่ วิธีนี้จะทำให้แบตเตอรี่หมด เพียงแค่ "ดึง" ตามต้องการและเวลาที่เหลือจะถูกดึงโดยใช้อัลกอริทึมการวาดภาพดั้งเดิมของ UIImageView
Stephen Furlani
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.