एंड्रॉइड थ्रेड्स ने मेरे सिर को डिजाइन के चारों ओर लपेटने में परेशानी होती है


9

मुझे गेम डिज़ाइन के चारों ओर अपना सिर लपेटने में परेशानी हो रही है। एंड्रॉइड प्लेटफॉर्म पर, मेरे पास एक गतिविधि है और इसकी सामग्री को कस्टम सतह दृश्य के साथ सेट करें। कस्टम सतह दृश्य मेरे पैनल के रूप में कार्य करता है और मैं सभी कक्षाओं के उदाहरण बनाता हूं और वहां सभी ड्राइंग और गणना करता हूं।

प्रश्न: क्या मुझे अपनी गतिविधि में अन्य वर्गों के उदाहरण बनाने चाहिए?

अब मैं एक कस्टम थ्रेड क्लास बनाता हूं जो गेम लूप को हैंडल करता है।

प्रश्न: मैं अपनी सभी गतिविधियों में इस एक वर्ग का उपयोग कैसे करूँ? या क्या मुझे हर बार विस्तारित थ्रेड क्लास का एक अलग उदाहरण बनाना होगा?

मेरे पिछले गेम में, मेरे पास कई स्तर थे जिन्हें थ्रेड क्लास का एक उदाहरण बनाना था और थ्रेड क्लास में मुझे प्रत्येक अलग स्तर के लिए कंस्ट्रक्टर के तरीके सेट करने थे और लूप में एक स्विच स्टेटमेंट का उपयोग करके यह जांचना चाहिए कि इसे किस स्तर पर रेंडर करने की आवश्यकता है और अपडेट करें। क्षमा करें, अगर यह भ्रामक लगता है।

मैं बस यह जानना चाहता हूं कि क्या मैं जिस विधि का उपयोग कर रहा हूं वह अक्षम है (जो कि शायद यह है) और इसे सही तरीके से डिजाइन करने के बारे में कैसे जाना जाए। मैंने कई ट्यूटोरियल पढ़े हैं और मुझे अभी भी इस विषय पर बहुत परेशानी हो रही है। हो सकता है कि कुछ ट्यूटोरियल का एक लिंक जो इसे समझाए? धन्यवाद।

जवाबों:


13

मैं अत्यधिक अनुशंसा करता हूं कि आपके पास एक रेंडर थ्रेड है (उपयोग करना Canvas/ OpenGL ES, Canvasशायद सेटअप करना थोड़ा आसान है) और एक गेम थ्रेड जहां आप अपना गेम लॉजिक लगाते हैं।

खेल को वास्तव में "लोड" करने के लिए आप गेमप्लेइन क्लास बना सकते हैं और अपने आवेदन का केंद्र बिंदु बना सकते हैं। जब आपका रेंडरर जाने के लिए तैयार है, तो आप 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();
}

खेल यंत्र

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.
}

वाह धन्यवाद। मुझे अच्छा लगा कि आपने इसे कैसे समझाया। यह एक व्याख्या मेरे लिए पूरी अवधारणा को बताती है।
सेमाजं

@ सस्माजन: बस पूछें कि क्या आपको और समस्याएं हैं। :)

मेरे सिर में यही है: GameEngine वर्ग जो पैनल के साथ अन्य सभी वर्गों के लिए "लिंक" या "संदर्भ" के रूप में कार्य करता है। गतिविधि> पैनल> गेमबाइन> अन्य सभी कक्षाएं।
सेमाजं

@ सेमाजन: बिल्कुल। केवल आपके ज्ञान के लिए: यदि आप अपने साथ जाने का फैसला करते हैं, OpenGL ESतो आपको पता होना चाहिए कि रेंडरर के OpenGL ESपास पहले से ही अपना धागा है और उस स्थिति में आपको मैन्युअल रूप से एक नया Threadऔर Runnableउस सिस्टम को बनाने और शुरू करने की आवश्यकता नहीं है।

इस टिप्पणी को अनदेखा करें।
सेमाजं

3

आमतौर पर, आपका गेम-लूप किसी एकल गतिविधि के अंदर आत्म-निहित होता है।

जब आप गतिविधि स्विच करते हैं, तो आप अपने गेम-लूप को रोकते / मारते हैं। अलग-अलग गतिविधियों को खेल को वैसे भी रोकने के अनुरूप होना चाहिए (जैसे कि आपने "दोस्तों को ईमेल भेजें" या "मुख्य वेबसाइट" पर स्विच किया है)

अतिरिक्त स्तरों के लिए, आपको किसी भी नए थ्रेड का निर्माण या उसे नष्ट नहीं करना चाहिए ... जब तक कि आप "स्तर-पूर्ण, अगले स्तर पर लोड नहीं कर रहे हैं, कृपया प्रतीक्षा करें" गतिविधि, और आप "मुख्य गेम को पुनरारंभ करने जा रहे हैं" “वैसे भी गतिविधि। लेकिन उस मामले में भी, आप वास्तव में "अतिरिक्त" धागे नहीं बना रहे हैं, आप सिर्फ एक धागा उस एक गतिविधि में बना रहे हैं, और क्रमिक रूप से हत्या / पुनः आरंभ / हत्या / पुनः आरंभ कर रहे हैं ... आदि। हर बार एक स्तर पूरा हो गया है।


3

यदि आप जर्मन समझते हैं, तो यह ट्यूटोरियल बहुत अच्छा है।

अंग्रेजी भाषा के लिए मैं सिफारिश कर सकता हूं इस ट्यूटोरियल की

धागा कक्षा के बारे में: मुझे नहीं पता कि क्या यह वास्तव में आवश्यक है कि आप अपने आवेदन में सभी वर्गों से संदर्भ ले सकते हैं। अपने खेल में, मैंने इसे इस तरह हल किया:

मुख्य GUI आकर्षित करने के लिए जिम्मेदार वर्ग में एक ओवरराइड रेंडर विधि है। इस पद्धति में एक थ्रेड क्लास कहा जाता है जो सभी GUI तत्वों को अपडेट करता है और उपयोगकर्ता इनपुट को संसाधित करता है।

एक स्थिर फ्रैमरेट को बनाए रखने के लिए धागा भी जिम्मेदार है। आपके द्वारा विकसित किए जा रहे खेल के आधार पर यह महत्वपूर्ण हो सकता है।


यह जर्मन ट्यूटोरियल अच्छा है, लेकिन यह मोटे तौर पर vai google का अनुवाद किया गया था, इसलिए इसे समझना कठिन है।
सेमाजं
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.