Как делалась первая игра. Советы начинающим

Всем Привет. Меня зовут Андрей, и я с детства увлекался видеоиграми. Идея делать флеш игры засела мне в голову пару лет назад, но всё как-то не было времени. Я читал форумы и блоги разработчиков, играл в игры, завёл тетрадку куда записывал свои идеи, но руки как-то не доходили. Оказалось, самое трудное это начать.

Я очень рад, что моя половина разделила моё увлечение и всячески помогала мне в этом, не только советами но и делом.

Эта статья не в коем случае не является 100% руководством к действию, в ней я описываю наш “путь” первой игры. Возможно профи увидят в написанном много глупостей и очевидностей, или знают как реализовать той или иной функционал более изящным методом. Профи, пишите комментарии о ляпах и помогите советом нам, начинающим.

Есть такая поговорка: «Счастье, плохой наблюдательный пункт». Именьно поэтому я решил написать статью с “наблюдательного пункта“ после создания первой игры. Пока ещё свежи воспоминания.

Начало

Чтобы что-то строить, нужно уметь держать в руках инструмент. Глупо забивать гвозди микроскопом, когда удобнее использовать молоток. Первая игра должна быть простой в реализации. Есть готовые движки и библиотеки для создание игр Box2d, Pixel, Push Button Engine, WCK … К некоторым есть подробные гайды даже на русском языке, но сначала я бы рекомендовал изучить основы AS3.
Именно AS3.

Для этого подойдёт книга Рич Шупа и Зевана Россера Колина «Изучаем ActionScript 3.0» или книга Колина Мука «ActionScript 3.0 Для Flash». Она большая, но прочитайте хотя бы первые 6 глав. Ну хотя бы главу про список отображения.
Ещё бы я посоветовал прочитать туториал MJW по созданию игры. Именно на основе его прочтения я и сделал движок для Светлячка. Если у вас проблеы с английским, то гугл переводчик более менее сносно переведёт. Зато вы узнаете много интересного, о том как взаимодействуют объекты и как это описать. Туториал очень подробный, со всеми исходниками. Всего 12 глав, на каждую главу не более часа. И к каждой главе есть отдельные исходники.

Для игры вам нужна Идея. И не просто идея: “ну пусть это будет стрелялка про зомби и кровищи побольше”, а глубоко проработанная идея. Кто герой, какое оружие, как будет развиваться герой от уровня к уровню, сколько будет уровней, какая цель героя, какое управление, сколько уровней, сколько противников, как начинается уровень и как заканчивается… Чем глубже будет проработано, тем лучше вы сможете представить себе структуру игры. Конечно потом в процессе создания можно всё изменять, но имея в голове стуктуру игры(а лучше на бумаге) гораздо проще сделать план разработки и действовать по нему.

Кстати про план, очень полезная штука, если им правильно пользоваться. Чем подробнее план, тем лучше. Распишите все элементы, которые нужно сделать(нарисовать и запрограмировать). И от малого к большому начинайте реализовывать. Так приятно вычёркивать из списка уже сделанное. Если на чём то забуксовали, просто разбейте на более мелкие части.

Код

Мне вообще нравится использовать карандаш и бумагу для планирования. Перед тем как писать код нарисуйте структуру игры. Прелоадер => Главное Меню => Выбор Уровня => Игра => Выигрыш => Игра …

Понятно, что из Главного Меню можно попасть не только на Выбор Уровня, но и на Настройки, а из Выбора Уровня можно попасть назад в Главное Меню. А куда можно попасть из Игры? Очевидно что в Паузу или Выигрыш или Проигрыш. А из Паузы? Нарисуйте всю структуру и связи в ней.

К связям неплохо приписать информацию, которая передаётся в новый элемент. Например из Игры в Выигрыш можно передавать информацию о кол-ве очков, время игры, оставшихся жихнях. А из Выбора Уровня как минимум передаётся информация о выбранном уровне.

В своё время я кучу времени потратил на поиск удобного способа передачи информации между классами. От родителя к сыну и наоборот( от вызывающего класса к вызванному, и наоборот). Например у меня Игра, это класс который вызывается каждый раз с разными параметрами в зависимости от выбранного уровня в Выбор Уровня.

