TowerDefence #1. Структура игры

Самое сложное и страшное практически в любом деле — это начать. А когда начинаешь, то дальше уже все не так страшно и сложно :) С чего же начинаются игры?

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

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

Базовая структура практически любой игры может выглядеть следующим образом:

Базовая структура игры

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

Preloader.as — это общий класс, который можно написать один раз и использовать во всех своих играх. Он отслеживает загрузку флешки и красиво демонстрирует этот процесс нашему игроку. После того как флешка загружена в нем инициализируется наше приложение App.as.

App.as — это точка входа в игру. В этом классе я обычно инициализирую общие игровые параметры, а так же при необходимости выполняю кэширование игровых ресурсов. Этот класс является уникальным для каждой игры, но его принцип работы одинаков для всех игр. Когда все параметры инициализированны и выполнено кэширование необходимых объектов или графики, этот класс создает непосредственно нашу игру Game.as.

Game.as — это ядро игры. В этом классе у меня, как правило, живут и общаются между собой игровые экраны/меню. Так же в этом классе создается и живет ядро игрового мира World.as.

World.as — это фактически игровой движок. В него загружаются и обрабатываются игровые уровни, а значит там живут и взаимодействуют между собой все игровые объекты и обрабатывается игровая логика.

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

Я пока решил пропустить этап создания прелоадера, так как это довольно скучная процедура и начинать с нее не особо интересно. Тем более на данном этапе в игре нет почти никаких ресурсов, поэтому прелоадер мы интегрируем в игру чуть позже. Раз нет пока загрузчика, значит и класса Preloader.as пока тоже не будет, так что начнем с точки входа в нашу игру, с App.as. Но прежде, чем начать, я сделаю отступление и расскажу о том, как мы будем структурировать ресурсы игры и исходники.

Структурирование исходников и ресурсов игры

Мой программисткий опыт показал, что один из самых главных факторов комфортной разработки игр или приложений — это четкая и понятная структура хранения исходников и различных ресурсов. Чтобы к середине разработки игры не возникал жуткий фарш из безумного количества файлов классов и ресурсов, сваленных в одной или нескольких папках, нужно хорошенько думать над именами и аккуратно раскладывать все по папкам. Данное правило относится не только к способу хранения файлов на диске, но и к формированию исходного *.fla.

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

Любой, кто хоть чуть-чуть работал с ООП, знает, что набор из нескольких классов может выполнять какую-то одну задачу, например, будь это небольшой твиннер или движок поиска пути на карте. Как правило, все классы, (основные и вспомогательные) сосредоточенные на выполнении какой-то одной задачи, группируются в один пакет. В AS3 пакет — это всего лишь обычная папка с классами, поэтому для создания пакета нам нужно просто создать папку, например «pathfinder» и положить туда класс, выполняющий поиск пути с вспомогательными для него классами. Пакеты не только облегчают работу с классами, но и решают проблему классов с одинаковыми именами.

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

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

Структура папок игры

Обратите внимание, все исходники заключены в папку com — это нужно делать, следуя стандарту формирования пакетов во избежании случаев повторяющихся имен пакетов и классов. Название этой папки может соотвествовать зоне вашего доменного имени, например если у вас есть сайт в зоне .ru или .net то вы можете в место com использовать эти имена. Далее согласно стандарту все ваши исходные коды должны быть в папке с именем вашего домена, что в будущем позволяет их использовать в других проектах, не нарушая структуры этих проектов. Но пакет towerdefence врядли попадет в какой-то другой проект, поэтому о его имени не переживаем и называем его в честь игры. А вот папку framework следует назвать именем своего доменного имени или ника, так как в будущем она сможет легко кочевать из проекта в проект, в качестве набора инструментов, используемых в разработке, или даже как небольшой собственный движок. Кстати, класс Preloader.as туда попал как раз по той причине, что каждый раз его нет никакого смысла писать, и он будет частью набора инструментов.

Если вы что-то не поняли о формировании имен пакетов и классов или хотите узнать подробнее, то обратитесь к книге Колина Мука, там этот вопрос затрагивается более подробно.

Пишем первый код

Что же, со структурой игры и структурой исходников вроде определились и настало самое время приступить к работе. Первым делом создаем папки в таком порядке, как показано выше. Когда все папки созданы запускаем Adobe Flash и создаем новый ActionScript 3 документ и сохраняем его как TowerDefence.fla в папку Project TowerDefence.

Если вы совсем не писали ранее код для Flash, то не переживайте об этом. Никаких дополнительных редакторов и компиляторов для работы с ресурсами и кодом кроме Flash IDE вам не понадобится. Для новичков все самое необходимое есть в нативном редакторе, даже простой менеджер проекта, с которым мы и будем работать. Чтобы открыть его следуйте меню Window > Other panels > Project.

Менеджер проектов

Перед вами должна появиться такая панель.

Теперь создадим новый проект. Кликните по выпадающему списку Project и выберите пункт New Project. В качестве имени проекта вводим название нашей игры TowerDefence и указываем основную папку Project TowerDefence с нашими исходниками, а после жмем кнопку Create.

Новый проект

Если все сделано правильно, то содержимое окна должно выглядеть примерно так.

Теперь мы можем быстро создавать новые классы и папки (пакеты), а также открывать и редактировать уже существующие, не покидая окна Flash IDE.

Совет: для комфортной работы с проектом во Flash IDE вы можете расставить панели инструментов как на этом скриншоте — 270кб

App.as

Настало время создать точку входа в приложение и написать первый код. Откройте папку towerdefence в панели проекта и нажмите кнопочку создания нового класса в панели проекта. Теперь в поле Class допишите к уже существующему пути название нового класса, чтобы получилось так: com.towerdefence.App и нажмите кнопку Create Class. Новый класс должен появиться в папке towerdefence и тут же открыться в новом окне для редактирования. В будущем все эти действия должны стать для вас привычными действиями создания новых классов.

Теперь необходимо связать наш класс App.as с TowerDefence.fla. Но прежде чем это сделать, давайте изменим код следующим образом:

package com.towerdefence
{
  // Подключаем стандартный класс Sprite
  import flash.display.Sprite;

  // Наследуем от него наш класс
  public class App extends Sprite
  {

    // Initialization:
    public function App()
    {
      trace("Hello world!!1");
    }
  }
}

Это позволит нам тут же проверить работоспособность приложения после того как мы свяжем его с документом.

Переключаемся на вкладку с нашим чистым документом и находим панель Properties. Она должна быть включена по умолчанию, но если вдруг по какой-то причине её нет, то включите её через меню Window. ? на ней в поле class вписываем путь и имя нашего класса: com.towerdefence.App, а так же заодно меняем fps на 35 кадров и размеры документа на 640x480. После этого сохраняем изменения в документе и изменения в классе App.as и жмем ctrl+enter. Если все сделано правильно, то перед вами должно появиться белое окно и в панели output строка "Hello world!!1" — это значит что все работает как нужно и пора приступать к созданию класса Game.as.

