Форум программистов, компьютерный форум, киберфорум
ActionScript
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
1

Менеджер состояний (Пауза в играх)

05.09.2012, 11:27. Показов 1890. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Набрел на статью "Пишем игровой движок". И вот цитата оттуда:

Менеджер состояний, что следует из названия, позволяет следить за состоянием игры, в котором она сейчас находится. Чтобы прояснить ситуацию, давайте разберем игру. Сначала вы входите в игру и вам показывается логотип создателя или ролик или что-то еще. Давайте назовем это начальным состоянием. Затем вы попадаете в главное меню, где выбираете начало новой игры, сохранение/загрузку игры, изменение настроек или выход. Мы назовем это состоянием главного меню. Затем, после начала новой игры, мы входим в основное состояние игры. Как вы можете заметить, мы должны что-то иметь, что скажет игре, в каком состоянии она находится. Это то, чем занимается менеджер состояний.
Тут можно соорудить что-нибудь вроде:

ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
//Менеджер состояний
public var theGameState:int = 0; //0 - меню; 1 - игра; 2 - ролик;
public function stateManager():void {
    if (theGameState == 0) {
        //Создание главного меню
        var mainMenu:MainMenu = new MainMenu();
        addChild(mainMenu);
    } else if (theGameState == 1) {
        //Состояние игры
    } else if (theGameState == 2) {
        //Состояние ролика
    }
}
Следить за состоянием легко - в ентер фрейм проверять переменную theGameState или же просто повесить изменение состояния на клавишу Esc. Но как в состоянии главного меню сказать программе, чтоб "течение времени в игре" остановилось. Первая мысль была "if (theGameState == 0) {то не выполняем код} else {выполняемый код здесь}" но это ж придется пихать в каждый класс, в каждую функцию. Явно, это не способ. А как это реализовать?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.09.2012, 11:27
Ответы с готовыми решениями:

Менеджер состояний игры
Здраствуйте! Мне необходимо реализовать менеджер состояний, в связи с чем есть вопросы Главный...

Пауза на 7 секунд или пауза до нажатия клавиши
Для загрузчика надо сделать паузу, длящуюся 7 секунд, во время которой, если пользователь нажмет...

Синий экран в онлайн играх, в офлайн играх синего экрана нет
Появляется синий экран в онлайновых играх ...В офлайновых синего экрана нет.Синий экран может...

Синие и черные экраны в браузерных играх, одноклассниках и оффлайн играх
Здравствуйте товарищи. Приключается уже довольно продолжительное время траблы с компом, уже год с...

14
Модератор
2904 / 1763 / 179
Регистрация: 19.02.2011
Сообщений: 6,477
05.09.2012, 11:46 2
Цитата Сообщение от Defake Посмотреть сообщение
в ентер фрейм проверять переменную theGameState
Не дай бог!

Цитата Сообщение от Defake Посмотреть сообщение
повесить изменение состояния на клавишу Esc.
А при чем здесь клавиша?

Цитата Сообщение от Defake Посмотреть сообщение
но это ж придется пихать в каждый класс, в каждую функцию
В каждый класс, которому это необходимо, но не в каждую функцию. Т.е. некий глобальный контроллер запускает метод pause у всех заинтересованных. В вашем случае этот метод будет вызван 3 раза, или даже 1 (только для объектов, связанных с текущим состоянием).
В данном случае возможно стоит применить другой подход. Вычислять текущее время каждый раз, когда это будет актуально. Для этого используем getTimer.
1
214 / 80 / 2
Регистрация: 31.05.2011
Сообщений: 258
05.09.2012, 12:13 3
Фактически при паузе вам необходимо останавливать все звуки, ставить на паузу запущенные эффекты, ставить на паузу все таймеры и (если необходимо) отображать диалог паузы в игре. Для централизованного контроля всех этих штук можно создать сервисы (сервис по контролю над всеми звуками, сервис который контролирует эффекты и т.д.) и подписать их на событие в каком-нить глобальном контейнере, сообщающее нам, что пауза включена (или отключена). После диспетчерезации этого события, все подписанные на него сервисы принимают необходимые меры для обеспечения функционала паузы.
1
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
05.09.2012, 12:19  [ТС] 4
То есть создаем класс StateManager. При создании любых объектов, они добавляются в некий массив, который будет доступен классу StateManager. При изменении состояния класс StateManager отслеживает это и на каждый объект ставит паузу. Так?