Передать данные в вызванный класс легко:
playScreen = new PlayScreen();
addChild( playScreen );// добавляем класс
playScreen.pusk(false,0);// вызываем в этом классе функцию с передачей данных из родителя
или
playScreen = new PlayScreen();
playScreen.numEnemy = 3; // передаём данные в переменную  numEnemy (она должна быть public)
playScreen.numBonus = 1;// передаём данные в переменную  numBonus
addChild( playScreen );// добавляем клас


А вот наоборот сложнее, вызванный класс не может обратиться к родителю и передать ему данные. Для этого отлично подходит dispatchEvent.
Логика проста:
1)создаётся класс для передачи событий NavigationEvent, наследник Event
package  
{
        import flash.events.Event;
        public class NavigationEvent extends Event 
        {
                public static const WIN:String = "win";
                                
                public function NavigationEvent( type:String )
                {
                        super( type );
                }
        }
}

2)создаётся слушатель события
playScreen.addEventListener( NavigationEvent.WIN, onWin)
3)при наступлении условий для выигрыша в коде класса PlayScreen пишется
dispatchEvent( new NavigationEvent( NavigationEvent.WIN ) );


4)Вуаля, если условия для выигрыша выполняются, срабатывает dispatchEvent и передаёт событие NavigationEvent.WIN, а его слушатель уже вызывает функцию onWin в родителе.
Не обязательно использовать константу в классе NavigationEvent:
public static const WIN:String = "win";

вместо неё можно передавать переменную типа string, об этом подробнее в части про звук.

Старайтесь не тратить много времени на оптимизацию кода, который выполняется разово(например при инициализации меню), но если код используется часто на EventFrame или по таймеру, оптимизируйте его. Я потратил несколько дней на оптимизацию кода меню выборауровней, а потом только подумал — ну стало не 140 строчек кода, а 40. Кто заметит разницу? И наоборот оптимизация часто повторяющегося кода в игре очень заметна. Для отслеживания «пульса» игры используйте счётчик FPS. Например этот. Используя код по ссылке создать класс FPSMemCounter, а в код добавить:
var MyFPSMemCounter : FPSMemCounter  = new FPSMemCounter ();
addChild( MyFPSMemCounter );


Графика

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

Наоборот, использование векторной графики хорошо сказывается на объёме, но плохо на производительности, особенно когда очень много небольших элементов. Мы рисовали графику прямо во флэш.
Совет — флеш автоматически ужимает растровую графику при публикации, поэтому лучше самому настроить параметры публикации иначе на выходе можнополучить графику низкого качества.
Для улучшения производительности с векторной графикой, её можно оптимизировать (Модификация => Фигура => Оптимизация). Неплохо пользоваться cacheAsBitmap = true, тогда ваша векторная графика не будет перерисовываться каждый кадр, что тоже позволит улучшить производительность.

Насчёт рисования я плохой советчик. Здесь уже полно уроков по рисованию. Но вот мои пять копеек: Для рисования лучше использовать планшет Wacom, они конечно стоят дорого, но можно заказать б.у. на e-bay. Если планшета нет, можно обрисовывать контуры рисунка мышкой и подправлять их прямо во флеш. И не забывать про Ctrl+Z.

Звук

Про звук не так много статей. Я использовал Audacity, бесплатная программа для обработки музыки. Она позволяет не только обрезать звук в нужных местах, там есть очень полезные фильтры: удаление шума, затухание звука и нарастание и многие другие, но я пользовался именно этими. Звуки для игры я записывал или на телефон или прямо на микрофон ноутбука.
Звуки кнопок, это звук удара по бамбуковым палкам, звук взрыва, это звук колокола коровы и т.п.
Потом просто применял фильтр от шума, затухание вконце и нарастание в начале. Звук готов.

Конечно, если есть возможность лучше нанимать профессионала, но если нет возможности…

программирование звука — прочитайте тут
Очень удобно управлять звуками создав специальный класс и использовать dispatchEvent для передачи событий в этот класс для проигрывания звуков.
С этим классом удобно использовать кнопки выключения/включения звука по каналам.