Game.as

Для создания класса с игрой мы повторяем все те же самые действия, что и для App.as. Попробуйте сделать это сами, это будет полезной практикой. Только содержимое trace(); в App.as и в Game.as замените на что-то более информативное, например "Application initialized...", "Game initialized...", позже это позволит увидеть в какой последовательности создаются классы.

После того как создали Game.as модифицируем код класса App.as следующим образом:

package com.towerdefence
{
    
  import flash.display.Sprite;

  public class App extends Sprite
  {

    public static const APP_VERSION:String = "TowerDefence 0.1 - Oct 15, 2010";

    // Размер документа по ширине/высоте
    public static const SCR_W:int = 640; 
    public static const SCR_H:int = 480;

    // Середина документа по ширине/высоте
    public static const SCR_WDIV:int = 320; 
    public static const SCR_HDIV:int = 240;
        
    // Vars
    private var _game:Game;
    
    // Initialization:
    public function App()
    {
      trace(APP_VERSION);

      _game = new Game();
      addChild(_game);
    }

  }

}

Обратите внимание, я сразу добавил статические константы в которых содержится параметры нашего документа, позже мы их будем использовать везде в коде, чтобы если вдруг когда-нибудь понадобится изменить эти параметры, нам не пришлось переписывать пол игры под новые размеры :)

?нформация: Все переменные, доступные только внутри класса, всегда должны начинаться с _подчеркивания — так нам будет проще отличать внутренние переменные от глобальных. А все константы всегда пишутся ЗАГЛАВНЫМ?_БУКВАМ? и их содержимое нельзя менять в ходе выполнения программы.

Код выше создает экземпляр класса Game.as, сохраняет ссылку на него в переменной _game и добавляет на сцену внутрь класса App методом addChild(); после чего Game.as становится рабочей частью приложения.

Если все сделано правильно, то после компиляции (ctrl+enter) в окне output должны появится две строки:

TowerDefence 0.1 - Oct 15, 2010
Game initialized...

Домашнее задание

Я решил, что в конце каждого урока буду придумывать небольшое домашнее задание, целью которого будет вносить какие-либо изменения в код и получать требуемый результат. Это поможет вам быстрее понимать что к чему и вносить любые изменения в игру самостоятельно. Его выполнение лежит полностью на вашей совести :) Решение домашнего задания будет обязательно продемонстрировано в следующей части за счет чего вы сможете проверять свои решения.

Сегодняшнее домашнее задание будет достаточно простым: вам необходимо добавить в игру класс World.as так же как мы это сделали с предыдущими двумя классами.

Внимание! В ходе небольшого разбирательства стало известно, что в новой версии Flash CS5 имя World зарезервированно под какой-то еще не документированный системный класс. Поэтому в качестве имени класса для игрового мира следует использовать Universe.as.

Заключение

Это первый вводный урок, который показывает простой принцип создания нового документа и основных классов. Я думаю, что он будет мало интересен опытным разработчикам, но все же без вводного урока никак не обойтись, так что гуру программирования прошу меня извинить :) В последующих частях будет больше упора на создание игры, а не на подробные описания действий.

Ссылка на исходники — CS4, *.zip, 12 кб.

Что дальше?

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

Содержание

  1. Вступление
  2. Структура игры
  3. Карта проходимости
  4. Первый враг
  5. Готовимся к поиску пути
  6. Поиск пути
  7. Редактор уровней
  8. Движение врагов
  9. Первая башня
  10. Кэширование объектов
  11. Полоса жизни
  12. Вражеские волны
  13. Загрузка вражеских волн
  14. Продолжение следует...

 

 

Спасибо. То, что ты делаешь, - очень круто. Для меня flash - это хобби, и благодаря урокам вроде твоих, дождливым осенним вечером можно сесть за компьютер и сделать игру для поднятия настроения:)

Dyrk
17 Октября 2010
— 00:56
#

Ох, братюнь, не думал, что ты с САМОГО начала будешь. Гляди как бы миллиардами клонов не заполонили рынок ибо ОЧЕНЬ детально.
Спасибо за пост и куда дз то показывать?

Zarkua
17 Октября 2010
— 01:10
#

Огромное сасибо за труд.

Димка
17 Октября 2010
— 01:11
#

Антон молодца ;)

Vacsa
17 Октября 2010
— 01:22
#

@Zarkua, начать-то с чего-то нужно. В числе моих читателей как совсем «зеленые» новички, так и матерые профи, чтобы всем было интересно мне прийдется балансировать по серединке.

Рынок и без меня уже переполнен ТоверДефенсами, впрочем этот вопрос мы уже детально обсудили на флешгеймдев.ру — я сделал выводы и упростил программу урока.

Домашку никуда показывать не нужно — это лишь мотиватор для читателей покопаться в исходниках и разобраться что к чему. А так же повод включить мозк и научится немножко фантазировать, а не просто копипастить готовый результат :)

Ant.Karlov
17 Октября 2010
— 01:49
#

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

Regul
17 Октября 2010
— 03:07
#

Не ужели я дождался :) Спасибо Антон. Все здорово. Жду продолжения!!!

Я не робот!
17 Октября 2010
— 08:49
#

Думаю наплыва клонов не будет, если количество уроков будет 10+ и сложность будет нарастать. То к финалу создания игры доберутся только самые стойкие и понимающие.

Жду продолжения. Антон,а ты полную структуру игры себе представляешь уже перед тем как делать?
?ли за основу берешь предыдущие игры(класс для меню, паузы, выбор уровня, подсчёт очков и т.п.).
Мне как раз интересно про структуру узнать :)

Andrey
17 Октября 2010
— 09:27
#

Замечательно. Хорошее начало, для начала:). А то что легко это только +. Насчет клонов - это все ерунда.

WeslomPo
17 Октября 2010
— 11:45
#

Супер!!!!! Хочу дальше!! А можно поинтересовать сколько всего планируется уроков? =)

Руслан
17 Октября 2010
— 12:30
#

При данной структуре проекта, после написания App.as, этот класс установился в качестве главного только с формулировкой towerdefence.App (т.е. без com), соответственно и в самом коде класса пришлось убрать com из строки указания пакета. Почему именно так?

?лья
17 Октября 2010
— 13:10
#

Ох и непростую задачу ты перед собой поставил! Могу лишь пожелать удачи и терпения. Самое сложное для начинающих это правильно зацепить классы друг за друга, чтобы затем игры делались просто и удобно. Насколько я понял - ты решил показать как это делается. Супер!

По поводу клонов - механика игр повторяется в миллионах проектов. Какие из них успешны? Зависит ли успех от открытости технологий? Успели ли надоесть шутеры за почти 20 лет своей истории? Так ли часто новаторские игры успешнее чем клоны? Считаю что делать клон работа адская. Собственно этим сейчас и занимаюсь :D

RaymondGames
17 Октября 2010
— 13:58
#

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

