Cтруктура игры

Июль 16th, 2010 автор: Oleg Antipov

По запросу камрада In-Finity написал статью о том, как я организовываю структуру игры, как осуществляю переходы между менюшками и самой игрой.

Собственно сам пример минимального игрового приложения:

Обычно на главной линейке игра занимает у меня четыре кадра:
разработка flash игр

На первом кадре располагается прелоадер. Я уже здесь писал как его сделать, поэтому не буду повторятся. Единственное отличие заключается в том, то в прелоадер я добавил кнопку Play.

Далее на втором и третьем кадре показываются Лого спонсора и мой Лого. Я делаю на разных кадрах потому, что часто приходится по просьбе спонсора убирать свой Лого :(

На четвёртом кадре лежит мовиклип Game в котором собственно и лежит вся игра.
В тестовом примере в мовиклипе Game расположены клипы главного меню (menuMain), клип меню настроек (mеnuOptions), и клип самой игры (Level). К каждой из этих менюшек привязывается соответствующий класс. Все менюшки лежат на разных слоях чтобы их было удобно редактировать:

разработка flash игр

Обратите внимание я не использую вообще Document Class, т.к. он не особо то и нужен :)
В конструкторе класса Game.as задаётся какая из менюшек будет показана первой. В нашем случае это menuMain:

package main 
{ 
     import flash.display.MovieClip; 
 
     dynamic public class Game extends MovieClip 
	 { 
 
		   public function Game() 
		   {
			    //Показываем главное меню
 				menuMainMC.visible=true;
				menuOptionsMC.visible=false;
				LevelMC.visible=false;
           } 
 
	 }
}

Конечно можно вместо visible=true и visible=false использовать removeChild и addChild, но я считаю это необоснованным геморроем. Кстати хочу обратить внимание что если вы используете в менюшке событие ENTER_FRAME то его слушатель стоит удалять при убирании менюшки с экрана, т.к. даже с visible=false событие ENTER_FRAME будет вызываться.

Далее пишем обработчик для главного меню menuMain.as:

package main 
{ 
     import flash.display.*; 
	 import flash.events.*;
 
     dynamic public class menuMain extends MovieClip 
	 { 
 
			public function menuMain() 
			{ 
				//Вешаем события на кнопки
				buttNewMC.addEventListener(MouseEvent.CLICK, buttNewMC_Click);
				buttOptionsMC.addEventListener(MouseEvent.CLICK, buttOptionsMC_Click);
				buttMoreMC.addEventListener(MouseEvent.CLICK, buttMoreMC_Click);
 
			} 
 
			function buttNewMC_Click(e : MouseEvent):void 
			{
				//Прячем текущее меню, показываем уровень
				visible=false;
				Game(parent).LevelMC.visible=true;
			}
 
			function buttOptionsMC_Click(e : MouseEvent):void 
			{
				//Прячем текущее меню, показываем меню настроек
				visible=false;
				Game(parent).menuOptionsMC.visible=true;
			}
 
			function buttMoreMC_Click(e : MouseEvent):void 
			{
			}
 
	 }
}

Слушатели кликов по кнопкам создаются в конструкторе класса.
Код для меню настроек menuOptions.as:

package main 
{ 
     import flash.display.*; 
	 import flash.events.*;
 
     dynamic public class menuOptions extends MovieClip 
	 { 
 
			public function menuOptions() 
			{ 
			    //Вешаем события на кнопки
				buttBackMC.addEventListener(MouseEvent.CLICK, buttBackMC_Click);
			} 
 
			function buttBackMC_Click(e : MouseEvent):void 
			{
				//Прячем текущее меню, показываем главное меню
				visible=false;
				Game(parent).menuMainMC.visible=true;
			}
	 }
}

Код для самой игры Level.as:

package main 
{ 
     import flash.display.*; 
	 import flash.events.*;
 
     dynamic public class Level extends MovieClip 
	 { 
 
			public function Level() 
			{ 
			    //Вешаем события на кнопки
				buttBackMC.addEventListener(MouseEvent.CLICK, buttBackMC_Click);
			} 
 
			function buttBackMC_Click(e : MouseEvent):void 
			{
				//Прячем текущее меню, показываем главное меню
				visible=false;
				Game(parent).menuMainMC.visible=true;
			}
	 }
}

В классе Level и происходит сама игра. В нём создаются слушатели кнопок, мышки, событие ENTER_FRAME… и понеслась разработка очередного хита )

