Заготовка для флеш-игры или как сделать себе приятно :)

10.10.2010, автор Stormit, рубрики: ActionScript

Раньше я считал флеш-игру сделанной, когда в неё можно было начать играть, нажав Ctrl+Enter во флеше. И почему-то я не учитывал что нужно ещё сделать странички с заставкой, главным меню, настройками и т.д. Хотя часто этот процесс может отнять несколько дополнительных дней. А ещё обиднее, если эти дни не учитывались при оценке стоимости игры. Вообщем, каждый раз к самой игре нужно разрабатывать ещё и саму оболочку-интерфейс. Со временем это становится неинтересно и хочется как-то использовать свои предыдущие наработки. Можно взять свою предыдущую работу, выкинуть оттуда всё лишнее и на тебе - интерфейс готов. Чтобы даже на это не тратить время, полезно иметь под рукой прототип интерфейса-оболочки для flash-игры.

Я просто выложу исходник и поясню как там всё работает. Это первый код на AS3, опубликованный здесь мною.  Статья также будет полезной тем кто хочет перейти на 3-ю версию ActionScript, но ещё не сделал этого. Сам пример и ниже пояснения к нему:

Код писался во FlashDevelop, компиляция при помощи FlexSDK. Вся графика зашита в SWC библиотеки, которые встраиваются в проект.

Тем кто не понял что я только что написал, дальше небольшой ликбез в помощь:

Вводная

Так получилось, что редактор кода во флеше (Flash IDE) очень убогий. Для меня загадка почему Adobe не придаёт этому большого значения. Возможно чтобы люди покупали ещё и Flash Builder. Так или иначе, большинство опытных программистов пишут ActionScript код во внешних редакторах (используя кучу возможностей: шаблоны кода, автоподсказки и автозавершение кода, генерация кода, рефакторинг и многое другое), а Flash используется только для рисования и анимации, а иногда, вообще обходятся без него.
Мне кажется что FlashDevelop - самый простой и удобный редактор для создания AS3 проектов. Возможны несколько режимов работы во FlashDevelop:

  1.  Вы пишете в FD только код, а флешку компилируете во Flash IDE (так называют наш любимый Adobe Flash) - это самый простой способ, который требует минимум изменений в своём сознании. Вся графика остаётся во FLA-файле.
  2. Всё - и написание кода, и компиляция - делается в FD. Но для этого нужно дополнительно скачать FlexSDK, Java и Debug Flash Player (чтобы наблюдать trace и сообщения об ошибках). Графику в этом случае удобно упаковывать в SWC-библиотеку (галочка выставляется во флеше в Publish Settings). Потом эта библиотека подключается в проект в FD и вы можете использовать всё что нарисовали.

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

Какой бы режим вы не выбрали, вам теперь будет на порядок легче создавать AS3 проекты, так как FlashDevelop будет делать за вас большую часть вашей работы.

По сути дела

В проекте 2 SWC-библиотеки: одна содержит графику интерфейса, другая нужна для графики самой игры.
Я предпочитаю такой подход к работе с графикой: для любого значимого объекта создаётся отдельный класс, а графика создаётся внутри него через оператор new (таким образом я могу расширять мой класс от любого другого, а не только от Sprite или MovieClip).

Фактически весь этот шаблон строится на одном классе PageManager, который управляет отображением страниц и событий PageEvent, которое хранит информацию о запрашиваемой странице. Все классы страниц расширяют общий для них класс BasePage.

Я сделал стандартный набор страниц. которые обычно вставляют во флеш-игрушки: Меню, Инструкции, Настройки, Таблица рекордов и Авторы.

Чтобы добавить свои страницы, вам нужно сделать следующее:

  1. Создать во флеше клип с графикой для вашей страницы (в файле lib/pageUI.fla) и выставить в свойствах ему экспортный класс, указав базовым классом flash.display.Sprite - так меньше памяти расходуется.
  2. Создать класс страницы, расширив BasePage.
  3. “Зарегистрировать” страницу методом pageManager.register(). Таким образом он узнает об этой странице и подпишется на её внутренние события. У меня в примере регистрация происходит в классе Main

