Програмування ігор Java 2D: різні підходи до створення ігрового циклу


10

Я новачок в ігровому програмуванні Java, але чим більше я читаю, тим більше я плутаюся, тому що я бачив кілька різних підходів до створення циклу гри: 1. Стандартний підхід, що використовує клас Timer (здається, менше точний). 2. Більш точний підхід, який використовує System.nanoTime. 3. Простий підхід, який використовує rasporedAtFixedRate.

Кому з них слід віддати перевагу і де є переваги / недоліки кожного підходу? Заздалегідь дякую за будь-яку інформацію.

Відповіді:


7

Для базового циклу ігор слід запустити цикл у той час, протягом якого ви отримаєте час, використовуючи nanoTime (), визначте, скільки часу минуло з останнього кадру, а потім оновите ігровий стан і рендер.

Використовуючи http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime%28%29 , ви можете опитувати за минулий час. В основному ...

public static void main(String [ ] args)
{
    long current_frame_time = system.nanoTime();
    long last_frame_time = current_frame_time;

    while(gameIsRunning)
    {
        last_frame_time = current_frame_time;
        current_frame_time = system.nanoTime();

        long timeTaken = current_frame_time - last_frame_time;

        //update and render game here
    }
}

Цей основний метод можна вдосконалити, наприклад, http://www.koonsolo.com/news/dewitters-gameloop/ та http://gafferongames.com/game-physics/fix-your-timestep/ .

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

Відповідно до http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html : " Відповідний кожному об'єкту Timer є єдиний фоновий потік, який використовується для виконання всіх таймерів завдання, послідовно. Завдання таймера повинні виконуватись швидко. Якщо завдання таймера потребує зайвого часу для завершення, воно "завиває" нитку виконання завдання таймера. Це, в свою чергу, може затримати виконання наступних завдань, які можуть "згуститися" і виконувати швидко, коли (і якщо) злочинне завдання нарешті виконане. "

Відповідно до http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html#scheduleAtFixedRate%28java.util.TimerTask,%20java.util.Date,%20long%29 : " У режимі фіксованої ставки кожне виконання планується відносно запланованого часу виконання первинного виконання. Якщо виконання буде відкладено з будь-якої причини (наприклад, збирання сміття чи інша довідкова діяльність), два чи більше виконання будуть відбуватися швидко щоб "наздогнати". З часом частота виконання буде точно зворотною за вказаний період (якщо припустити, що системний годинник, що лежить в основі Object.wait (long), є точним). "

Оскільки ви зазвичай не знаєте заздалегідь, скільки часу займає цикл гри, встановлення таймера для виконання вашої ігрової петлі кожні X мілісекунд (залежно від цільової частоти кадрів) може призвести до декількох згорнутих кадрів, які виконуватимуться кожного разу, коли кадр буде закінчено замість того, коли призначено кадр. Коли це відбувається ... навіщо в першу чергу використовувати таймер?

Тепер, не зрозумійте мене, таймер - це не поганий клас, але він, як правило, краще підходить для невеликих завдань, які потрібно виконувати періодично або в певний час, наприклад, поштовий клієнт може хотіти перевіряти наявність нової пошти кожні 5 хвилин, або лічильник може зменшуватися щосекунди, щоб відобразити зворотний відлік до початку гонки.


Питання стосувалося циклів гри, тому інформація про awt / swing є поза темою. Однак виглядало, що ця інформація була актуальною через невідповідну і заплутану лінію у питанні, тому я її усунув.
поштовх

Я адаптував свою відповідь, щоб відобразити зміни, внесені до питання.
Вихідний

7

Я б не ставив головну петлю в таймер. Швидше я б зробив цикл "while", який обробляє кожен кадр, а потім використовую якусь функцію хронометражу (це звучить як у Java, що це System.nanoTime), щоб обчислити, скільки часу минуло з часу останнього кадру / останньої ітерації петля.

Деякі мови тут є винятками (наприклад, JavaScript, ActionScript), оскільки ці мови працюють у середовищі, яке має чіткий основний цикл для підключення (наприклад, браузер, Flash Player), але цей виняток не застосовується до Java.

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