Архитектура и методология игры (экраны / эффекты) - PullRequest
0 голосов
/ 27 января 2012

Я смотрю на то, как я должен разрабатывать свои игры с точки зрения управления / перехода с разных «экранов», а также с учетом времени выполнения. В настоящее время я использую AndEngine на Android, который не имеет явного игрового цикла, хотя мне интересно услышать, как эти проблемы решаются как с игровым циклом, так и без него.

  1. Я уже написал временную систему, которую я использую для обработки различных «экранов» в моей игре (заставка, меню, игра, опции и т. Д.), Которая основана на «сценах» в AndEngine. У меня есть 3 базовых "сцены", которые действуют как слои для фона, контента и всплывающих окон. Каждый экран имеет методы onTransitionIn () и onTransitionOut (), которые вызываются ScreenManager, когда вызываются его собственные методы (например, closePopup () и тому подобное). Однако весь код в методах перехода, очевидно, будет выполняться одновременно, то есть все анимации, состояние экрана и т. Д. Будут выполняться мгновенно. Чтобы преодолеть эту проблему, я использовал метод postDelayed (runnable, delay) в классе Android-обработчика. Таким образом, я смог изменить состояние экрана после завершения анимации перехода и запускать одну анимацию за другой. Теперь вся система в значительной степени основана на запуске отложенного кода через обработчик. Неудивительно, что он грубый, не особо стабильный и в целом дилетантский.

  2. Второй вопрос, касающийся «времени эффекта», тесно связан с моим использованием класса Handler. Скажем так, я хочу создать эффект, когда пользователь завершает задачу, когда воспроизводится некоторая анимация и на экране увеличивается число. На данный момент единственный способ запустить один за другим - использовать обработчик. Как указывалось ранее, это кажется мне грубым / нестабильным / любительским методом.

Мне бы очень хотелось узнать, как эти проблемы обычно решаются в играх (как с явным циклом, так и без него).

1 Ответ

1 голос
/ 27 января 2012

Из вашего описания звучит так, что когда вы хотите запустить цепочку действий, вы в основном запускаете их все сразу, каждое с некоторой фиксированной задержкой.Это довольно хрупко - если вы измените продолжительность одного из действий, оно может больше не синхронизироваться с чем-то, что должно произойти после него.

Более надежный подход - использовать Observer.Узор .Каждое действие может иметь событие onCompleted() (и / или различные другие события, в зависимости от характера действия), которое можно использовать для запуска начала следующего действия.

Например, скажем,что, когда пользователь нажимает кнопку выбора элемента меню, вы хотите следующую последовательность событий:

  1. Воспроизвести анимацию выбранного элемента.
  2. Когда 1 закончится, перейдите на текущий экранвыкл.
  3. Когда закончится 2, включите следующий экран.

Похоже, вы делаете что-то вроде этого:

void onItemSelected(MenuItem menuItem) {
    runNow(new SelectedItemAnimationHandler(menuItem)); // Takes 500ms
    // Delay for 500ms to wait until end of selection anim.
    postDelayed(new ScreenTransitionOffHandler(currentMenu), 500); // Takes 1000ms
    // Delay for 1500ms to wait until end of transition off.
    postDelayed(new ScreenTransitionOnHandler(nextMenu), 1500);
}

Возможно, выобъедините в цепочку события, создав действия (которые выполняют роль субъекта в шаблоне Observer) и ActionObservers (которые выполняют роль наблюдателя):

void onItemSelected(MenuItem menuItem) {
    // Set up the actions
    // Actions call onCompleted() on any observers when they complete.
    SelectedItemAnimationAction sa = new SelectedItemAnimationAction(menuItem);
    ScreenTransitionOffAction stoff = new ScreenTransitionOffAction(currentMenu);
    ScreenTransitionOnAction ston = new ScreenTransitionOnAction(nextMenu);

    // Add some observers to the actions
    sah.addOnCompletedHandler(new ActionObserver() {
            public void onCompleted() {
                stoff.start();
            }
        });
    stoff.addOnCompletedHandler(new ActionObserver() {
            public void onCompleted() {
                ston.start();
            }
        });

    // Start the first action
    sa.start();
}

Таким образом, вам не нужно указыватьпродолжительность SelectedItemAnimationHandler при настройке ScreenTransitionOffHandler.

EDIT: попытался сделать реализацию шаблона Observer более понятной.РЕДАКТИРОВАНИЕ 2: изменен runNow (действие) на action.start ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...