FIN
Игра готова? Протестирована на знакомых?
Не забудьте сделать прелоадер. Я с этим мучался 3 дня. Всё работало, но экран прелоадера показывался только с 80%. Перечитав кучу гайдов о том, как сделать прелоадер и перепробывав более 6 методов, перепроверяя код, ловя ошибки я ни к чему не пришёл. Начал по кускам удалять игру и смотреть, что получится. В итоге причина была проста, во «второй кадр», в котором лежит всё, что должно подгружаться при вставке из библиотеки вкладывался только 1 звук, остальные не включались в этот кадр. Это баг или ещё что-то, не знаю. В символе AssetsHolder, в котором лежат все объекты для до загрузки, звуки вложил на разные кадры- сработало. Теперь считает от 1%.

Попытайтесь найти продюсера для своей игры, если не получится (у меня не получилось), прийдётся делать всё самому, без советов.

Я сделал всё не так(из-за чего игра пока не продана), но, полагаю, что нужно было действовать следующим образом:
1)сделать сайт лок для FGL
2)составить хорошее описание на хорошем английском
3)сделать красивый аватар(100*100)
4)подготовить красивые принт скрины игры
5)сделать небольшое видео с лучшими моментами геймплея
6)разослать по спонсорам предложение посмотреть

ps
Возможно, между 5 и 6 пунктом лучше сделать «порку» на форуме, доработать и уже потом показывать?
Повторюсь, я пока не продал игры и этот рассказ с моей колокольни. Саму игру можно посмотреть по ссылке.
Прочитав множество блогов разработчиков я хотел бы тоже преподнести свой небольшой вклад. Надеюсь, информация была полезной и увлекательной.

Комментарии (81)

+1
скууууучнааа))) очевидные советы:

1. за зеленые листики давать очки, за красные отнимать
2. убрать движение экрана влево-вправо
3. убрать мерцание экрана при касании любых листиков
4. добавить хоть какое-то развитие геймплея, чтобы игроки не заснули/закрыли игру через 1 минуту
5. пока что вы наврятли сможете метко попасть в эстетствующих хардкорщиков, так что рекомендую обратить своё внимание на казуальный стиль графики — светло, ярко, радостно, легко. С музыкой — тот же совет.

Удачи!
  • fedos
  • fedos
0
Да я не игру хотел пиарить, но за советы спасибо.
Как статья то? В

2 никому движение не нравится, думал это прибавит объёма

3 я как раз хотел фидбек сделать, что прикосновение с препятствием это плохо.

4 оно постепенно развивается от уровня к уровню, видимо недостаточно быстро

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

Хотя может это модно сейчас. Хз.
  • ryzed
  • ryzed
0
А как?

Например у меня вся логика геймплея в классе Game, который был вызван и добавлен на сцену через главный класс(DocumentClass).
Как вызвать из кода класса Game функцию своего родителя?
Например функцию удаления класса Game со сцены?
0
Храни ссылку на родителя.
var parentLink:DocumentClass;
parentLink.DoSomething();

Как-то так.
Просто непонятно, зачем терять ссылку на родителя, а потом через диспач ее снова искать.
0
вроде бы в первых 6ти главах колина это есть да?))))
0
А я не знаю. Не читал.
0
С событиями гибче — не надо хранить ссылки на родителей.
Рассылаешь сообщения, кому они нужны — получают и делают, что положено.
Зачем потомкам что-то знать о родителях? Они выполняют свою работу и оповещают об изменениях
0
зачем плодить события для каждого действия, когда можно хранить ссылку и обращаться через неё к любому методу/переменной? Такое программирование мне больше по душе. Позволяет расставить всё по полочкам и не держать всё в голове… Ну хотя кто знает. Просто предпологаю.
0
Сделайте одно/группу событие и передавайте параметры.

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