Ant.Karlov
17 Октября 2010
— 15:44
#

@?лья, такая проблема скорее всего возникла потому что TowerDefence.fla сохранен в папку com, а не в папку Project TowerDefence. *.fla докумен должен быть за приделами папки com.

Ant.Karlov
17 Октября 2010
— 15:46
#

@RaymondGames, успешны те клоны, которые по настоящему интересны и увлекательны. Открытость технологий позволяет делать более качественные игры с наименьшими затратами. Шутеры как и игры любого другого жанра бывают разными, поэтому тут на вкус и цвет. В любом случае сделать клон всегда намного проще и возможно выгоднее чем придумать и разработать что-то новое и оригинальное ;)

Ant.Karlov
17 Октября 2010
— 15:51
#

Знаю, что Mining Truck 2 был продан 15 октября. Когда будет релиз? Очень поиграть хочется:)

p0lter
17 Октября 2010
— 16:00
#

Сделать успешный клон ~= придумать новое и оригинальное :D Либо мы о разных вещах говорим. Пример - воркрафт и старкрафт. Два клона от одной компании. Ужели сделать старкрафт было на порядок проще чем придумать...тетрис-реверси?

? возможно я неправильно понимаю слово клон. По мне так все игры внутри одного жанра и со схожей механикой - клон. ? что теперь не делать экшен платформеры? Забросить сайд скроллеры? Забыть о тавер дефенсах??? Ну нет)) А про то что делать клоны проще - очень спорно. В нашей раше допустим очень долго не могли склонировать жанр экшен не смотря на доступность технологий. Видимо не всё так просто?

Вобщем я так понял ты против клонов.

RaymondGames
17 Октября 2010
— 16:14
#

@Ant.Karlov, да, все верно. Спасибо. Перенес fla-файл, поправил в нужных местах записи - все работает. Просто по скриншотам не совсем понятно, где именно должен лежать fla-файл.

?лья
17 Октября 2010
— 16:37
#

Снимаю вопрос, наиграюсь на FGL:)

p0lter
17 Октября 2010
— 16:51
#

Привет! Классный урок!
Тока вот мне лично не понравились имена классов и переменных. )) По моему программерскому опыту... а он исходит из 5го флеша, проходит через си шарп и ас3, я бы посоветовал не использовать сокращения в именах классов и особенно переменных. Все должно называться своими именами и тогда это становится очень прозрачным.

Например SCR_W - лучше называть SCREEN_WIDTH - от этого никто не пострадает - автокомплит все сделает за вас. ?ли например класс App - можно заменить на Main, т.к. это стандарт для вхождение в любую апликацию, и именно с этого класса начинается все.

SuperMan
17 Октября 2010
— 17:36
#

Спасибо, Антон. Я хоть и не новичек и все это знаю и использую, но всегда ж приятно почитать как работают другие, жду продолжения)))

crionuke
17 Октября 2010
— 17:51
#

@RaymondGames, да, похоже ты путаешь понятие клон игры с понятием жанр игры. Клон — это когда новая игра копирует ключевые особенности старой игры. ?гры в одном жанре не могут быть клонами одной игры, так как они могут иметь не только уникальное графическое представление но и оригинальные ключевые особенности которые очень сильно влияют на геймплей и в итоге игры существенно могут отличатся. При этом общая игровая концепция может оставаться прежней, что объединяет разные игры в один жанр. Тут как в кино, есть типичные боивики клоны, а есть очень оригинальные боевики.

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

Я к клонам равнодушен так как просто клоны не несут ничего нового интересного, они скучные. Но если брать готовую игровую концепцию и координально её изменять, то можно получить если не новый жанр, то хотя бы просто отличную игру которая уже не будет клоном ;)

Ant.Karlov
17 Октября 2010
— 17:52
#

@SuperMan, согласен. Но для меня лично сокращение SCR уже давно стало полноценным словом SCREEN и эти константы наиболее часто используемые в коде игры, поэтому для очевидных констант и переменных я использую очевидные сокращения. В остальных случаях название констант пишу полностью. В урок внесу исправления.

А вот на счет Main.as не знал :) Но App.as мне нравится больше не только потому что оно везде в списках отображается в числе первых (согласно алфавиту), но и то, что это имя более емко отражает суть класса нежеле просто Main.as — что главный? Зачем главный? Куда главный? :) Спасибо за замечания!

Ant.Karlov
17 Октября 2010
— 18:17
#

@SuperMan, кстати App.as так же записан в сокращенной форме потому что в нем используются все основные статические константы и к ним приходится часто обращатся в любых других классах и строки:

myButton = new Button(Application.SCREEN_WIDTH_HALF, Application.SCREEN_HEIGHT_HALF);
// Например создание кнопки в центре экрана

— начинают быстро раздражать и мешают читаемости кода. Поэтому использование сокращений и полных имен нужно применять с умом (?МХО).

Ant.Karlov
17 Октября 2010
— 18:21
#

@p0lter, дата релиза игры Mining Truck 2 пока не известна. Но судя по тому как все движется и согласно моим правилам продажи игры — я чувствую, что релиз состоится не раньше ноября.

Ant.Karlov
17 Октября 2010
— 18:24
#

зеленые-презеленые, к тому же блондинки... ну почти :) К чему это я... а, да, хотела сказать СПАС?БО!!! Пока все понятно, даже домашка получилась "с лету". Есть пара вопросов, но это к Муку/Розенцвейгу, а не к Антону (пошла читать).

Ronda
18 Октября 2010
— 05:01
#

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

Dulea
18 Октября 2010
— 10:38
#

Дождались наконец! :) Надеюсь, принцип "главное - начать" будет перенесен на сами уроки и они будут появляться регулярно.

Вопрос не совсем по игре: какой плагин используется для оформления кода в статье?

jarofed
18 Октября 2010
— 12:10
#

Привет! По поводу

/*
myButton = new Button(Application.SCREEN_WIDTH_HALF, Application.SCREEN_HEIGHT_HALF);
// Например создание кнопки в центре экрана
*/

1. Не создаем константы - половина экрана, зачем они? они легко получаются из SCREEN_WIDTH и SCREEN_HEIGHT умножением на 0.5.

2. Создаем функцию которая создает кнопки в нужных месте и вешает им слушатели:

private function createButton(x:Number, y:Number, clickHandler:Function):Button
{
var button:Button = new Button();
button.x = x;
button.y = y;
button.addEventListener(MouseEvent.CLICK, clickHandler);
//здесь можно сделать дофига всего, потому как создание кнопки не ограничивается тока заданием слушателя
addChild(button);
return button;
}

3. В итоге в коде будет нечто типа:

createButton(Application.SCREEN_WIDTH * 0.5, Application.SCREEN_HEIGHT * 0.5. myButtonClickHandler);
//и вот эта функция сокращает сильно код создания кнопок
//вообще функции и сделаны для того что бы избегать повторение кода

