หัวข้อ Android มีปัญหาห่อหัวของฉันไปรอบ ๆ การออกแบบ


9

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

คำถาม: ฉันควรสร้างอินสแตนซ์ของคลาสอื่นในกิจกรรมของฉันแทนหรือไม่

ตอนนี้ฉันสร้างคลาสเธรดที่กำหนดเองที่จัดการลูปเกม

คำถาม: ฉันจะใช้คลาสนี้ในทุกกิจกรรมได้อย่างไร หรือฉันจะต้องสร้างอินสแตนซ์ที่แยกต่างหากของคลาสเธรดเสริมแต่ละครั้งหรือไม่

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

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

คำตอบ:


13

ฉันขอแนะนำให้คุณใช้เธรดการเรนเดอร์ (โดยใช้Canvas/ OpenGL ES, Canvasอาจจะง่ายกว่าการเซ็ตอัพเล็กน้อย) และเธรดเกมที่คุณวางตรรกะเกมของคุณไว้

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

รหัสตัวอย่าง:

แอปพลิเคชันเริ่มต้น

private GameEngine engine;
private CanvasRenderer renderer;

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   // Create instances of your two Runnable classes and pass that into
   // the GameEngine constructor.
   // Create an instance of the game engine.
   engine = new GameEngine(canvasRunnable, gamelogicRunnable);
   renderer = new CanvasRenderer(this, engine); 
   setContentView(renderer); 
}

CanvasRenderer

private GameEngine engine;    

// Save your instance from the GameEngine reference in your constrcutor and make
// a global initializion for your GameEngine instance.  

@Override
public void surfaceCreated(SurfaceHolder holder) {  
   // One time setup here.
   // When your view is ready, make this callback to the 
   // GameEngine.
   engine.surfaceIsReady();
}

GameEngine

private Thread canvasThread;
private CanvasRunnable canvasRunnable;
// You should be able to figure out how to create a second thread
// where you should put your game logic. :)

// Constructor stuff like creating instances of your threads
// and passing references as you wish to those.
// Don't start the threads here.
// Remember to set references from your Runnable's into your Thread's 
// instances here!

/**
 * Callback. Now your renderer is ready and you
 * can start your threads.
 */
public void surfaceIsReady() {
   thread.setName("Canvas");
   thread.start();
   // Same for game logic.
}

ว้าวขอบคุณ. ฉันชอบวิธีที่คุณอธิบาย คำอธิบายนั้นทำให้ฉันเข้าใจแนวคิดทั้งหมดของฉัน
semajhan

@semajhan: เพียงแค่ถามว่าคุณมีปัญหามากขึ้นหรือไม่ :)

นี่คือสิ่งที่ฉันมีอยู่ในหัวของฉัน: คลาส GameEngine ที่ทำหน้าที่เป็น "ลิงค์" หรือ "อ้างอิง" กับคลาสอื่น ๆ ทั้งหมดด้วยพาเนล กิจกรรม> แผงควบคุม> GameEngine> คลาสอื่นทั้งหมด
semajhan

@semajhan: แน่นอน สำหรับความรู้ของคุณเท่านั้น: หากคุณตัดสินใจที่จะไปกับOpenGL ESคุณควรรู้ว่าตัวแสดงผลOpenGL ESมีเธรดของตัวเองอยู่แล้วและในกรณีนั้นคุณไม่จำเป็นต้องสร้างและเริ่มใหม่Threadและด้วยตนเองRunnableสำหรับระบบนั้น

ละเว้นความคิดเห็นนี้
semajhan

3

โดยทั่วไปแล้วลูปเกมของคุณจะอยู่ในกิจกรรมเดียว

เมื่อคุณสลับกิจกรรมคุณจะหยุดชั่วคราว / ฆ่าเกมลูปของคุณ กิจกรรมแยกควรสอดคล้องกับการหยุดเกมชั่วคราว (เช่นเนื่องจากคุณเปลี่ยนเป็นกิจกรรม "ส่งอีเมลไปยังเพื่อน" หรือ "เมนูหลัก")

สำหรับระดับพิเศษคุณไม่ควรสร้างหรือทำลายเธรดใหม่ใด ๆ ... เว้นแต่คุณจะเปลี่ยนเป็น "ระดับเสร็จสมบูรณ์โหลดระดับถัดไปโปรดรอ" กิจกรรมและคุณจะต้องเริ่มเกมหลัก "ใหม่ "กิจกรรมอยู่ดี แต่ในกรณีนั้นคุณไม่ได้สร้างเธรด "พิเศษ" คุณเพียงแค่สร้างหนึ่งเธรดในกิจกรรมนั้นและฆ่า / รีสตาร์ท / ฆ่า / รีสตาร์ทตามลำดับ ... ฯลฯ ในกิจกรรมนั้น แต่ละครั้งที่ระดับเสร็จสมบูรณ์


3

ถ้าคุณเข้าใจภาษาเยอรมันการสอนนี้ดีมาก

สำหรับภาษาอังกฤษฉันสามารถแนะนำบทแนะนำนี้ได้

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

คลาสที่รับผิดชอบในการวาด GUI หลักมีวิธีการเรนเดอร์แบบ overriden ในวิธีการนี้จะเรียกว่าคลาสเธรดซึ่งจะอัปเดตองค์ประกอบ GUI ทั้งหมดและประมวลผลอินพุตผู้ใช้

เธรดยังรับผิดชอบในการรักษาอัตราเฟรมคงที่ ขึ้นอยู่กับเกมที่คุณกำลังพัฒนาสิ่งนี้อาจมีความสำคัญ


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