วิธีการจัดเก็บและแสดงแผนที่ย่อยบนเว็บได้อย่างมีประสิทธิภาพ


9

เกี่ยวกับ

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

เรากำลังสร้างเกมผู้ประกอบการหลายคนที่ใช้เบราว์เซอร์โดยใช้ห้องสมุด CraftyJS เพื่อแสดงผลเป็น Canvas ในพื้นหลังของ GUI เราใช้งาน Yii Framework บน PHP และทุกอย่างเชื่อมต่อกับเครื่องสร้างแผนที่แบบ Python และเครื่องมือสร้างเกม

นี่คือลักษณะที่แสดงแผนที่คร่าวๆเป็นครั้งแรก: http://i.imgur.com/khAXtl.png

กำลังจัดเก็บข้อมูลแผนที่

โลกของเกมจะถูกสร้างแบบสุ่มทุกครั้งที่เริ่มเกม ขนาดคือไพ่หกเหลี่ยม 100x100 สำหรับผู้เล่นแต่ละคน นั่นหมายความว่าสำหรับเกมผู้เล่นสามคนมีการสร้างไทล์ 90,000 แผ่น ขณะนี้ฉันเพิ่งสร้างอาร์เรย์ JavaScript ที่ฉันแสดงแผนที่

วิธีนี้ใช้งานได้ดีสำหรับการเรนเดอร์ แต่สำหรับการโต้ตอบใด ๆ กับแผนที่เราจำเป็นต้องเก็บผู้เล่นที่เป็นเจ้าของไทล์โครงสร้างประเภทใดที่สร้างอยู่ด้านบนสุดของมันราคาปัจจุบันและอื่น ๆ ในตอนแรกอย่างน้อยสำหรับต้นแบบเราต้องการใช้ MySQL แต่หลังจากการทดสอบบางอย่างมันไม่เร็วอย่างที่ฉันต้องการ บางทีที่เก็บวัตถุอย่าง MongoDB น่าจะเหมาะกว่าสำหรับเก็บข้อมูลไทล์แทนตาราง SQL หรืออาจเป็นอย่างอื่น?

แสดงแผนที่

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

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

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

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


1
ฉันประหลาดใจที่คุณระบุว่า MySQL เป็นคอขวด คุณทดสอบอะไรเพื่อให้ได้ข้อสรุปว่ามันทำให้ช้าลง
bummzack

@ bummzack หากเขามีแถวต่อแผ่นฉันแทบจะไม่สามารถดูว่าสิ่งต่าง ๆ จะไม่ช้า
aaaaaaaaaaaa

1
@eBusiness การสอบถามแถวพันแถวจากฐานข้อมูลควรไม่ใช่ปัญหาจริงๆ สิ่งนี้ควรอยู่ในช่วงมิลลิวินาที นอกจากนี้มันจะไม่เป็น 90'000 แถว แต่จะมีแถว 30'000 แถวสำหรับผู้เล่น 3 คน (100x100 ต่อผู้เล่น)
bummzack

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

คำตอบ:


2

การเล่นเกม
ก่อนอื่นฉันอยากถามคุณคุณต้องการ 10,000 แผ่นต่อผู้เล่นหรือไม่? ในขณะที่ฉันไม่รู้ว่าเกมแบบไหนที่คุณทำมันเป็นเรื่องจริงที่แผนที่ขนาดใหญ่สร้างเกมยาว แผนที่ที่ใหญ่ที่สุดในอารยธรรม 5 คือไพ่ 10240 และ sorta นั้นใช้ได้เพราะคุณไม่จำเป็นต้องเล่นมากกว่าเศษเสี้ยวของมัน

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

ที่เก็บข้อมูล JavaScript
สำหรับลูกค้าผมว่าคุณควรโหลดแผนที่ทั้งหมดให้ดีกว่าอย่างน้อยถ้าคุณติดกับแผ่น gazillion ที่มีทั้งหมดในต้นไม้วัตถุที่ดีอาจจะมากเกินไปดังนั้นคุณควรเก็บข้อมูลไว้ ในรูปแบบที่เข้ารหัส "กึ่งไบนารี" สตริงทำงานได้ดีเยี่ยมสำหรับสิ่งของประเภทนี้หรือคุณสามารถเก็บจำนวนเต็มไม่ได้ลงนามได้ถึง 53 บิตใน 64 บิตลอยตัวสิ่งต่างๆมากมายในอาร์เรย์และฉันคิดว่าคุณจะเห็นรอยความทรงจำที่ค่อนข้างดี

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

เคล็ดลับมืออาชีพ
อย่างไรก็ตามบางครั้งการแบ่งปันเมล็ดพันธุ์ที่ใช้ในการสร้างทำได้ง่ายกว่าการแชร์แผนที่ทั้งหมด


+1 แต่น่าเสียดายที่แอปพลิเคชันบนเว็บที่เขียนด้วย PHP มักจะไม่ได้หมายความว่าจะทำให้สถานะเกมอยู่ในความทรงจำ
bummzack

@bummzack, Ahh ใช่ฉันคิดว่าฉันข้ามคำว่า PHP ไปแล้วและอ่าน Python จากนั้นการเปลี่ยนแปลงของกรอบแบ็กเอนด์อาจเป็นไป Node.js อาจเป็นตัวเลือก
aaaaaaaaaaaa

ฉันกำลังสร้างผู้ประกอบการขนส่งที่มีการแข่งขันคิดว่า OpenTTD แผนที่ขนาด 512x512 (262k) นั้นไม่ใหญ่สำหรับผู้เล่นสองคน ฉันรู้ว่ามันมีความทะเยอทะยาน แต่ถ้าแผนที่ไม่ใหญ่เกมจะจบเร็วเกินไป เพราะมันเป็นเกมที่มีผู้เล่นหลายคนฉันต้องซิงค์การเปลี่ยนแปลงของแผนที่ระหว่างผู้เล่น สัญชาตญาณแรกของฉันคือใช้แนวคิดที่ฉันรู้จักจากการพัฒนาเว็บและไปกับดาต้าเบส มันไม่จำเป็นต้องเป็นเรียลไทม์สุด ๆ ฉันกำลังสร้างภาพข้อมูล JS เพราะฉันต้องการมีเนื้อหาแบบไดนามิกบนแผนที่
องค์ประกอบ

พิจารณาคำตอบของฉันให้เป็นพอยน์เตอร์ในท้ายที่สุดคุณจะต้องพัฒนาประสิทธิภาพของตัวเองมันเป็นปัญหาที่ร้ายแรงและคุณอาจต้องประนีประนอม
aaaaaaaaaaaa

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

1

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

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

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

ภาคผนวก:

เรากำลังใช้ Yii Framework บน PHP และทุกอย่างเชื่อมต่อกับเครื่องสร้างแผนที่แบบ Python และเอ็นจิ้นเกม

หากคุณมีความสามารถด้วย Python ฉันขอแนะนำให้คุณใช้คนกลาง PHP หากคุณเรียกใช้เกมเป็นกระบวนการ Python คุณสามารถเก็บข้อมูลไทล์ของคุณไว้ในหน่วยความจำได้ง่ายขึ้นและลดการเข้าถึง MySQL ลงอย่างมาก มันช่วยให้ Python นั้นเป็นภาษาที่มีความสุขมากกว่า PHP ด้วยเช่นกัน

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