SuperMan
18 Октября 2010
— 12:20
#

Наконец мы все дождались :)

Вопрос: при такой организации получается что класс World.as вырастает в очень длинную колбасу, потому что содержит всю логику игры и обработку управлением всех объектов в игре?

shaman4d@gmail.com
18 Октября 2010
— 14:41
#

Ну вот понеслось :) Сколько кодеров столько и вариантов называть переменные функций и их использование не напугайте Антона....

Я не робот!
18 Октября 2010
— 16:01
#

Че-то не получается world.as добавить (((
Пишет: Game.as, Line 10 1136:Incorrect number of arguments. Expected 2.

Вот класс Game.as

package com.towerdefence{
import flash.display.Sprite;

public class Game extends Sprite {
private var _world:World;

public function Game() {
trace("Game initialized...");

_world = new World();
addChild(_world);

}

}

}

вот класс World.as

package com.towerdefence {

import flash.display.Sprite;

public class World extends Sprite{

public function World() {
trace("World initialized...");
}

}

}

pkasha
18 Октября 2010
— 17:52
#

@SuperMan,

> 1. Не создаем константы - половина экрана, зачем они? они легко получаются из SCREEN_WIDTH и SCREEN_HEIGHT умножением на 0.5.

Как правило элементы пользовательского интерфейса рассполагаются где угодно, но только не посередине экрана, а значит помимо получения середины экрана в строке будут и другие различные вычисления чтобы получить нужную позицию. Честно, еще в MT2 я делал точно так же как ты говоришь. За счет чего при создании кнопок и других элементов у меня в коде постоянно дублируется умножение ширины и высоты на .5 — посмотрев на все это я решил, что в следующем проекте обязательно заведу отдельную константу чтобы избежать лишних вычеслений и повысить читаемость кода. Более того 2-3 раза я умудрился забыть поставить точку в .5 при делении ширины или высоты, что в последующем убило 5-10 минут времени на поиск кнопок на экране и на поиск этого бага соответственно :) Когда в строке большая формула расчета выравнивая кнопки относительно чего либо, то недостающей точки можно легко не заметить.

> 2. Создаем функцию которая создает кнопки в нужных месте и вешает им слушатели:

Все правильно. Но поскольку я обычно пишу отдельный класс для кнопок, то вся инициализация кнопок производится в нем согласно указанной разновидности кнопки :)

Ant.Karlov
18 Октября 2010
— 18:07
#

@jarofed, я тоже очень надеюсь, что уроки будут появляться регулярно :)

Для подсветки кода используется SyntaxHighlighter — ссылку на сайт разработчика можно узнать наведя мышку на код и кликнув на кнопку с «вопросиком» в появившейся панели.

Ant.Karlov
18 Октября 2010
— 18:10
#

@shaman4d, переживать не стоит, World.as — это лишь ядро игровой логики, в нем будет выполнятся основной процесс для всех объектов и будут выполнятся только самые важные условия для игровой логики. Логика отдельных объектов не имеющих особого отношения к игровому миру в целом, будет существовать внутри их классов. Представленная структура игры является базовой и она пока не отражает сути всей игры.

Ant.Karlov
18 Октября 2010
— 18:14
#

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

k0t0vich
18 Октября 2010
— 18:19
#

@pkasha, ошибка в 10ой строке класса Game.as, компилятор указывает на то, что при создании класса указано не верное количество параметров. К сожалению 10 строку я в коде заключенного в комментарий я точно определить не могу, как и наличие ошибки на глаз. Можете прислать исходник мне на почту.

Прежде чем компилировать игру, не забывайте сохранять все измененные классы (ctrl+s), у измененных и не сохраненных классов в названии файла (на вкладке) отображается звездочка. Если вы внесли изменения в класс и не сохранили его, то компилироваться будет та версия класса, что находится на диске (то есть от предыдущего сохранения).

Ant.Karlov
18 Октября 2010
— 18:19
#

@k0t0vich, спасибо за совет! Сам я не пишу код во Flash IDE так как давно бы уже убил себя об стену :) В статье написал лишь как можно кодить не имея ничего кроме Flash IDE.

Flash Develop отличная вещь, но нет версии под Mac, поэтому я пользуюсь не менее удобным TextMate.

Ant.Karlov
18 Октября 2010
— 18:22
#

Здравствуйте, Антон.
А как Вы относитесь к различным фрейворкам типа Flixel или PBE? Не легче ли использовать велосипед, изобретенный кем-то другим? Какие их недостатки?

Max D
18 Октября 2010
— 19:36
#

Такая же ошибка, как и у pkasha. Ругается на эти две строчки:

1. _world= new World();
2. addChild(_world);


Line 1 1136: Incorrect number of arguments. Expected 2.

Line 2 1067: Implicit coercion of a value of type World to an unrelated type flash.display:DisplayObject.

World.as аналогичен Game.as - не понимаю в чем ошибка.

dada
18 Октября 2010
— 21:22
#

Уже взял на вооружение часть статьи. Делаю свою первую личную игру и поэтому хочу немного забежать вперед с вопросами. Где ты предполагаешь осуществлять перерисовку элементов? Будет ли это единая перерисовка элементов? Ведь скажем в Game.as могут быть какие-то элементы для перерисовки, ну и понятно, что в World.as тоже много чего будет перерисовываться. Ну и последний вопрос, графика кешируется в App, а передача будет осуществляться дочерний класс в виде параметра в конструктор?

Антон
18 Октября 2010
— 21:33
#

Max D, с Flixel легко можно и так разобраться. В обще там довольно много лишнего. ? для максимальной оптимизации лучше их почистить. Я лично пишу на flixel, начал еще летом, сейчас поднатарел во Flash, хочу свой движок сделать, максимально узкоспециализированный под свой проект, потому что иногда flixel жутко мешает, хотя плюсов у него конечно больше.

WeslomPo
18 Октября 2010
— 22:10
#

@Max D, к сторонним фремворкам я положительно отношусь. Но я считаю, что прежде чем использовать сторонние разработки нужно немного разобраться с тем как все устроено и как работает без каких-либо движков и библиотек.

Ant.Karlov
18 Октября 2010
— 23:38
#

@dada, ну вот. Не такая уж и простая домашняя работа оказалась для некоторых :)

К сожалению я тоже не понимаю в чем может быть ошибка, так как в самом коде что вы мне демонстрируете все верно написано. Пришлите свой исходник мне на почту (адрес есть на странице «Об авторе»). Спасибо!

Ant.Karlov
18 Октября 2010
— 23:50
#

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

В случае с отображением игровой карты и игровых интерфейсов — все делится на слои которые могут перекрывать друг друга. Например для карты будет свой слой, для игровых меню свой, и если вдруг нужно будет открыть игровое меню, то слой содержащий меню окажется над игровой картой и перекроет её. Работая с игровым меню мы будем обрабатывать содержимое слоя в котором находится меню отключая обработку других слоев с элементами. Это если в кратце.

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