Переключить страницу можно двумя способами: pageManager.showPage(pageClass:Class) - если у вас есть ссылка на объект PageManager или разослав событие PageEvent.NEED_PAGE из класса страницы (в примере переключение так и работает).

Смена страниц  происходит не моментально, а плавно. Если хотите изменить, перепишите методы show() и hide() в классах страниц (или измените в базовом классе). Важно только знать, что после появления или скрытия страница рассылает соответствующее событие. Например, если использовать TweenLite, то переход может быть типа того:

public function show():void { 
        visual.alpha = 0;
        TweenLite.to(visual, 1, {alpha:1, onComplete:function():void{dispatchEvent(new PageEvent(PageEvent.SHOW_COMPLETE))}});
}

Если же какие-то страницы вам не нужны, просто не регистрируйте их и удалите соответствующие классы и клипы.

Страница GamePage - это по сути контейнер для самой игры. Пихайте её сюда и проверяйте как работает.

Для тех кому влом переходить на сторонний редактор, в папке src лежит InterfaceAS3.fla. В нём тоже можно компилировать, правда без прелоадера.

Download: Flash game interface AS3  Flash game interface AS3 (100.8 KB, 3,478 hits)

Интересно на 56%

(67) Хитрых на тему «Заготовка для флеш-игры или как сделать себе приятно :)»

  1. InspiritGames

    Круто, вселенский разум существует. Сейчас сделали прототип игрушки, чтобы протестить моентизацию как раз добрались до менюшек и тут бах, новый пост про менюшки в rss пришел.

  2. Minos

    В посленей версии FD не требует установка дебаг версии плеера, он идет с IDE.
    Нужно еще отметить, через FlexSDK и подключение SWC библиотек компиляция проходит быстрее.

  3. Zarkua

    “Со временем это становится неинтересно”
    Помоему уникальные менюшки, заточенные под игру создавать гораздо интересней.
    Ну конечно если вырабатывать свой узнаваемый стиль это ок, но просто так смиряться с однобразностью меню своих игр не хотел бы.

  4. Klerick

    спасибо, меня этот вопрос очень интересовал! :)
    правда, после слов “По сути дела” я почти ничего не понял… но и Москва не сразу строилась)))))

  5. Bocap

    Спасибо. Вы, как-то, давно не писали.

  6. danyy

    Спасибо

  7. Alxs

    Приветствую Денис! С возвращением. Приятно видеть тебя с новым постом на твоём замечательном блоге. Дерзай далее не пропадай… :) За статейку спасибо, многим начинающим будет полезно…

  8. cot45

    У меня вопрос по коду - почему в функции hideCompleteHandler нужная страница всегда добавляется addChild(newPage); при этом removeChild не вызывается нигде вроде(закомментирована эта строка). Получается тогда одна и та же страница может быть добавлена много раз на сцену или нет?

  9. Stormit

    to Zarkua
    Речь идёт о шаблоне кода, а графику мне и самому приятно новую делать. Просто теперь достаточно перерисовать фон и графику кнопок.

    to cot45
    при многократном вызове addChild не создаются новые копии страницы, просто текущая перезаписывается каждый раз в список отображения PageManager. Можно раскомментировать ту строку, но тогда появляется небольшой баг с кнопками - они могут зависнуть в сосноянии _over (клип с кнопками исчезает с экрана и событие MOUSE_OVER для кнопки не вызывается). А так страницы висят всегда, но с нулевой прозрачностью или с visible=false

  10. FRend

    Да, узнаваемый стиль меню это здорово) Особенно если игр выходит немало…

  11. fedoz

    Здорово! Так держать!

  12. fedoz

    Скажите, как Вам удалось получить в папке src Вашего проекта файл .fla? У меня есть сделанная в FD игра и мне хотелось бы запихнуть её в Вашу заготовку. Подскажите, пожалуйста, как это совершить?

  13. Stormit

    Создал фла-файл во флеше и сохранил его в папке src.
    Чтобы запихнуть вашу игру в этот интерфейс, скопируйте ваши исходники в папку src (если есть файлы с одинаковыми именами, их нужно переименовать) и создай объект твоей игры (скорее всего это будет переименованный класс Main)

  14. fedoz

    Спасибо!
    Все работает, кроме того, что параметр rotationX не работает в игрульке. То-есть если даже в trace выводить rotationX то программа дальше этой строчки не выполняется. Не сталкивались с такой проблемой раньше?

  15. Dan4ez

    С возвращением!

  16. hitab

    Приятно видеть новые записи, тем более на AS3 :). А я делаю почти так же), только за основу взят этот урок:
    http://active.tutsplus.com/tutorials/workflow/handling-screen-architecture-the-painless-way/

  17. 1g0rrr

    А почему проект настроен под 9-й плеер?

  18. 1g0rrr

    Еще я обратил внимание, что импорт производится для каждого класса отдельно:
    import pages.GamePage;
    import pages.AuthorsPage;

    Вы каждый импорт вручную прописывали, или ФД у Вас как-то настроен, что дописывает импорты автоматом?

  19. Stormit

    Наверное по умолчанию под 9-ку было. Разве это имеет значение? Наоборот - совместимость со старыми плеерами выше.
    А FD на то и нужен чтобы делать рутинную часть работы за меня - он сам импорт прописывает, без какой-либо предварительной настройки. Просто набираете new SomeClass, выбираете класс из предложенного списка и всё прописывается автоматом (даже для пользовательских классов)

  20. yar44

    Добрый день! Спасибо огромное за ваши ценные советы!
    Есть вопрос: можно ли через опции в меню регулировать fps?

  21. Stormit

    Можно задать framerate перед компиляцией, можно потом программно менять его через stage.frameRate, а fps - это показатель того, насколько процессор справляется с расчётами и отрисовкой. FPS нельзя контролировать напрямую, можно повышать только оптимизируя код и графику, .

  22. yar44

    Cпасибо!

  23. 1g0rrr

    Еще вопрос, а почему у вас в PageManager.as переменная _currentPage - начинается с подчёркивания (как я понял, из-за того, что приватная), а newPage - без подчёркивания, хотя тоже приватная? Где вообще можно почитать про именования переменных и вообще про хороший стиль кодирования на as3?

  24. Stormit

    Это потому, что раньше я использовал приватные переменные, а сейчас стараюсь больше использовать protected. Ну и соответственно правил этот класс несколько раз.

  25. Lexin

    По поводу стандартов кодирования:
    http://opensource.adobe.com/wiki/display/flexsdk/Coding+Conventions

  26. levati

    Отрадно, что записи на Хитри стали появляться, но уровень изложения уже где-то ближе к середине, а не для новичка. Особенно в скриптинге на AS3.

    Скачал FD, установил, разбираюсь… но многое ещё не понятно. Судя по отзывам - не мне одному. Есть ли в будущем идея мануала, или видео подкаста по теме?

  27. Stormit

    Ну мы все растём потихоньку и на AS3 переходить как-то нужно.
    Соответственно и уровень материала немного изменился. Я как можно меньше хочу использовать терминологию ООП чтобы не пугать людей, но тем кто решил перейти с AS1 на AS3 нужно догнать базовые принципы - тогда мы сможем говорить на одном языке :)
    На самом деле сложного тут ничего нет. Поставьте себе цель каждый день создавать новый тестовый проект во FlashDevelop и делать что-то простое - trace() или символ из библиотеки на сцену перетянуть. Главное каждый день делать это с нуля. Через неделю у вас будет гораздо меньше вопросов.
    Профессионалы не те кто хорошо учился, а те - кто написал кучу кода - у них это уже в крови.

  28. dedsky

    Отлично, но рыба не полная. Нужен еще звук, таймер, что там еще..

  29. einsof

    Изначально изучал AS3 + FlashDevelop, но все равно читал ваш блог за большое количество вкусностей.
    Очень позитивно видеть новенькое на AS3. Тем более расширит круг ваших читателей.

    Успехов вам! И спасибо за заготовку!

  30. web-moder

    отличная статья
    но у меня возникла проблемка не получается открыть InterfaceAS3.fla и swc файлы
    подскажите в чем проблема
    .З.Ы. может через другие програмки

  31. Stormit

    FLA-файл в версии Adobe Flash CS5, а SWC-файл открывать не нужно, его нужно подключать в проект как библиотеку и использовать в коде его содержимое

  32. web-moder

    ясно спасибо

  33. Александр

    Добрый день.

    При компиляции в строгом режиме ( CS5 portable) следующей строки

    pageManager.registerPage(new MenuPage(new MenuComponent()));

    выдало ошибку

    \InterfaceAS3\src\Main.as, строка 31 1180: Вызов предположительно неопределенного метода MenuComponent.
    и аналогичные ошибки до 36 строки…

    Я не смог найти класс MenuComponent во вложенном архиве. Помогите разобраться:)

    ps Я пока только изучаю AS3 вместе с Зоопарком Колина Мука ( 200 страниц:)), поэтому и такие вопросы:) Спасибо1

  34. Варус

    А как в вашу болванку запихнуть игру сделанную в сs4 или cs5???? может кто-нить подробнее объяснить… я что то не очень понял как правильно
    это сделать …

  35. Игорь

    Добрый день.
    Когда использовал только flash IDE я помещал клип в библиотеку, например HeavyTank и писал соответствующий клипу класс HeavyTank, где размещалась вся нужная мне функциональность.
    Попробовал пользоваться указанной здесь связкой FlashDevelop + Flash IDE (для рисования). После того как я упаковал графику в swc библиотеку встает вопрос о том как в FD к данному клипу дописать нужную мне функциональность?

  36. Игорь

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

  37. Stormit

    В том то и дело что расширять клип здесь не нужно.
    Вы создаёте свою структуру классов (которые можно наследовать не от MovieClip, а как вам нравится). А сам клип с графикой вы передаёте этим классам в конструктор. Например если в SWC есть клип мячика, которому вы в библиотеке задали экспортный класс BallVisual, то в коде его можно использовать примерно так:

    var ballVisual:Sprite = new BallVisual();
    addChild(ballVisual);
    var ball:Ball = new Ball(ballVisual);
    

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

  38. Игорь

    Спасибо! Очень здорово то, что Вы делаете!

  39. Страга

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

  40. Андрей

    Добрый вечер! Stormit мог бы ты описать чуть подробнее как вставить игру в данный болванку или можешь ответить на два вопроса: Графику игры нужно помещать во game.fla?
    И куда помещать весь функционал игры?(GamePage или в Main или вообще лучше создать новый класс)
    Может кто-нибудь уже разобрался с этим вопрос … помогите пожалуйста…

  41. Stormit

    Графику для игры можно поместить как в эту же библиотеку (для экономии если графика в игре и интерфейсе одинаковая) либо в отдельный SWC файл (проэкт можно подключать сколько угодно библиотек).
    Саму игру нужно помещать в класс GamePage. Вернее создавать здесь объект основного класса игры и аттачить его к странице. Если ты сделал игру отдельным проектом, то это будет класс Main (по умолчанию) - просто переименуй его, например, в Game, добавь все классы игры в проект с интерфейсом и в классе GamePage напиши:
    var game:Game = new Game();
    _visual.addChild(game);

  42. Андрей

    Stormit спасибо за ответ!!! у меня еще один вопрос…. ты написал следущее…
    Stormit:”добавь все классы игры в проект с интерфейсом…”
    ты имел ввиду добавить в pageUI.fla ? или я что-то не правильно понял)).

  43. Stormit

    нет, я имел ввиду проект на FlashDevelop
    Если компилируешь во флеше, то скопируй классы игры в папку, где лежит фла-файл. Возможно придётся подкорректировать пакеты у классов игры.

  44. Андрей

    спасибо за ответ!!!
    запихнул основной класс своей игры Game в консруктор класса GamePage вот так:
    var game:Game = new Game();
    _visual.addChild(game);
    Затем подключил свою графику через swc-библиотеку… к основному fla-файлу заготовки.
    Но у меня стали вылезать вот такие ошибки:
    1120: Обращение несуществующего свойства startText. и таких 16 еще ошибок
    только с другими свойствами..
    Не могу понять как их исправить? Подскажите пожалуйста что не так делаю…

  45. Max

    Здравствуйте. Подскажите пожалуйста книги, для начинающего разработчика flash игр.И какую IDE стоит использовать, при разработке flash игр?
    Спасибо.

  46. Alex

    Max,
    Колин Мук, Колин Мук и еще раз Колин Мук. а после этого уже читать про флэш и остальное.

  47. Victor

    Всем привет!
    Я тоже мучался вопросом как сделать навигацию между разделами в игре.
    И пришел к такому варианту: меню, таблица с оками, уровень игры - это классы (наследуемые от Sprite) , которые имеют интерфейс IModule. Этот интерфейс предполагает два метода: удаление со сцены, добавление на сцену спрайта с модулем.
    А для выбора модуля использовал метод фабрики.
    Получился своеообразный движок, который можно использовать в других играх.

  48. Nikolay S.

    Спасибо за статью и исходники. Жаль только комментариев в них нет. Ну да ничего, сами допишем. :)

  49. Nikolay S.

    Хм, получается у вас все экраны всегда висят в памяти (невидимые, кроме текущего)? А как же экономия памяти?

  50. Саня

    скажите пожалуйста вот такая ситуация.
    В fla файле у меня накидана сцена из объектов (объект с вложенми клиами с именами), каждый обект имеет export в созданный мой класс, когда я компилю во Flash то у меня все отрабатывает и вызываются конструкторы каждого накиданного мной на сцену объекта.
    Если запускаю во Flashdevelop (предворительно я все в swc компилю по флеш) то конструкторы не вызываются как быть?

  51. Саня

    Так же при компиляции в Flashdevelop выдает ошибку в классе где я расширяю объект клипа Export том , то что не видет объявленных в объекте других мувиков, видимо се из за того что при компиле swc что то не так((

  52. Жень Шень

    Спасибо за чудесный сайт.
    Но по данному уроку есть замечания: если запустить симуляцию загрузки, то прелоадер появится (и собственно начнет показывать) с 75%. Даже если вынести отдельно прелоадер в свою SWC-библиотеку, то показывать он начнет с 45%. Но стоит загрузить в страницы побольше графики и показатель снова устремится к 78-85%%. То есть прелоадер организован так, что он ждет подгружения всего контента и не хочет работать (отображать загрузку) с нуля.
    Печально наблюдать белый экран в течениее этой загрузки. Если можно, прокоментируйте ситуацию, а может быть предложите выход из данной ситуации.
    Спасибо

  53. Stormit

    Это стандартный прелоадер, который генерирует FlashDevelop - всё должно работать. Если компилировать во флеше, то он не работает (у меня). Я весь AS3 код пишу и компилирую во FlashDevelop, версию для флеша я выложил только для тех, кто ещё не слез с Flash IDE.

  54. zaynyatyi

    @Жень Шень код Preloader.as не менялся?

  55. Жень Шень

    Нет, не менял.
    Мне кажется собака зарыта здесь:
    private function startup():void {
    // hide loader
    removeChild(visual);
    var mainClass:Class = getDefinitionByName(”Main”) as Class;
    addChild(new mainClass() as DisplayObject);
    }
    Но, даже если Main-у убрать галку в “Ехпорт в 1-й кадр”, майн все равно будет загружаться с прелоадером.
    Да, попробуйте предложеный авторский код скомпилировать и протестить с имитацией загрузки. Я не думаю, что прелоадер начнет отображаться с нуля.
    В настоящее время я поступаю так:
    - грузится прелоадер в первом кадре. Весь контент (классы в либе) со снытой галкой (грузятся не в пермом кадре).
    - При полной загрузке переходят в 3 кадр. (Во втором стоит принудительный возврат на первый кадр - вдруг кто-то нетерпеливый нажмет ЭНТЕР)
    - В третьем кадре лежит контейнер с классом загрузки всего остального.
    Но это совсем не как в предложеном уроке, где можно обходиться одним FD.
    Посему и спрашиваю, так как предложеный подход очень понравился.

  56. zaynyatyi

    Дело в том, что я использую подобный код, с основой FD’шного тимплейта. Вес приложения около 800 кб. Грузится нормально, отчет с 0% (не считая времени загрузкт прелоадера).
    Просто раньше напарывался на косяк подобный вашему изза того, что явно указывал тип var mainClass:MyClass = getDefinitionByName(”Main”) as MyClass;
    в этом случае да, майн будет загружаться с прелоадером.
    сейчас у меня
    var mainClass:* = getDefinitionByName(”Main”);
    Пишу на чистом АС3, поэтому с кадрами не работаю, забыл их как страшный сон, равно как и сам Flash как среду.
    getDefinitionByName(”Main”) не загружает класс вместе с прелоадером.

  57. zaynyatyi

    Может покажете свой код, да всё и прояснится? На pastebin можно выложить для удобочитаемости. Но подход 100% рабочий.

  58. zaynyatyi

    Кстати! Кто использовал данный подход со сторонними прелоадерами (Я про прелоадер из FD)? Например mochimedia, flashgameslicense и прочими? У меня в лоб не заработало, кто как модифицировал код?

  59. Жень Шень

    Привет!
    Разобрался с прелоадером.
    Ситуация следующая:
    - если скомпилировать «пустышку», то есть предложенный автором вариант, то при тестировании в режиме симуляции загрузки прогресс-бар начинает показывать с 43% (выведено в текстовое поле в примере по ссылке http://rghost.ru/6030571). Но, если вложить что-нибудь «тяжелое» (картинку в 3 метра) в какой-нибудь файл основного контента, например в game.swf, то все станен на свои места – прогресс-бар начнет работать с нуля.
    В «пустышке» вес графики прогресс-бара как раз и тянул на 40-50%, и при медленной загрузке, естественно это отразилось на результате.
    Так что все сомнения развеялись. Еще раз спасибо за урок.
    Единственное, что давало ошибку, так это строка:
    addChild(new mainClass() as DisplayObject);
    В моем примере работает в такой редакции:
    addChild(new mainClass());

  60. Nikolay S.

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

  61. ASA

    Ребят, подскажите пожалуйста, я новичек в этой теме - пытаюсь разобраться

    скачал исходники
    компилятор ругается на строки в main.as
    pageManager.registerPage(new MenuPage(new MenuComponent()));
    и еще на остальные подобные строки далее

    пишет “call to a possibly undefined method MenuComponent”
    если исходники рабочие якобы, получается у меня какие-то библиотеки не подключены?

  62. Толик

    Та же самая проблема 1180: Call to a possibly undefined method GameComponent и тд и тп. Помогите понять проблему.

  63. foreground

    Я ради черепашки тутор скачал. А там её и нету…. ууууу.

  64. Valeriy

    Эх, снимите меня с тормоза плз =)
    Пишу во FlashBuilder - импортировал все классы меню, подключил библиотеки из примера - все работает замечательно. Но, нужно еще прелоадер подключить - файл из примера импортирован в проект - а где должен создаваться объект Preloader?

  65. Anna

    Спасибо огромное за пример!) Будет очень интересно разобраться во всем этом)

  66. Aitken

    Добрый вечер, помогите. Хочу засунуть под кнопку Play игру, что-то не выходит, есть index.fla, Main.as, папка Box2D, и movieMonitor. Cпасибо большое!

  67. Создание ООП игры на Alternativa3D – Класс Main | Рецепты по AS3 и AIR

    […] создаем меню игры и выводим его на сцену. Меню взято из блога xitri.com. При первой инициализации игры вызываем функцию […]

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