Вообще, лично я считаю, что с опытом программист постигает самый главный дзен: «знать всякие штуки и уметь их НЕ применять» :)
0
согласен) я к такому выводу тоже начал приходить.)
0
Вообще, лично я считаю, что с опытом программист постигает самый главный дзен: «знать всякие штуки и уметь их НЕ применять» :)
:)) +1
0
Именно так.
Однако стараюсь не вдаваться в крайности, поэтому в таком случае юзаю вызов полей-функций (var onWin: Function). И писать мало, и со структурой порядок.
0
хм. Я навичок в ас3 но разве нельзя создать ссылку на родителя и обращатся к её функциям/методам через эту ссылку?
0
Также можно через static методы или синглтоны. А конкретно в этом примере к DocumentClass'у можно обратится через свойство root любого экранного объекта
+1

public class Game
{
                public var owner : DocumentClass;
                
                public function Game(o : DocumentClass)
                {
                        owner = o;
.....
+1
а в самом DocumentClass создаешь экземпляр игры так:
new Game(this);
0
Всем спасибо! Действительно работает.
И гораздо проще чем я делал. В будущем упростит сильно жизнь.

Но зато сделал на диспатче класс звуков. :)
0
воспользуюсь моментом.
когда я делаю так, то при запуске игры почему то все ас3 файлы(весь код игры) загружается в первый кадр, что приводит к тормозам в прелодере.
0
Создавайте новую игру после полной загрузки прелоадером
+1
И еще: не надо указывать явно new Game, а то оно по зависимостям все впихнет в первый кадр. Надо использовать getDefinitionByName. Погугли — в инете есть примеры.
0
Спасибо! То что нужно.
0
Тоже никогда не понимал зачем их в простых случаях используют :)
0
совет: снять с игры ограничение по просмотрам (:
я к примеру продаю вне ФГЛ
  • z3lf
  • z3lf
+1
playScreen.numEnemy == 3;

тут присваиваете? или все таки на равенство проверяете?
  • juice
  • juice
0
Упс, поправил. Конечно присваиваю.
0
Либо ссылки на родителей, либо синглтоны — это самое простое и быстрое.
Event'ы вещь удобная, но весь движок на них строить не стоит, они очень медленные (даже если брать их заменители).
При сильной вложенности и большом количестве объектов еще и управлять всем этим будет сложно.
Я предпочитаю (за редким исключением) чтобы ивенты жили в пределах одного объекта и занимались только этим объектом.
И лучше организовать передачу параметров, меньше объем кода будет (про это уже написали).
+1
Кто-то покажет пример кода в котором тормозило бы из-за событий?
Да они медленнее, но это не те значения которые так уж сильно сказываются. Обычно другие факторы вносят намного большие тормоза.

В треде на флешере довольно много хороших специалистов отписались, и практически все пишут, что если правильно их применять, то ничего плохого в них нет.
+3
довольно много хороших специалистов отписались
О, меня можно уже считать хорошим специалистом — я за ивенты :)
Event'ы вещь удобная
Ивенты вещь не только удобная, но и быстрая и более гибкая чем те-же калбеки. Под быстрой я понимаю, что не медленней вызова функции через указатель (в норм языках это быстро во флеше произвоительность меняется от версии к версии). Это конечно исключает оригинальные ивенты от индийских прогламмистов идущие с самим флешем.
управлять всем этим будет сложно
ЛОЛ. Ивенты как раз упрощают управление. Сложно переключить мозг на писание под ивент-архитектуру, если он уже испорчен другими подходами-парадигмами, но юзать уже написанные и протестированные либы — одно удовольствие.
Я предпочитаю (за редким исключением) чтобы ивенты жили в пределах одного объекта и занимались только этим объектом.
Не удивительно, что после стрельбы из пушки по воробьям ивенты и неудобные и медленные и кучу ненужного кода порождают. Порождают плохой код не подходы, а тот, кто неумело ими пользуется.
— Я понял — тут заговор матерых программистов — они не хотят палить тему с крутостью ивентов, чтоб молодые задрачивались ваще на мегарульном функциональном программировании, которое в изначально полностью ООП-шном АС3 вообще редкостный и изысканнейший изврат.
— И вообще, лично я считаю, что с опытом программист постигает самый главный дзен: «знать всякие штуки и уметь их правильно применять как надо и где надо»: Р — Т.е. понимать, нафига оно вообще надо, а не использовать для спила дерева не пилу, а пилочку для ногтей — а чо, тоже ж можно и дзен типа постигаешь.
— Ивенты дают гибкость. Это главная их особенность.
Есть четко поставленное условие от которого не будет отклонений и нет подходящего фреймвока — писать с нуля и жестко (с прямыми вызовами, кастомными списками обработчиков) будет проще и быстрее.
Нет четкой задачи, условия будут перестраиваться по ходу — уже лучше использовать ивент архитектуру, даже если писать ее с нуля.
— Насчет примеров кода с тормозящими ивентами — та изобразить можно что угодно, причем тормозящее проще. Самый главный фактор, вносящий тормоза — это когда программист тормоз :) — шутка ничего личного и не про кого лично.
— @abyss: юзай ивенты, но пойми для чего они нужны. И тогда ты извлечешь из них только хорошее.
0
Я скажу просто — сколько людей столько мнений и подходов. Раз ты говоришь что ничем не отличается (ну якобы удобнее, но это субъективное наверное мнение), то каждый будет использовать то, что ему удобнее.