Ant.Karlov
18 Октября 2010
— 23:59
#

Я хотел спросить немного не про это, но спасибо, что ответил). По второму вопросу я все понял спасибо. Теперь по первой части, я немного не то хотел спросить, проще говоря, где будет расположен eventListener и eventHandler (для таймера ну или ENTER_FRAME)? Будет это один листенер и хандлер? Заранее спасибо).

Антон
19 Октября 2010
— 00:24
#

@Антон, в своих проектах я обычно делаю два перехватчика ENTER_FRAME, для Game.as и World.as отдельно. Нужно это для того чтобы ставить на паузу игру когда включаем меню и наоборот. Можно конечно делать общий перехватчик на два класса — но мне это не очень нравится так как это немного нарушает целостность классов и делает их взаимосвязанными.

Ant.Karlov
19 Октября 2010
— 01:07
#

Кстати, если заменить имя классы World на другое, то ошибка пропадает. Похоже на то, что класс World уже существует... Как это можно проверить?

pkasha
19 Октября 2010
— 09:45
#

Очень рад появлению серии уроков от великого мастера!! Буду следить и учиться.

p.s. судя по комментариям, многие уже сталкиваются с проблемами, хотя всё наглядно было показано и описано. Представляю, что же будет дальше...
Ребята у кого не получается, то в конце статьи выложены исходники, посмотрите их и сверьте со своими и сразу увидите, где вы ошиблись.

Samana
19 Октября 2010
— 12:10
#

@pkasha, действительно судя по ошибке похоже что класс World уже где-то существует и возникает их конфликт (может быть добавили клип World в библиотеку и сделали его экспорт в AS?). Я добавил в свой код класс World и у меня не возникло никаких проблем. Было бы здорово если кто-нибудь пришлет свои исходники чтобы посмотреть где может быть допущена ошибка.

?сходник для проверки работоспособности программы с World.as — 12 кб.

Ant.Karlov
19 Октября 2010
— 15:24
#

Ant.Karlov, к сожалению, с твоим исходником выдает ту же самую ошибку :) Я думаю, что проблема в версии, у меня стоит CS5 (думаю, что и у других, у кого не работает).
Видимо в CS5-ой версии существует какой-то системный класс World. Но я не нашел никакой документации по этому вопросу.
В любом случае простое переименование с World на Universe решает проблему и все работает.
Единственное, что мне удалось найти, - это чей-то комментарий на форуме:

So Flash CS5 has two new undocumented root classes: World & Joint. I tried the CS5 demo and WCK blew up, eventually traced the problem back to this. If you create a new project and on the timeline:

trace(Joint);
trace(World);

You will see those classes are defined. Very interesting...
Действительно интересно:) Нужно будет активнее поискать информацию об этих классах.
В любом случае, пока что единственное очевидное решение - не использовать имя World.

Dyrk
19 Октября 2010
— 19:54
#

@Dyrk, большое спасибо за комментарий! Это действительно похоже на правду. Мне лично вообще ничего не удалось найти по этому поводу, когда я пытался понять может ли существовать какой-то стандартный класс с таким именем.

В общем прийдется использовать другое название для игрового мира и я думаю, что Universe.as хорошая альтернатива :)

Ant.Karlov
19 Октября 2010
— 20:19
#

Поэтому я его давно назвал GameWorld

?ван
20 Октября 2010
— 06:30
#

Случайно наткнулся на не плохой урок
http://www.guahanweb.com/2009/01/31/tower-defense-in-as3-part-iv/

там же есть и
http://code.guahanweb.com/viewsource/td04/

иван
20 Октября 2010
— 09:08
#

Ну все! Приступаем к написанию клонов! )))

KUSAKA
20 Октября 2010
— 10:29
#

Антон, спасибо большое за запуск цикла уроков!
иван +1, в свое время по нему и пытался написать TD игру + пара других примеров )

LegendMAN
20 Октября 2010
— 11:31
#

Антон, здравствуйте, к сожалению не смог найти вашу контактную информацию на сайте и в интернете, потому пишу сюда.
Если вам интересно предложение о долговременном сотрудничестве, то напишите мне на почту, и я опишу суть предложения подробнее: pvmajev at gmail dot com

Филипп
21 Октября 2010
— 01:25
#

О, спасибо.
А я уже думал ты уже забросил идею с туторами)

Мне как раз нужна игра для рекламы моего новоиспечённого портала, сделаю дефенс. :)

Midnight
21 Октября 2010
— 01:57
#

Филипп, в разделе "Об авторе", в шапке блога, там есть email

WeslomPo
21 Октября 2010
— 15:59
#

Вчера вечером неспешно под кофе и музычку сделал этот урок (и домашнее задание). Теперь с нетерпением ожидаю следующего.

jarofed
22 Октября 2010
— 11:13
#

@KUSAKA: похоже этой осенью будет TD-бум! Главное чтобы в последствии те, кто поторопился выпустить чисто геймплейный продукт не кричал на тех, кто сидел днями доводил игру до совершенства, что мол идеи у них спёрли и все дела)) ДАВАЙТЕ ДЕЛАТЬ КАЧЕСТВЕННЫЕ ?ГРЫ! да и вообще...думаю сейчас планка на TD игры ооочень высока. Если все кто сделают игру по этому тутору запостят её на FGL...выживут только сильнейшие. Так что уважаемые товарищи клоны...успехов!))))

RaymondGames
22 Октября 2010
— 15:24
#

RaymondGames, мало кто преследует цель сделать дефенс по этим урокам, чтобы потом пытаться на нем заработать. Чтобы получить хоть какие-то копейки за игру, нужно сделать ее максимально не похожей на ту, что будет в уроках. Поэтому я не думаю, что появится много клонов. А если и появятся, то сразу и исчезнут.

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

Dyrk
22 Октября 2010
— 17:08
#

Привет Антон. Спасибо за урок. Я как раз занимаюсь в тек. момент ТД темой... Очень кстати... :) Насчёт структуры игр оч. всем советую книгу "The Essential Guide to Flash Games"... Правда на английском. Там как раз разбирается тема написания своего фреймворка для игровых проектов.

Alxs
22 Октября 2010
— 18:29
#

@Alxs, спасибо за подсказку о книге. К сожалению в рамках этого урока я не буду стараться охватить основы создания своего фремворка. Урок больше ориентирован на то, как можно что-то создать на ровном месте.

Ant.Karlov
23 Октября 2010
— 03:46
#

Думаю, что еще больший интерес к той или иной игре будет проявляться, если в ней сделать какие-то дополнительные возможности (например, какие-нибудь бонусы или мини-игры).
Я совсем недавно наткнулся на этот блог и стало очень интересно, тем более что небольшой опыт кода и анимации во Flash я приобрел. Кстати, благодаря все той же книге Колина Мука, всем рекомендую.
Антон, спасибо большое за этот блог, надеюсь, что уроки удадутся на славу :)

