Дек
20

AndEngine. Скелет игры

logo_100

Опытным путём я пришёл к следующей структуре игры на AndEngine.

В игре я делаю одну главную сцену MainState и много других сцен — с игрой, с выбором уровней, с экраном Game Over, Level Up, с главным экраном, экраном паузы и т.д.

Все сцены добавлены в Главную Сцену. Остаётся только включать / выключать неактивные в данный момент сцены.

game_struc1

Главная Сцена также рассылает в дочерние сцены нажатия на экран или нажатия кнопок. Но только в активные в данный момент Сцены!

Чтобы не запутаться, что нужно показать, а что спрятать на Главной Сцене, и в каком состоянии сейчас вообще игра находится, я использую переменную GAME_STATE и создаю константы.

Например:

public static final int STATE_MAIN_MENU = 0;
public static final int STATE_GAME_RUNNED = 1;
public static final int STATE_LEVELMAP = 2;
public static final int STATE_STAGE_SELECT = 3;

Сцены, которые явно не управляются с Главной Сцены, я добавляю в другие сцены. Например, сцены, которые используются только во время игры, логично добавить в Сцену с игрой. Таким образом, пряча Сцену с игрой, все вложенные сцены также прячутся.

Важно помнить, что Сцену нужно не просто делать невидимой, когда прячем её, но и "выключать" её из обработки движком. Вот так:

public void Hide() {
	setVisible(false);
	setIgnoreUpdate(true); //<--
}

Вот часть кода из моей игры (Главная Сцена), где я рассылаю нажатия в Сцены:

@Override
public boolean onSceneTouchEvent(TouchEvent pSceneTouchEvent) {
	switch (_StateOfGame)
	{
		case STATE_GAME_RUNNED:
		_GameState.onSceneTouchEvent(pSceneTouchEvent);
		break;

		case STATE_LEVELMAP:
			switch (CommonValues.StageNum) {
			case 0:
				_Stage1_LevelMap_Scene.onSceneTouchEvent(pSceneTouchEvent);
				break;
			case 1:
				_Stage2_LevelMap_Scene.onSceneTouchEvent(pSceneTouchEvent);
				break;
			}
			break;
		case STATE_STAGE_SELECT:
			_StageSelect_Scene.onSceneTouchEvent(pSceneTouchEvent);
			break;
	}
	return true;
}

А вот часть кода из Игровой Сцены:

@Override
public boolean onSceneTouchEvent(TouchEvent pSceneTouchEvent) {
	if (_HUD_Scene.isVisible()) _HUD_Scene.onSceneTouchEvent(pSceneTouchEvent);
	if (pSceneTouchEvent.getAction() == MotionEvent.ACTION_DOWN)
	{
		switch (_StateOfGame)
		{
			case STATE_WAIT_FOR_CLICK_TO_START_LEVEL:
				setIgnoreUpdate(false);
				SfxAssets.press_btn_sfx.play();
				StartLevel();
				break;
			case STATE_LEVEL_RUNNED:
				_player.Jump();
				break;
			case STATE_LEVELUP:
				_LevelUp_Scene.DoTouch();
				break;
		}
	}
	return super.onSceneTouchEvent(pSceneTouchEvent);
}

Ну вообщем, как-то так.




5 коммент. к записи “AndEngine. Скелет игры”

  • А почему бы не использовать переменную, где бы хранилась текущая сцена?

    Не было бы такого объема дублежа кода...

    Так же вопрос: спрайты нормально нажатия таким образом отрабатывают?

    • Ну мне так удобнее. Ведь одновременно могут быть покзаны несколько сцен — допустим выбор уровней, сверху ещё кнопки типа «Назад» или «Настройки» и сверху еще сцена с рекламным баннером. Во все эти активные сцены нужно отсылать нажатия.

      А спрайты — да, нормально отрабатывают нажатия.

  • Не мог бы ты поподробнее рассказать про самое интересное — переключение сцен? Я сейчас при переключении просто пересоздаю mainScene, в которой все остальные запиханы сцены. Но через 15-20 переключений — белый экран. Если делать hide/show как у тебя в коде, то перестают работать нажатия почему-то при возвращении в предыдущую сцену и к каждой сцене еще надо делать метод, где все ресетится к дефолтным значениям и спрайты и переменные?

    • А видео смотрел? Там я все рассказал 🙂

      И да — в Show можно запихнуть инициализацию всех позиций и состояний объектов, как тебе нужно

Прокомментировать



ЗАДАЙ СВОЙ ВОПРОС