А вот пример про пилочку для ногтей в топку.) В корни неверный пример и преувеличенный в сотни раз.

Могу на этом примере лично по своему мнению сказать вот так — Это тоже самое что использовать пилу для сруба дерева, но в отношении эвентов мы её ещё и натачивать будим.)))
0
про пилочку для ногтей ты сам все придумал, я ее ни с чем ни сравнивал, а приводил к фразе «знать всякие штуки и уметь их правильно применять» — там все уместно.

А если в аналогии писать ли жестко на методах без ивентов и с ними (кстати калбек — это одиночный обработчик события, т.е. упрощенный механизм обработки событий), то скорее это так: для спила нескольких деревьев тебе дают или просто пилу или пилу, топор, точило, веревку и бензопилу с бензином.
0
Иногда ивенты очень сильно насасывают — например, главное меню — 5 кнопок, по-хорошему надо чтобы при нажатии на каждую кнопку диспатчилось отдельное событие. Ладно, для 5 еще можно написать, а если их будет 25, 50, 100? Неа, лучше для каждой кнопки сделать публичный метод
setCallback(function, args)
кода будет в разы меньше.

P.S. Использую и ивенты и колбеки, говорить что одно лучше чем другое — глупо, надо выбирать по конкретной ситуации.
0
button1.addEventListener(MouseEvent.CLICK, onButton1Click, false, 0, true);
button2.addEventListener(MouseEvent.CLICK, onButton2Click, false, 0, true);
button3.addEventListener(MouseEvent.CLICK, onButton3Click, false, 0, true);
button4.addEventListener(MouseEvent.CLICK, onButton4Click, false, 0, true);
button5.addEventListener(MouseEvent.CLICK, onButton5Click, false, 0, true);

Не немного сложнее чем setCallback(), не?
+2
хорошо, у вас есть меню выбора уровней — 24 уровня, вы для каждой кнопки будете это писать?
мб, так лучше:
for (var i:int = 0; i < buttons.length; i++) {
    // i - номер уровня
    (buttons[i] as MyButton).setCallback(startLevel, i);
} 
0
А что мешает использовать одного слушателя для всех кнопок и также в цикле повешать его на все?
0
а как аргументы передадите?
или свичем будет потом в слушателе разбирать?
+1
В MyButton добавлю свойство level, которое соответствует номеру вызываемого уровня. В слушателе получу его через (event.target as MyButton).level

Или можно сделать слушателем метод класса и цеплять его, например, в конструкторе тогда у него будет прямой доступ к свойству level
+1
На вкус и цвет.

Вам надо будет плодить классы для разных кнопок. Т.е. для выбора уровня у вас будет класс LevelButton с полем level, для качества отрисовки понадобится класс QualityButton с полем quality. А проще создать класс MyButton который будет иметь метод setCallback() и использовать этот класс повсеместно.

