Android нитки проблеми з обгортанням моєї голови навколо дизайну


9

У мене виникають проблеми з обгортанням голови навколо ігрового дизайну. На платформі android у мене є активність і я налаштовую її перегляд вмісту за допомогою спеціального перегляду поверхні. Спеціальний вигляд поверхні виступає моєю панеллю, і я створюю екземпляри всіх класів і роблю там все креслення та обчислення.

Питання: Чи потрібно замість цього створити екземпляри інших класів у моїй діяльності?

Тепер я створюю власний клас потоку, який обробляє цикл гри.

Питання: Як я використовую цей один клас у всіх своїх заходах? Або мені потрібно створювати окремий примірник розширеного класу потоку кожного разу?

У моїй попередній грі у мене було кілька рівнів, які повинні були створити екземпляр класу потоків, і в класі потоку я повинен був встановити методи конструктора для кожного окремого рівня, а в циклі використовувати оператор перемикання, щоб перевірити, на якому рівні йому потрібно рендерувати та оновлення. Вибачте, якщо це звучить заплутано.

Мені просто хочеться знати, чи метод, який я використовую, неефективний (який він, мабуть, є), і як правильно розробити його правильно. Я прочитав багато навчальних посібників там, і у мене ще багато проблем з цією темою. Може бути посилання на якісь підручники, які пояснюють це? Дякую.

Відповіді:


13

Я настійно рекомендую мати у своєму розпорядженні нитку візуалізації (використання Canvas/ OpenGL ES, Canvasмабуть, трохи простіше в налаштуванні) та ігровий потік, де ви вкладете свою логіку гри.

Щоб насправді "завантажити" гру, ви можете створити GameEngine клас і зробити це центральною точкою вашої програми. Коли ваш рендер готовий до запуску, ви можете створити зворотний виклик до екземпляра 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 та обробляє введення користувача.

Нитка також відповідає за підтримку постійної частоти кадрів. Залежно від гри, яку ви розробляєте, це може бути важливим.


Цей німецький підручник є приємним, але він був грубо перекладений vai google, тому його важко зрозуміти.
semajhan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.