Исходник проекта можно качнуть здесь: http://www.anegmetex.com/devblog/files/gameStruct.rar

Надеюсь новички вынесут из этого поста что-то полезное :)

Категория: Хитрости

18 Комментариев

  1. Andrew

    Еще неплохой пример структуры
    http://www.emanueleferonato.com/2007/12/22/designing-the-structure-of-a-flash-game/.

    А кодить на таймлайне нехорошо ;)

  2. Andrew

    +
    http://www.emanueleferonato.com/2008/12/17/designing-the-structure-of-a-flash-game-as3-version/

  3. Ant.Karlov

    А вот кстати removeChild() – это очень даже обоснованный «геммор», в кавычках потому что это вовсе не геммор ;)

    Опытным путем было доказано, что removeChild() убирает объект из структуры приложения так, что он не обрабатывается и на него не тратятся ресурсы. А visible = false лишь визуально скрывает объект, но при этом объект по прежнему остается в структуре приложения и получает всякие события. Поэтому я бы рекомендовал всякие меню которые не понадобятся игроку в ближайшее время — вовсе освобождать ;)

    В своих работах я лично использую DocumentClass как точку входа в приложение, а кода в кадрах стараюсь не допускать. И мне кажется это очень удобно, потому что все раздельно и нет путаницы.

  4. Oleg Antipov

    2Ant.Karlov
    Под гемором я подразумевал то, что при addChild не сохраняется старая глубина, и менюшка добавляется на верх. Иногда это не приемлемо т.к. на верху есть вспомогательные мовиклипы для затухания изображения, курсор и т.д. Да иногда и порядок самих менюшек важен (например клип самой игры должен быть всегда под клипом GUI, а поверх них должен быть всегда клип с меню паузы).

    Придётся запоминать эту глубину и порядок менюшки, потом делать addChildAt… а по сути из-за оптимизации 4-5 менюшек, которые всё равно не тормозили. Зачем оптимизировать то, что не тормозит? :cool:

  5. Oleg Antipov

    2Andrew

    Из первого примера switch просто жесть) Не думаю что это очень удобный способ.
    А насчёт таймлайна – там только stop(), ничего криминального.

  6. Andrew

    Ну в любом случае надо как-то переключать состояния.

    Для таймлайна можно использовать addFrameScript

  7. Oleg Antipov

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

  8. Platon

    оффтоп.

    Смотрю, 8биткиллер уже за 20 тыс установок в контакте. Есть какой-никакой доход заметный?

  9. Oleg Antipov

    Заметного дохода особо нет, ну за год на хостинг и домен разве что наверно хватит.. что вообщем то тоже не плохо )

    На самом деле 20к не так много у апитека есть гамесы по 100к+ установок. У моей в день гдето всего 800 геймплеев судя по статистике.

    Ещё возможно щас лето и многие школьники (а это основная ЦА) на каникулах. К сентябрю попробую запилить Toy Tales вконтакт думаю она чуть получше пойдёт (в основном конечно у женской аудитории).

  10. Alxs

    Привет соратнику! Куда пропал? Давно небыло новостей на блоге? Наверно “поуши” в разработке?

  11. Oleg Antipov

    Привет. Ну не так уж и давно ) но сейчас действительно слегка занят новым проектом :)

  12. Alxs

    Ну тогды успехов тебе, с новым проектом! Не теряйся, пиши хоть изредка на блоге…

  13. fra

    как при такой структуре (без аддЧилд) сделать при переходах от меню к меню эффект плавного замещения (альфа текущей менюшки меняется а в провсете видна новая менюшка или новая менюшка наезжает на старую сбоку, т.е. одновременно видны 2 меню)?

  14. Oleg Antipov

    А в чём проблема сделать такое? )

  15. fra

    сложность по моему заключается в том, что порядок самих менюшек предопределен слоями

  16. Oleg Antipov

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

  17. fra

    сори, не асс в этом деле, но “новая менюшка наезжает на старую сбоку, т.е. одновременно видны 2 меню” – делаем твин нового меню на текущий – тогда как меню из нижнего слоя накроет меню из верхнего?

  18. Oleg Antipov

    Ну если старая уезжает или исчезает, то всё ок )

    ну если нужно использовать addChild то вообщем то ведь никто не запрещает, просто вместо изменения visible надо будет делать addChild\removeChild – вот и всё отличие.

Оставить комментарий