Или можно сделать слушателем метод класса и цеплять его, например, в конструкторе тогда у него будет прямой доступ к свойству level
или это похоже на мой способ, или я чего-то не понял :)
0
Может и похож, я же не знаю, как внутри колбэк цепляется. Я имел ввиду сделать слушателя членом класса. Можно его цеплять и снаружи, например так:
(buttons[i] as MyButton).addEventListener(MouseEvent.CLICK, (buttons[i] as MyButton).onButtonClick, false, 0, true);

А на счет классов, если группа кнопок имеет одинаковое поведение и свойства, например: линейные размеры, одинаковые наборы картинок на каждое состояние, etc. — то не вижу нечего зазорного чтобы выделить их в отдельный классы, а не передавать каждый раз в конструктор множество повторяющихся параметров.
0
Сделал бы почти также, только вместо отдельного свойства для каждой кнопки проверял бы её имя в слушателе, например так:
nameButton = event.target.name;
var myLevel = int(nameButton.charAt(4)+nameButton.charAt(5));// имена lvl_1...lvl_15 например

Но такой способ проще, если делаешь меню в IDE, там даешь инстанс-имена кнопкам и их классы генерирует IDE
0
Ну почему только в IDE. Никто не мешает генерировать осмысленные имена внутри callback фунции и вызывать event с нужным именем.
0
Согласен, можно и так.
0
@qdrj:
(buttons[i] as MyButton).setCallback(startLevel, i);
А ничо что для этого тоже только один класс кнопки подходит с одним обработчиком (в примере не калбэк если тошнить) и чтобы прикрутить обработчик с нецелочисленным параметром надо писать новый класс?
Рановато вам ивенты юзать :)
+1
Ничо, ничо. MyButton — это просто подкласс SimpleButton с новым методом setCallback. Сигнатура метода setCallback:
public function setCallback(callback:Function, ...args)

запись ...args вам понятна?
0
ага щаз — «в интернете кто-то не прав» — разгребайте кашу в своей голове сами. Нет времени и желания разжевывать.
+1
Вот так люди и юзает 100500 евентов а потом удивляются тормозам.
Что мешает повесить один слушатель на само меню (в котором расположены кнопки), а дальше через event.target смотреть какая именно кнопка нажата.
0
молодца! настоящий джедай!
А другие пусть используют ивенты в пределах одного класса и доказывают, что калбеки (которые с некоторым утрированием можно назвать частным случаем ивентов).
0
покаж примерчик с меню!
+3

var menu:Sprite = new Sprite();
addChild(menu);

//btn - это,например, класс присвоенный символу в библиотеке
var btn1 = new btn();
btn1.name = "btn1";
menu.addChild(btn1);

var btn2 = new btn();
btn2.y = 100;
btn2.name = "btn2";
menu.addChild(btn2);

var btn3 = new btn();
btn3.y = 200;
btn3.name = "btn3";
menu.addChild(btn3);

menu.addEventListener(MouseEvent.CLICK, onClick);

function onClick(e:MouseEvent)
{
        trace(e.target.name);
}
0
Зачет!
0
такой же подход юзаем, очень облегчает добавление-удаление функционала
0
Главная проблема ивентов, для меня, не тормоза, а напряжное удаление их при определенных событиях. Да и синхроности с другими ивентами не будет, что может вызвать некоторые проблемы с кодом.
+1
а напряжное удаление их при определенных событиях
Это как? GC достаточно шустро подчищает event объекты.
0
Это только в теории.
0
А что события занимают много памяти?
0
Главная проблема ивентов, для меня, не тормоза, а напряжное удаление их при определенных событиях.

Это каких событиях?

Да и синхроности с другими ивентами не будет, что может вызвать некоторые проблемы с кодом.
События на то и события, что они генерятся не в определенное время. Какие преимущества дают при этом колбеки?
+4
puzzlesea — зачем мешать все в кучу, а потом холиварить?
Каждый все равно будет писать так, как ему удобно. Да и автор, сам решит как ему удобнее.
Не нужно из мухи делать слона. Из всего написанного обсуждать можно только скорость, все остальное — на вкус и цвет.
Здесь все лишь комментарии в конце концов, и дискуссии тут вести не удобно совсем.
+2
Я ничего в кучу не мешал, я ее разгребал.
Скорость чего?
Разработки? — ивенты ее увеличивают если их использовать в общей архитектуре на расширяемых узлах (Вот кнопки как раз оч хороший пример, только если не узколобо лепить к ним единственный обработчик).
Быстродействия? — стандартные ивенты тормозные, для скорости надо писать свои. Свои быстрые насколько оптимально написан их код.
Для кого — вкус и цвет, а для кого сознательный выбор более эффективного средства.
Я не холиварю. Я привожу разумные выводы (на доводы к сожалению места нет — да, неудобно тут с этим), а не домыслы и надуманные куски кода, которыми тут кишит. Разница понятна между убеждениями и выводами. Поэтому я нисколько не холиварю — это делают большинство остальных.
зы: кстати калбэки устаревшая техника со времен когда не было ООП и был такой язык Си без плюс-плюс. И выпиливаются калбэки ООП элементарно, ибо тупо передаем не сслылку на функцию, а объект с нужными интерфейсами, которые дергаются. И это уже кстати гибче и быстрее, т.к. приведения типов не надо — будет дергаться нужный метод с нужным набором параметров. Я могу еще продолжать, но надоело… Все, кому надо услышали и поняли, остальные — юзайте древние приблуды и гордитесь этим.
0
Речь про начинающих. По хорошему в flash много чего нужно переписывать, переделывать и оптимизировать.
Вот только это постепенно нужно делать, а не забивать себе голову с самого начала.
И зря ты так про С. Это язык жив и еще многие новомодные плюшки переживет.
Потому как идеально заменят ассемблер и дает максимум скорости при стандартной разработке.
А на повестке дня у нас как раз слабые системы. Смартфоны, планшеты, приставки, нетбуки.
И ObjectiveC хорошо это доказывает (это совсем не C++).
Вытеснили его только там, где нужен параллелизм + скорость, но там и текущие OOP фавориты тоже в пролете.
Но это уже оффтопик.
0
да развеж я супротив Сей? я про то, что калбэки выпиливаются языком с ООП и это более органично смотрятся. Т.е. с Си калбэки имеют место (ну нет там методов), а с ООП нафик не нужны, ток если не юзать ивенты. Вот с калбеками тут как раз дело вкуса: или использовать старый функциональный подход (никто ж не запрещает) или ООП-ешный.
Вот для начинающего лучше и ориентироваться сразу правильно. Для начала стандартные флешовые поюзать, понять, потом под себя либу сделать.
0
Ок, я в программинге никто чтобы спорить о таких вещах, поэтому попрошу лучше вот что — ссылочку или примеры как до правильного использования твоего способа дойти можешь дать? Просто тока начию постигать… не хочется переучиваться.
+1
ууф. я как-бы в процессе доходил: там почитал, там подумал, там сделал. Поэтому ничего конкретного не могу посоветовать. Для общего представления по вики и прочим можно пошарить по callback, observer pattern, event-driven programming.
Еще в кратце: СОП (событийно ориентированный подход/программирование) позволяет реализовать даже некоторые парадигмы ООП, что актуально для процедурных языков без ООП. Также позволяет избавится от нагромождения select-case в типичной модели состояний системы, просто включая и отключая нужные обработчики событий. Дает большую гибкость для доработки кода — это (как и ООП) оценится когда надо будет переписывать и повторно использовать куски кода от предыдущих проектов.
Рекомендую! :) *зловеще потирает руки: еще одного обратил: Е*
зы: еще можно пошарить по исходникам мочиАПИ — у них своя система ивентов, хотя и недалеко от стандартной флешевой ушла — ленивые они. Но для понимания подойдет. А дальше под свои нужды либу ивентов можно написать или воспользоваться готовой — они есть. Есть либа turbosignals, но она больше для примера как раз того как калбэки заменяются в ООП. И еще она очень быстрая за счет прямых вызовов методов. Но в реале ее неудобно использовать — только посмотреть для обучения. На флешере выкладывали свои наработки люди и еще есть robertpenner/as3-signals — неплохая либа порт на АС3 с пошарпаной Qt.
Как по мне либа as3-signals сильно навороченая, возможности там больше для системного программирования чем для игрового. В большинстве случаев в играх примитивной реализации — событие со списком слушателей (вызываемых калбеками) вполне достаточно.
0
Я собсна как бы и писал, что как по мне евенты дают гибкость и большую универсальность кода. Колбеки можно использовать, когда заранее все известно и топорно.

Кстати евенты и колбеки одна малина — что мешает использовать евент, как колбек


mc.addEventListener(SomeEvent, someFunc);

function someFunc(e:SomeEvent)
{
 //универсально удаляем слушатель без заморочек
 e.currentTarget.removeEventListener(e.type, arguments.callee); 

 doSomething();
}
0
Когда все известно и топорно — лучше использовать прямые вызовы методов. Калбэки тут как еще одна ненужная прослойка.

Да. Вариант калбеков, которые тут приводились — это уже примитивная форма ивент подхода. Более развитая и гибкая, это когда на событие цепляется несколько калбеков. Т.е. по сути тут несли фигню: ивент архитектура использует калбеки в основе, соотв. использование калбеков — уже использование примитивной ивент архитектуры.
0
Полностью согласен. А какие эвенты юзаешь вместо оригинальных?
0
Самописные. Как уже писал, простой реализации событие-список обработчиков для игр хватет. Всяких излишеств типа приоритетов нет. Но всякие удобности — использую. Например иногда надо чтобы обработчик был первым — случается. Ну и так по ходу что возникает — свою либу всегда можно привести к нужному состоянию, а чужую еще разобрать надо.
0
хардкорщик ты)
0
покажите хотя бы трейлер игры чтоли…
мне как начинающему, начинающему, и все никак не начавшему свою первую игру, очень интересно смотреть на первые игры других девелоперов, а у вас на фгл игра закрыта(
0
Это всё моя паранойя, что игру скопируют китайцы. Видимо слишком много форума читал на эту тему, поэтому боязно её открывать в свободный доступ.

Пытался сделать видео, но пока не получается. Как сделаю, тут же добавлю. Проблема в том, что мы путешествуем, а нетбук и старый ноут тормозят при записи. Я попросил друга записать, так что скоро добавлю. Да и на FGL в описании игры видео сильно не хватает. Говорят, спонсоры не любят игры играть, они любят ролики смотреть.
0
А кто/что на фотке?
+1
На фотографии дяденька рисует граффити с надписью «Your Game». Это фотография с фестиваля экстремальных видов спорта 2006 года. К игре отношения не имеет, зато передаёт настрой статьи.
0
Спасибо!
0
На фгл не могу посмотреть и еще ошибочка в статье
«Для отслеживания «пульса» игры используйте счётчик FPS. Например этот (ссылка).»
А ссылки нет :)
0
Мне вот этот нравится: www.lostinactionscript.com/blog/index.php/2008/10/06/as3-swf-profiler/
0
Спасибо, поправил.
Например этот. Используя код по ссылке создать класс FPSMemCounter, а в код своего проекта добавить:
var MyFPSMemCounter : FPSMemCounter  = new FPSMemCounter ();
addChild( MyFPSMemCounter );


+1
отличный пост для начинающих. написно хорошо — читать приятно. плюсую.

согласен с остальными — использование ивентов это спорный момент, особенно для начинающих мне кажется это трудно для восприятия. но тут на помощь им придут комментарии к этому посту и люди поймут в какую сторону копать. так что всё нормально)
+1
Спасибо, я очень доволен количеством и качеством комментариев.

Некоторые слишком сложны пока, но большинство примеров я уже попробовал запрограммировать и они сработали. Думаю ими воспользоваться в следующей игре. Надеюсь эти советы пригодятся не только мне.
0
Опять обсуждение форумного формата получилось.

По аналогии с хабром:
— Теперь я знаю знаю как управлять flashgameblogs, нужно постить советы как программировать (зловещий хохот за кадром) :)
0
неправильные советы :)
+1
Мне никогда не научиться управлять flashgameblogs :(
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.