xiii
23 Октября 2010
— 12:58
#

@Dyrk: мой тебе совет - не надо делать туторы - делай игру. Вот возьми блокнот, набросай там за пару дней/неделю геймплей (МАКС?МАЛЬНО ПРОСТОЙ). Затем добавь к нему геймплейные фишки (МАКС?МАЛЬНО ПРОСТЫЕ НО СВО?). ? все это дело распиши на технические задания себе же. Будет сложно, зато если ты реально сделаешь игру - это будет в тысячи тысяч миллионов раз лучше чем повторение туториала/изучение темы. Поверь мне, я на этих граблях был лет десять. Как пример можешь действительно взять за основу этот замечательный туториал, но с помощью него сделать свою полноценную игру и выпустить и получить копейку как ты говоришь. Вот тогда ты действительно поймешь твой это путь или сила в web-программизме.

@Ant.Karlov - Жду поста про MiningTruck2!

RaymondGames
24 Октября 2010
— 00:09
#

"В одном файле может быть только один класс."
Скорее должен быть один класс, так как в .as файл их можно впихнуть и больше =)

hitab
24 Октября 2010
— 16:43
#

Совсем недавно наткнулся на блог =) ?нтересно читать и сравнивать со своим подходом. Спасибо! Удачи!

Nbooo
31 Октября 2010
— 00:03
#

извини за тупой вопрос, я хотел у вас спросить я учился по диску на http://easyflash.org/ , но там он делал игру без скелета, просто все хронилось в fla, вы не могли бы мне обьяснить пожалуйста зачем такая структура, и что такое классы?

Max
11 Ноября 2010
— 15:48
#

@Max, классы используются для Объектно Ориентированного Программирования — это когда игра собирается из «кирпичиков» (классов с разными методами и свойствами) которые между собой грамотно взаимодействуют. ООП позволяет быстро и доступно собирать сложные приложения с возможностью быстро вносить изменения в структуру программы и понимать, что и как работает.

Пример по приведенной вами ссылки я посмотреть не могу, но подозреваю, что в том уроке автор пишет код прямо в кадрах *.fla файла, что для больших игр не подходит и затрудняет последующий реюз отдельных возможностей разрабатываемой игры в будущем. Чтобы понять, что такое классы и как они используются, я настоятельно рекомендую почитать вам книжку Колина Мука — Actions Script 3.

Ant.Karlov
11 Ноября 2010
— 16:59
#

Огромное вам спасибо за то что уделили мне время и за быстрый ответ, а насчет урока, да он делал это прямо в кадрах, на отдельном слое "actions" спасибо за совет буду читать.

max
11 Ноября 2010
— 17:36
#

Спасибо. супер.

Айя
1 Декабря 2010
— 17:44
#

Добрый день. Вылезает такая ошибка.
1067: Implicit coercion of a value of type com.towerdefence:Game to an unrelated type flash.display:DisplayObject.
Не могу понять что такое. Помогите пожалуйста.

PRIZRAK
6 Декабря 2010
— 16:42
#

@PRIZRAK, это значит, что происходит неявное приведение класса Game к типу DisplayObject но таковым он не является (хотя должен, так как Game.as унаследован от Sprite). Где именно вы допустили ошибку я едвали догадаюсь, поэтому советую вам сверится с исходниками.

Ant.Karlov
6 Декабря 2010
— 18:52
#

Говорит что ошибка в 28 строке, addChild(_game);

PRIZRAK
7 Декабря 2010
— 12:36
#

Понял в чем ошибка была)

PRIZRAK
7 Декабря 2010
— 15:12
#

Шикарная статья, спасибо! У вас опечатка. Ск?лет.

Алексей
22 Декабря 2010
— 15:57
#

исправь скилет на скелет;)

?ван Пятоволенко
4 Февраля 2011
— 16:11
#

спс за урок. Бум учиццо. ?деи есть, осталось реализовать. 8)
Параллельно буду изучать фрэймворк моего друга - синглетон+интерфейс.

Слава
7 Февраля 2011
— 21:31
#

Спасибо за урок!

Гена
11 Февраля 2011
— 11:24
#

Огроменнейшее спасибо!
Действительно стартовать очень сложно...
Есть идеи. есть желание, не хватало Вашего туториала для старта! Теперь, надеюсь. приобретя навыки и знания буду пробовать воплощать свои идеи в жизнь.

ElviS
15 Марта 2011
— 02:42
#

Почему не завести отдельный класс для глобальных игровых констант? Получается Game.as какой-то полуфабрикат.

pavezlo
11 Апреля 2011
— 22:42
#

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

Ant.Karlov
12 Апреля 2011
— 09:51
#

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

ziplex
3 Мая 2011
— 11:44
#

А у меня такая шняга:
C:Users*******DesktopProject ******com******App.as, Line 1 5000: The class `com.******.App` must subclass `flash.display.MovieClip` since it is linked to a library symbol of that type.

Как решить? =((

Lx4
31 Мая 2011
— 18:42
#

@Lx4:
Попробуй в строчке:
public class App extends Sprite
поменять Sprite на MovieClip

BuxomBerry
1 Июня 2011
— 07:52
#

@BuxomBerry:
Не, не помогает =(( Уже и программу сносил, проект тоже...

Lx4
1 Июня 2011
— 12:00
#

Можно ли класс App поменять? На какой либо другой? ?ли не будет работать?

Lx4
1 Июня 2011
— 12:01
#

@Lx4, дело скорее всего не в названии класса App.as. У вас класс App унаследован от класса Sprite или MovieClip?

public class App extends MovieClip
{
...
}

Есть выделенная жирным строчка в классе App?

Ant.Karlov
1 Июня 2011
— 12:21
#

@Ant.Karlov
У меня public class App extends Sprite
Менял на МувиКлип - таже фигня. Даже если просто в Prop. там где class написать com.названиеигры.App, а в самом классе не чего не писать и скомпилировать, то он все ровно ругается. Если кликнуть на ошибку (в компиляторе), то он на 1 строку показывает, независимо, есть там что-то или нет.

Lx4
1 Июня 2011
— 23:22
#

@Ant.Karlov
Можно ли как-то настроить прогу по умолчанию? Чтобы не сносить. Просто такая ошибка возникла когда я экспериментировал.

Lx4
1 Июня 2011
— 23:24
#

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

Мой контактный email можно найти на странице «Об авторе».

Ant.Karlov
1 Июня 2011
— 23:49
#

@Ant.Karlov
Хорошо. Завтра вышлю. =)

Lx4
2 Июня 2011
— 00:06
#

@Ant.Karlov:
О! Все сделал занова, не торопился и все заработало! Спасибо за быстрые ответы и сорри за потраченное время =))

Lx4
2 Июня 2011
— 15:04
#

1) // Наследуем от него наш класс
public class App extends Sprite

Что такое наследование и зачем наследовать класс Sprite для класса App?

2)// Vars
private var _game:Game;

что ето за сменная _game(не понятно что ето у неё за тип Game)?

3) _game = new Game();[/b]
У книге Мука вроде сказано, еслы не ошибаюсь, что ето сменной _game присваивается экземпляр класса Game, но я не пойму что такое экземпляр класса.

4) не совсем понятен метод addChild(); а именно не понятно что значит "добавляет на сцену класс Game.as внутрь класса App "

Рома
12 Августа 2011
— 23:18
#

@Рома, на все заданные вами вопросы есть ответы в книгах, причем все эти знания являются базовыми.

1. Наследуя класс App от класса Sprite мы получаем в классе App все возможности класса Sprite, но при этом можем добавить ему свои методы и свойства которые сделают его более подходящим под наши нужды.

2. Переменная _game хранит указатель на созданный класс игры Game.

3. Экземпляр класса — это созданный объект на основе нашего класса, например Game. Благодаря переменной _game мы можем обратится к нашему созданному объеку типа Game.

4. Метод addChild() является стандартным методом почти для всех визуальных объектов. Вызывая этот метод и передавая в него указатель на наш только что созданный объект мы добавляем наш объект в визуальную структуру программы. Если не вызывать метод addChild() (не добавить объект в визуальную структуру), то он никогда не будет видимым.

P.S.: Не называйте переменные "сменными" чтобы не путать себя и других.

Ant.Karlov
12 Августа 2011
— 23:55
#

@Ant.Karlov, та согласен что есть в книге, но так как опыта в программировании всего лишь паскаль и то СОВСЕМ на базовом уровне, то есть з ООП совсем не встречался, то книга Мука даеться ОЧЕНЬ сложно

1)теперь понятно что такое наследование...а в нашем случае с какой целью делаем наследование класса Sprite?

4)"никогда не будет видимым" это значит что к нему нельзя будет обращаться?

P.S. что то у меня на початковом етапе написания класса App та же ошибка что и у Lx4 была...

Рома
13 Августа 2011
— 16:46
#

Спасибо, начинаю изучать флеш по твоим урокам!

Gorcer
26 Августа 2011
— 07:08
#

Огромное спасибо! Для новичка вроде меня это просто великолепный материал!

Артем
14 Сентября 2011
— 11:32
#

Антон, вот в этом месте:

Код выше создает класс Game.as, сохраняет ссылку на него в переменной _game и добавляет на сцену внутрь класса App методом addChild(); после чего Game.as становится рабочей частью приложения.

вместо слова "класс" вы хотели сказать объект класса или я что-то не понял?

Владимир
6 Ноября 2011
— 14:35
#

@Владимир, да, более понятно звучало бы «экземпляр класса».

> Код выше создает экземпляр класса Game.as, сохраняет ссылку на него в переменной _game и добавляет на сцену внутрь класса App методом addChild(); после чего Game.as становится рабочей частью приложения.


Спасибо что обратили внимание.

Ant.Karlov
6 Ноября 2011
— 21:34
#

Да, экземпляр класса, хотел отредактировать, но не нашел как =)

Владимир
7 Ноября 2011
— 18:00
#

Антон, спасибо вам за уроки!
Начал изучать AS по ним. До этого с Flash вообще не имел дела.
Очень хорошо написано.

Также скачал рекомендуемую вами книгу, буду изучать. Ещё раз спасибо!

Дмитрий
7 Декабря 2011
— 21:21
#

Добрый день.
Насчет расстановки панелей в IDE - у вас какая диагональ?
такое ощущение что стопитьсот ) и все помещается )

Hudson
13 Декабря 2011
— 15:05
#

@Hudson, в основном я работаю на 24" с разрешением ~ 1900x1600, но сейчас все чаще на ноутбуке 15" с разрешением 1440x900 — и как показывает практика на ноутбуке тоже не так уж и тесно :)

Ant.Karlov
17 Декабря 2011
— 11:53
#

У меня уже проблемы... Нету вкладки "проекты" то есть есть но там нельзя классы создавать... ? не правильно вообще проект создается.. А через деволм получилось криво, и не хочет привязываться... Не выводить Hello world...

Макс
6 Января 2012
— 02:23
#

Ну никак не хочет выводить Hello word, уже даже скачал CS 5.5 ,.. Ну что за..

Макс
6 Января 2012
— 04:00
#

Выставил просто так, ошибка:
http://clip2net.com/clip/m51167/1325808136-clip-73kb.png
Если нормальный класс выставлен все равно ошибка:
http://clip2net.com/clip/m51167/1325808185-clip-75kb.png

Макс
6 Января 2012
— 04:03
#

Уже не надо, я решил сам..

Макс
6 Января 2012
— 04:13
#

Странно если такую функцию делать через Деволп и CS3, то не привязывается... Установил CS5 и работает..

Макс
6 Января 2012
— 04:18
#

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

Ant.Karlov
6 Января 2012
— 11:40
#

Вот смотрите, надпись "Hello Word" Не выводится в версии CS3, а в версии CS5 выводится, почему же? Всё делал так же..

Макс
6 Января 2012
— 16:08
#

Зачем вообще нужны эти 2 строки:
var rect:Rectangle;

rect = grid.getRect(grid);

Не проще просто указать тут :
matrix.translate(0, 0);
0 0 ? Ведь так же получается

? зачем вообще стоит минут? (-rect.x, - rect.y);

Макс
13 Февраля 2012
— 00:45
#

?звините, не туда написал..

Макс
13 Февраля 2012
— 00:47
#

Подскажите, пожалуйста, как осуществить очистку ресурсов после прохождения уровня:
1) Univesre и все кто имел на него ссылку (враги, башни, панели управления...) должны подписываться на
removeEventListener(Event.REMOVED_FROM_STAGE, destroyObject),
а в обработчиках destroyObject обнулять все свои ссылке.
2) ?ли с точки зрения производительности лучше чтоб, подписывался только Universe и в этом обработчике вызвать всем своим объектам скажем deinit, а они в свою очередь для своих мемберов дергают deinit?

FirstFlashGame
27 Февраля 2012
— 14:32
#

@FirstFlashGame, объектам не нужно подписываться на какие-либо события. Архитектура игры построена таким образом что Universe управляет всеми объектами через ObjectController. Таким образом при очищении мира достаточно для каждого экземпляра контроллера вызывать метод clear() и все объекты будут корректно освобождены и помещены в кэш. А обнуление парамтров каждого из объектов происходит перед их добавлением в игровой мир (перед повторным использованием).

Сам игровой мир Universe не может удалятся и пересоздаваться потому что этот класс является синглтоном.

Ant.Karlov
27 Февраля 2012
— 21:48
#

@Макс, я использовал старый код из своего другого проекта где это нужно было.

Ant.Karlov
27 Февраля 2012
— 21:49
#

Тогда я попытаюсь описать архитектуру приложения согласно Вашым подсказкам:

App создает Game.
Game берет на себя работу менеджера окон, переключая между собой: Credits, ChooseProfile, LevelSelect, Win/Lose, Universe.
В отличии от других окон – Universe инициализируется один раз и более не уничтожается (синглтон)

Когда загружается новый уровень, или рестартует старый то вызывается startGame которая заново инициализирует панель статистики, панель башен.

При наступлении условия выигрыша или проигрыша Universe вызывает очистку clear() для towers, enemies, bullets и просит Game переключить окна на Win/Lose

Только вот что еще делает App кроме как создает Game? Ведь кешированием объектов занимается Universe, также и перегонкой вектора в растр после загрузки уровня…

Все ли верно я понял?

FirstFlashGame
28 Февраля 2012
— 00:04
#

@FirstFlashGame, App.as — это технический класс, по сути точка входа в приложение. В этом классе обычно выполняются всякие технические вещ, например: сбор статистики (вызов мочиботов), инициализация спонсорского API, демонстрация спонсорской заставки, возможна проверка на сайт-лок, запуск кэширования графических ресурсов (векторные анимации перегоняются в растровые ленты), и т.п. То есть что-то вроде тамбура где игра готовится к запуску. Обычно в законченной игре точкой входа в приложение является класс Preloader.as который будет создавать App.as и так далее.

Universe.as перегоняет сейчас фактически графику игрового уровня из вектора в растр, а в классе App обычно перегоняется вся спрайтов (или основная часто используемая графика, боевых единиц, постройки), которая используется в игре. Кэширование графики самих уровней допускается в процессе игры перед запуском уровня, так как на прекэширование графики непосредственно игровых уровней — памяти не хватит.

Ant.Karlov
28 Февраля 2012
— 00:49
#

Я пошел другим путем, и он оказался очень дремучим. Теперь, переработав классы согласно Вашим рекомендациям, головоломка помаленьку начинает складываться в голове. Уже нет противоречий в архитектуре, и понятны многие вещи, оставшиеся “за кадром” при делании уроков. Это чувство всегда приятно, когда пелена спадает пред глазами. Все работает! Спасибо!

FirstFlashGame
28 Февраля 2012
— 14:41
#

Антон, а почему фреймрейт 35?
Всегда считал, что общепринятый стандарт = 30 fps.
?ли у меня устаревшие сведения? )

Kingo
27 Марта 2012
— 14:29
#

Ant.Karlov, а как вы обрабатываете? После окончания игры нужно отправлять пользовательское событие? Я просто не могу понять как связать менеджер экранов и события в игре

komarVadim
13 Апреля 2012
— 15:54
#

Прошу прощения, я создал класс App.as путь к нему если через доменное имя сайта выходит такой: ru.towerdefence.App, я его прописал но при компиляции файл TowerDefence.fla выдает только пустое окно флеша, но окна output нету ( в чем может быть проблема не подскажете пожалуйста)

марк
13 Апреля 2012
— 20:13
#

все получилось, почему то если пишу в пакете ru.towerdefence и при "вызове" класса на чистый лист пишу ru.towerdefence.App не работает, а если изменить название пакета на towerdefence и вызов класса на towerdefence.App то все работает

марк
13 Апреля 2012
— 20:26
#

Здравствуйте, вы написали что для новичков хватает flash ide, а в дальнейшем потребуется ли какой нибудь редактор кода, нужен ли он вообще?
Если да, то какой(под Mac)?

Visal
9 Июня 2012
— 15:36
#

@Visal, потребуется ли вам альтернативный редактор кода в будущем — это зависит только от ваших требований к редактору кода.

Хорошие альтернативные редакторы кода под Mac, работающие с AS3:
IntelliJ IDEA
FDT
TextMate

Как настроить TextMate для работы с AS3 я писал здесь...

Ant.Karlov
10 Июня 2012
— 11:46
#

Антон, нашел видео где с твоего поста все слизано, да же слова говорит как ты написал, блин даже обидно как-то стало за тебя=) Хоть бы упомянул что ресурс взят с твоего блога.
http://www.youtube.com/watch?v=kEdvoU5wz6Q

Vladimir
30 Июня 2012
— 14:06
#

@Vladimir, забавное видео. Но расстраиваться и унывать не стоит, я уроки пишу и публикую просто так и мне не жалко если их кто-то пытается переделать и/или выдать за свои без указания источника, пусть это останется на их совести. Спасибо за информацию! :)

Ant.Karlov
2 Июля 2012
— 20:34
#

Спасибо большое за инструктаж в нете мало что то подобное найдешь короче низкий Вам поклон!!!

moozes
6 Июля 2012
— 15:58
#

Антон, интересно узнать, почему ты используешь 35 кадров / сек?
Человеку вроде как 24 кадра хватает что бы воспринимать картинку как видео. Понятное дело если обрабатывать действия в ENTER_FRAME, то они будут выполняться чаще, но игру можно выполнять и по тикам в таймере. Где-то читал, что Flash`у "удобнее" работать с определенной частотой, хотя не думаю что это критично, хотел бы узнать твое мнение.

?горь
16 Августа 2012
— 22:34
#

@?горь, Для видео достаточно 24 кадров, да. А вот для игр чем fps больше тем лучше — все будет рассчитываться и рендерится намного плавнее.

Я выбрал 35 кадров как компромисс между скоростью и производительностью. 24 кадра в флеш играх мне уже категорически не нравится — не приятно глазу смотреть на дерганья. В идеале я бы ставил все 60 кадров :)

От тиков и таймеров для процессинга игры я настоятельно вам рекомендую отказаться так как во флеше они могут давать существенные временные сбои, для флеша идеально использовать ENTER_FRAME.

Ant.Karlov
21 Августа 2012
— 21:36
#

Всем кто столкнулся с
5000: The class `com.******.App` must subclass `flash.display.MovieClip` since it is linked to a library symbol of that type.

или

должен входить подкласс "flash.display.MovieClip", так как он связывается с символом такого же типа в библиотеке.


Лично у меня была проблема в том, что я привык что компилятор сохраняет весь проект перед компилированием. Флеш же так не делает. Так что сохраните то, что набрали (ктрл+С) а после запускайте.

Спасибо за уроки

ATEX
9 Апреля 2013
— 21:12
#

Антон, а в CS6 нет output?

Gost001005
2 Октября 2013
— 13:36
#

привет.
изучаю флеш, спасибо за урок. вчера столкнулся с ошибкой, которая описана в комментариях, а именно - 1067: Implicit coercion of a value of type com.towerdefence:Game to an unrelated type flash.display:DisplayObject.

в комментариях выше вы пришли к выводу, что класс World является встроенным или системным, но это не так.
Как говорится, утро вечера мудренее, поэтому, сегодня утром я обнаружил, что эта ошибка выскакивает, если создать класс и не прописать в нём вот такую конструкцию:

import flash.display.Sprite;
public class Game extends Sprite

теперь и World.as работает без проблем

MainFish
15 Октября 2013
— 12:24
#