ActionScript 3
1
2
3
4
5
if (theGameState == 0) {
  for (var i:int = 0; i < array.length; i++) {
    array[i].stop();
  }
}
Это всё так должно происходить?
0
Модератор
2904 / 1763 / 179
Регистрация: 19.02.2011
Сообщений: 6,477
05.09.2012, 12:42 5
Defake, нет, в этом случае у вас получится большая связанность между различными узлами программы. А каждый модуль должен быть в какой-то степени самодостаточным. Так что все необходимые приготовления должны быть произведены внутри каждого модуля. А т.к. внутри у вас есть ссылки на все интересующие объекты, то нет надобности создавать массивы. Это не касается тех случаев, когда у вас много однотипных объектов, но, думаю, в этом случае у вас массив будет создан по другим причинам
1
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
05.09.2012, 14:09  [ТС] 6
А можно где-нибудь посмотреть на код подобной конструкции? А то опыта очень и очень мало, и на ум мне приходят только вот такие низкоуровневые идеи, которые не очень подходят для решения данной ситуации =(

P.S. А откуда у меня ссылки на все эти объекты? Я до сих пор чтоб обратиться от одного класса к объектам другого использовал либо массивы с контейнерами, либо аргументы
0
Модератор
2904 / 1763 / 179
Регистрация: 19.02.2011
Сообщений: 6,477
06.09.2012, 12:27 7
getTimer возвращает время, которое прошло с момента запуска приложения. Если вы ставите на паузу, начинайте считать время от этого момента и записывайте его в переменную. В дальнейшем рассчеты производите за вычитом значения, записанного в переменную. Записывать в каждом кадре смысла нет (если только вы в каждом кадре не нуждаетесь в этой информации), это достаточно делать по запросу.

Цитата Сообщение от Defake Посмотреть сообщение
А откуда у меня ссылки на все эти объекты?
ActionScript 3
1
var _obj:Object = {};//_obj - ссылка на созданный объект
если необходимо, что бы она была видна в других классах, делайте ее публичной (public). Но еще лучше оставить ее приватной (private), но при этом создать геттеры/сеттеры по необходимости

ActionScript 3
1
2
3
4
5
6
7
private var _obj:Object = {};
public function get obj():Object{//геттер
   return obj;
}
public function set obj(value:Object):void{//сеттер
   _obj = value;
}
1
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
06.09.2012, 13:35  [ТС] 8
TanaTiX, всегда, когда я обращался к объектам таким образом мне писали что-то вроде:

"Доступ к возможно неопределенному свойству CCC класса KKK"
0
Модератор
2904 / 1763 / 179
Регистрация: 19.02.2011
Сообщений: 6,477
06.09.2012, 13:57 9
Defake, значит у вас объект того типа не имел указанного свойства. Покажите пример.
0
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
06.09.2012, 14:19  [ТС] 10
Именно таких примеров сейчас нет. Т.к. я их всегда убирал, чтоб не было ошибок. Но вот что-то похожее:
ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Класс Manager
        public var theGameState:int;
        public function init(e:Event):void {
            removeEventListener(Event.ENTER_FRAME, init, false);
            theGameState = 0;
            var mainMenu:MainMenu = new MainMenu(0);
            addChild(mainMenu);
        }
        public function startGame():void {
            var loca:Location = new Location();
            loca.newLocation("start");
            loca.placeActor("start");
        }
 
/*Класс MainMenu (Функция выполняется после инициализации, так что свойство parent уже должно быть.*/
        private function menu0(e:MouseEvent):void {
            parent.theGameState = 1;
            parent.startGame();
            parent.removeChild(this);
        }
Итог:

MainMenu.as(69): col: 11 Error: Access of possibly undefined property theGameState through a reference with static type flash.displayisplayObjectContainer.
parent.theGameState = 1;

MainMenu.as(70): col: 11 Error: Call to a possibly undefined method startGame through a reference with static type flash.displayisplayObjectContainer.
parent.startGame();
0
Модератор
2904 / 1763 / 179
Регистрация: 19.02.2011
Сообщений: 6,477
06.09.2012, 14:26 11
ActionScript 3
1
parent.removeChild(this);
Во-первых так делать не следует. Что это за объект-камикадзе?
Во-вторых, что возвращает свойство parent? DisplayObjectContainer. А у этого объекта есть свойство theGameState? Нет. И не важно, что оно на самом деле есть (или может быть, упор на "может быть"), компилятор видит тип объекта, смотрит на свойства, к которым пытаются обратиться и те, которые реально есть - и выдает ошибку.
Почитайте про ООП.
0
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
06.09.2012, 14:32  [ТС] 12
А как мне в таком случае из дочернего объекта обратиться к свойству родителя, не используя аргументы?

P.S. Итак психанул и продолжил строить ВиртуальныйЗоопарк по книжечке =D
0
Модератор
2904 / 1763 / 179
Регистрация: 19.02.2011
Сообщений: 6,477
06.09.2012, 16:23 13
Цитата Сообщение от Defake Посмотреть сообщение
А как мне в таком случае из дочернего объекта обратиться к свойству родителя
Никак. Дети не командуют. Точнее технически это не проблема, но так делать не следует.
0
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
06.09.2012, 19:43  [ТС] 14
При определенном событии в дочернем объекте мне нужно, чтобы выполнилась определенная функция в объекте родительском. Как иначе это сделать?
0
Модератор
2904 / 1763 / 179
Регистрация: 19.02.2011
Сообщений: 6,477
06.09.2012, 21:15 15
Подписаться на это событие у дочернего объекта, или из дочернего объекта отправить всплывающее событие, или реализовать подписку с помощью колбэка, или еще пара-тройка способов, возможных и зависящих от реализации.
1
06.09.2012, 21:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.09.2012, 21:15
Помогаю со студенческими работами здесь

машина состояний
Здравствуйте. Подскажите пожалуйста, что почитать про машины состояний,а то ничего дельного...

Поиск в пространстве состояний
Поиск пространств и состояний (в глубину, в ширину,евристический поиск) Поиск в пространстве...

Массив состояний заказа
Добрейшего вечера! Соль задания была в чем - создать массив состояний заказа, создать enum-ы под...

Диаграммы действий и состояний
Я новичок.Кто может объяснить по скайпу, пожалуйста, отпишитесь. Смотрел кучу литературы но так и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru