TowerDefence #4. Готовимся к поиску пути

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

Чтобы урок про поиск пути получился интересным и полным за счет возможности протестировать работу алгоритма сразу же — нам нужно для этого сделать еще некоторые приготовления.

Обработка мышки

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

Об этом много рассказывать не нужно, поэтому сразу открываем класс Game.as и в конструкторе класса пишем следующий код:

addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);

В заголовке класса не забываем импортировать класс:

import flash.events.MouseEvent;

Теперь пишем обработчик движения мышки:

private function mouseMoveHandler(event:MouseEvent):void
{
  _universe.updateMousePos(event.stageX, event.stageY);
}

Как видно из кода, используя метод updateMousePos() класса Universe.as, мы передаем координаты мыши в игровой мир. Теперь нам необходимо написать метод updateMousePos(), чтобы обрабатывать координаты мышки. Переходим к редактированию класса Universe.as и добавляем новые публичные переменные:

// Текущее положение курсора мыши в пикселях
public var mousePosX:int = 0;
public var mousePosY:int = 0;

// Текущая ячейка, над которой находится курсор мыши
public var cellPosX:int = 0;
public var cellPosY:int = 0;

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

public function updateMousePos(mouseX:int, mouseY:int):void
{
  mousePosX = mouseX;
  mousePosY = mouseY;
            
  // Координаты тайла, над которым находится курсор мыши
  cellPosX = int(mouseX / MAP_CELL_SIZE);
  cellPosY = int(mouseY / MAP_CELL_SIZE);
            
  // Подсветка текущего тайла
  _currentCell.x = MAP_CELL_HALF + cellPosX * MAP_CELL_SIZE;
  _currentCell.y = MAP_CELL_HALF + cellPosY * MAP_CELL_SIZE;
}

Тут, как можно видеть из кода, я сразу добавил подсветку текущей клетки и еще одну новую константу, которая хранит в себе половину игровой ячейки в пикселях. Для чего это нужно, станет понятно позже, а пока объявим её в заголовках класса Universe.as:

public static const MAP_CELL_HALF:int = 16;

В качестве подсветки текущего тайла выступает обычный MovieClip из библиотеки клипов в TowerDefence.fla. Добавьте в папку _DEBUG новый клип с именем CurrentCell_mc и нарисуйте в нем полу-прозрачный квадратик или рамочку размером 32x32 пикселя, и выровняйте его по центру. Возвращаемся в Universe.as и добавляем новую приватную переменную, которая будет содержать этот квадратик:

private var _currentCell:Sprite;

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

_currentCell = new CurrentCell_mc();
addChild(_currentCell);

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

Если у вас что-то не работает и при этом не выводится никаких ошибок, то ищем причину, следуя шагам:

1. В методе mouseEventHandler() класса Game.as добавляем следующий код:

trace(event.stageX, event.stageY);

Тестируем приложение и смотрим, что выводится в окне output. Если в окне бегут цифры (координаты мыши), значит здесь все ок. ?наче перечитываем еще раз все внимательно или сверяемся с исходником.

2. Если вы вообще не видите спрайта _currentCell или он застыл в правом верхнем углу экрана, то добавляем trace всех координат в методе updateMousePos() и проверяем, что выводится в окне output. В особенности обратите внимание на координаты клипа _currentCell.x и _currentCell.y. Далее ищим причину ошибки самостоятельно или сверяемся с исходником.

Вопрос на засыпку: Как вы думаете зачем мы перехватываем координаты мыши непосредственно в классе Game.as, а не в игровом мире?

Доработка игровой карты

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

При создании игровой карты мы выровняли квадратики по левому верхнему углу внутри клипа, то есть центром каждой ячейки является левый верхний угол. Таким образом зная, например координаты ячейки x-3, y-2 мы можем узнать координаты этой ячейки в пикселях так:

cell.x = 3 * MAP_CELL_SIZE;
cell.y = 2 * MAP_CELL_SIZE;

Сейчас у нас реализовано так.

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

А нужно сделать так.

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

cell.x = MAP_CELL_HALF + 3 * MAP_CELL_SIZE;
cell.y = MAP_CELL_HALF + 2 * MAP_CELL_SIZE;

Ленивым заводить лишнюю константу для хранение размера половины ячейки я очень не рекомендую делать так: cell.x = MAP_CELL_SIZE * .5 + 3 * MAP_CELL_SIZE; Это не единственное место, где нам понадобится размер половины ячейки, и в итоге у вас может получится много лишних вычислений.

Теперь, чтобы карта выводилась согласно новым требованиям, нам нужно переделать метод makeDebugGrid(), добавив в место обнуления координат каждой ячеки присвоение значения MAP_CELL_HALF. Более того, я переименовал этот метод в updateDebugGrid(), так как каждый раз, удаляя или изменяя состояние карты проходимости, нам прийдется его повторно вызывать. ? поскольку старая его реализация была очень не оптимальна для постоянного его вызова, я его немного оптимизировал следующим образом:

private function updateDebugGrid():void
{
  // Графический образ ячейки
  var cellSprite:MovieClip = new DebugCell_mc(); 
            
  // Растровый холст для рисования сетки
  var bmpData:BitmapData = new BitmapData(MAP_CELL_SIZE * MAP_WIDTH_MAX, 
    MAP_CELL_SIZE * MAP_HEIGHT_MAX, true, 0x00000000);
            
  // Начальное положение текущей ячейки по высоте/ширине
  var matrix:Matrix = new Matrix();
  matrix.tx = MAP_CELL_HALF; 
  matrix.ty = MAP_CELL_HALF;
            
  // Двигаемся по высоте карты
  for (var ay:int = 0; ay < MAP_HEIGHT_MAX; ay++)
  {
    // Двигаемся по ширине карты
    for (var ax:int = 0; ax < MAP_WIDTH_MAX; ax++)
    {
      // Переключаем состояние ячейки
      cellSprite.gotoAndStop(getCellState(ax, ay));
                    
      // Рисуем текущую ячейку
      bmpData.draw(cellSprite, matrix);
                    
      // Меняем положение текущей ячейки по ширине
      matrix.tx += MAP_CELL_SIZE;
    }
                
    // Меняем положение текущей ячейки по высоте
    matrix.ty += MAP_CELL_SIZE;
    // Обнуляем ширину
    matrix.tx = MAP_CELL_HALF;
  }
                    
  // Передаем растровый холст в картинку
  _debugGrid.bitmapData = bmpData;
            
  cellSprite = null;
}

Принципиальное его отличие от прошлой реализации только в том, что мы избавились от временного контейнера grid и сейчас не создается на каждую ячейку отдельный MovieClip. В новой реализации создается растровый холст и, используя один единственный MovieClip, мы словно штампом отпечатываем на холсте все клеточки по очереди, предварительно переключая состояние этого штампа (клипа) в зависимости от состояния клетки. В качестве координат смещения клипа используется класс Matrix, в котором сразу указываются координаты где рисовать клип. Сам же клип в структуру отображения не добавляется и его координаты не обновляются. Когда весь холст заштампован ячейками, мы присваевам его нашей растровой картинке Bitmap. Обратите внимание, что создание и добавление картинки _debugGrid было вынесено за пределы этого метода, так как она больше не пересоздается и нет необходимости каждый раз её удалять и добавлять снова. Мы меняем только графические данные в bitmapData. Так что не забудьте добавить инициализацию нашей отладочной сетки в конструктор Universe.as:

_debugGrid = new Bitmap();
addChild(_debugGrid);

Далее, чтобы наши графические ячейки вставали правильно, нужно еще отредактировать клип DebugCell_mc во Flash IDE. Открываем клип для редактирования и на всех ключевых кадрах выравниваем квадратики по центру холста.

Тестируем! Теперь все должно быть так как нам нужно.

Редактирование карты проходимости

Теперь самый простой и самый вкусный этап на сегодня — добавляем возможность редактирования карты проходимости. Открываем Universe.as и добавляем в заголовок класса импортирование flash.events.MouseEvent, как мы это делали для класса Game.as и в конструкторе класса Universe.as добавляем слушателя:

addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);

Далее добавляем метод mouseUpHandler() — это обработчик отжатия кнопки мыши:

private function mouseUpHandler(event:MouseEvent):void
{
  if (getCellState(cellPosX, cellPosY) == STATE_CELL_BUSY)
    setCellState(cellPosX, cellPosY, STATE_CELL_FREE);
  else
    setCellState(cellPosX, cellPosY, STATE_CELL_BUSY);

  updateDebugGrid();
}

Тут я думаю все должно быть просто и понятно без дополнительных комментариев. ?спользуя методы getCellState() и setCellState(), а так же текущие координаты клетки, мы освобождаем занятую клетку при клике и наоборот, пустую клеточку занимаем, а в конце обновляем отладочную сетку. Тестируем!

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

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

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

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

  1. Добавить локальные переменные для хранения координат текущей ячейки врага в классе EnemyBase.as: _cellPosX, _cellPosY;
  2. Рассчитывать текущую ячейку врага при его движении в методе update() в классе EnemyBase.as. ? не забудьте добавить вызов родительского метода в EnemySoldier.update() — нужно это, чтобы для всех врагов был один рассчет координат. Подсказка: решение для рассчета текущей ячейки ищите в методе Universe.updateMousePos();
  3. Добавить в EnemyBase.as публичный метод setToCell(cellX:int, cellY:int), в котором необходимо производить рассчет нового положения врага, исходя из координат ячейки и помещать врага в данную ячейку на карте. Решение для рассчета текущего положения врага согласно указанной ячейки ищите в методе Universe.updateMousePos();

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

Заключение

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

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

Содержание

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

 

 

copyPixels работает побыстрее draw , вродебы.
Можно было отрисовать в битмап сначало клетку, а затем ее штамповать...
У меня вопросики еще...
1. Многие советуют использовать таймер вместо ENTER_FRAME. ? притом события в таймере выполняются не одновременно для всех обектов. Что ты об этом думаешь.
2. У тебя в МТ2 сохраняется информация о прохождениях. Как ты это сделал?

genm
8 Декабря 2010
— 00:49
#

@genm, для отрисовки отладочной сетки не особо принципиально как её рисовать. В первом варианте я вообще показал самый жуткий пример... ну чтобы потом не делали так :) copyPixels быстрее, да.

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

2. Что имеется в виду под «информацией о прохождениях»? Какие игровые уровни игрок прошел, а какие нет? Если да, то для этого используется SharedObject.

Ant.Karlov
8 Декабря 2010
— 01:11
#

Привет, отличная статья!
Можешь сказать, что за шрифт вы используете здесь:
http://www.ant-karlov.ru/formidable/uploads/2004-td4-pic1.png ?

rock
8 Декабря 2010
— 06:33
#

Спасибо!!! Очень интересно!

?ван
8 Декабря 2010
— 09:09
#

я прям не успеваю)) спасибо огромное за статью! бум ковырять =^_^=

coolsiu
8 Декабря 2010
— 09:52
#

Отлично. Как всегда.
Антон, интересно, почему мы используем именно MOUSE_UP, а не MOUSE_CLICK? Это принципиально и дает какие-то преимущества?

Iktash
8 Декабря 2010
— 11:59
#

@rock, это моноширный шрифт Monaco из серии стандартных шрифтов Mac OS. На просторах ?нтернет я встречал его версию для Windows но с наскоку найти не удалось.

Ant.Karlov
8 Декабря 2010
— 20:06
#

@Iktash, в данном случае не принципиально. Можно использовать и MOUSE_CLICK.

Ant.Karlov
8 Декабря 2010
— 20:09
#

2Ant.Karlov
Гм, спасибо.
Жаль только, что под Win они выглядят совершенно не так, как на той картинке.
http://www.peeep.us/bbfa12e2

rock
9 Декабря 2010
— 04:53
#

@rock, поставь размер шрифта 9px (или 10px) и отключи ClearType (сглаживание) для шрифтов и тогда должно будет выглядеть также.

Ant.Karlov
9 Декабря 2010
— 05:46
#

ааа)))) робокопов в спам)))))
под планшетом валяюсь!
это выстрел в моё сердце!
PS: простите за мой латентный любовный оффтоп))))

Antheni 13
9 Декабря 2010
— 10:25
#

Было бы здорово пару уроков по Box2d. Как подключать и тд. А то непонятно.

PRIZRAK
10 Декабря 2010
— 15:48
#

Не думаю, что в этом Товер Дефенсе будет Бокс2Д))

Iktash
10 Декабря 2010
— 16:51
#

Я не про Товер Дефенс а вообще.

PRIZRAK
10 Декабря 2010
— 20:40
#

?нтересная статья! Спасибо!
А поиск пути будет на основе волны?

BuxomBerry
10 Декабря 2010
— 22:07
#

Я готов к поиску пути :) Поехали :)

Жора
11 Декабря 2010
— 08:35
#

Я встрял в самом начале, в классе Game(). У меня конструктор обрабатывается, но до метода mouseMoveHandler даже не добирается. Как-будто не выполняется слушатель (всё испортировал и ошибок нет при компиляции). ? ещё, в классе создал:
private var _universe:Universe;
а то ошибку он выдаёт. Я не знаю, может _universe ты хочешь доставать из App.as ,раз не говоришь что нужно создавать переменную новую. Но она там приватная, да даже если делать публичную, то всё равно ошибку выдает. В общем я встрял в самом начале. Сильно не пинайте меня(
Может кто тыкнет пальцем что я делаю не так.

J0x
11 Декабря 2010
— 10:00
#

Очень интересно.
P.S.Новый индикаторы симпатичные ;)

?ван
11 Декабря 2010
— 13:28
#

Всё, скачал исходник, вопрос отпал. Эх, не соображаю еще до конца))

J0x
11 Декабря 2010
— 16:27
#

Антон, а какой ответ на "вопрос на засыпку"? (:

dada
13 Декабря 2010
— 02:29
#

@Ant.Karlov, подскажи где можно подробнее почитать о методах растеризации. Я не особо понял как мы оптимизировали нашу игровую сетку ни в первый раз (Урок #2), ни сейчас. То есть конечно разжевать для себя сам процесс можно благодаря комментариям. Но в голове не укладывается как до этого можно додуматься самому. Если понадобится когда-нибудь в своем проэкте.
Ты сам придумал оба эти способа или все же это общепринято так делать?:)

Raketa
13 Декабря 2010
— 23:58
#

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

Ant.Karlov, решил начать делать ТД, как бы банально это не звучало, попробую применить твои приемы) За одно проверить эффективность оптимизации.

VladiT
16 Декабря 2010
— 16:34
#

Отличный блог. Спасибо что вы делитесь своими знаниями и приёмами по созданию игр.
Я новичок в этом, не считая нескольких головоломок на Делфи и бэйсике.

Есть одно замечание по поводу статей. Мне кажется, надо было сначала объяснить подробнее что-такое TowerDefence или изобразить схематично что в итоге должно получится. А то я это понял только после 4 урока. ? пришлось заново осмысливать первые три.

ABER
17 Декабря 2010
— 16:15
#

ABER, не хочу обижать но если вы не знаете что такое TowerDefence, то тут никакие уроки не помогут :)

?ван
17 Декабря 2010
— 23:19
#

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

В том то и дело, я не знаю что такое TowerDefence, поэтому с удовольствием читаю уроки.

ABER
18 Декабря 2010
— 06:14
#

@ABER Просто аудитория уроков активные игроки-начинающие разработчики,поэтому TD понятие самособой разумеющиеся. Рекомендую просто поиграть в пару таких игр, чтобы все уяснить.

WeslomPo
18 Декабря 2010
— 15:01
#

Привет, не знаю видел этот ужас или нет но вот:
http://www.4v4.com/free-online-car-games/664/santa-truck.html

dm62
18 Декабря 2010
— 22:42
#

Зачетная игрушка!)))

WeslomPo
18 Декабря 2010
— 23:18
#

Еще одна игра в коллекцию клонов))

iktash
19 Декабря 2010
— 00:28
#

Блин я такую сделать хотел :(

Я не робот!
19 Декабря 2010
— 09:20
#

Hello,

1 of my crew members did buy the source and did redesign it.

We payed a reasonable amount for the source. So it isnt stolen.

With kind regards,
Vasco Rouw

WeslomPo
19 Декабря 2010
— 14:41
#

Это я по теме игры, им жалобу написал, это ответ. Ждем Антона, что он скажет :).

WeslomPo
19 Декабря 2010
— 14:42
#

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

?ван
19 Декабря 2010
— 16:35
#

Графика на фоне как у Антона, и уровни один в один. Если они код не купили, то это воровство.

WeslomPo
19 Декабря 2010
— 16:44
#

Словно бы никто обфускацию и не придумывал... О контрольных суммах тоже как бы никто не подозревает... Почему бы не защитить свои разработки от подобных нападок?

BuxomBerry
19 Декабря 2010
— 18:15
#

Все равно сломают

WeslomPo
19 Декабря 2010
— 19:14
#

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

Тут уже встает вопрос о выгодности этого мероприятия по взломщику.

BuxomBerry
20 Декабря 2010
— 07:18
#

BuxomBerry, а можно поподробнгее об контрольной суме во флеше? Можно статеику на вашем блоге накидать...

?ван
20 Декабря 2010
— 09:52
#

http://flashgameblogs.ru/blog/actionscript/291.html
Как защитить вашу игру от ребрендинга
Перевод поста с блога ФГЛ

WeslomPo
20 Декабря 2010
— 12:43
#

Ок спс

?ван
20 Декабря 2010
— 13:23
#

Что то Антон опять дето пропал :( Наверное продолжение ремонта...

?ван
20 Декабря 2010
— 14:55
#

@?ван: Действительно. Обещал перед НГ писать чаще и пропал. Надеюсь, что с ним все в порядке

Zaphod
20 Декабря 2010
— 16:23
#

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

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

Спасибо за проявленный интерес к ситуации! :)

Ant.Karlov
27 Декабря 2010
— 15:12
#

ждем продолжения)

Робокоп
2 Января 2011
— 06:42
#

Уже все готовы к поиску пути :)

?ван
19 Января 2011
— 14:49
#

@?ван значит завтра будем его искать! ;)

Ant.Karlov
19 Января 2011
— 20:42
#

@Ant.Karlov, на мой взгляд было-бы удобно, если была бы уроки были вынесены в отдельное оглавление и можно было бы их по порядку все просмотреть... А то искать их в недрах лога не очень уднобно (хоть и не смертельно, конечно-же)

Кирилл
7 Апреля 2011
— 13:03
#

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

Ant.Karlov
7 Апреля 2011
— 13:26
#

Тоже очень интересно узнать ответ на "вопрос на засыпку" ;)

jarofed
24 Августа 2011
— 13:12
#

Если я заменю (для большей гибкости) MAP_CELL_HALF:int = 16; на MAP_CELL_HALF:int = MAP_CELL_SIZE/2; - это не будет иметь никаких неприятных последствий? )

Kingo Kongo
29 Марта 2012
— 20:51
#

Упс, пардон ) только сейчас заметил комментарий по этому поводу )
.
Правда в моем случае я этот параметр (координаты центра ячейки) не буду использовать, поскольку все объекты у меня планируются размером примерно с ячейку, мелких нет.

Kingo Kongo
29 Марта 2012
— 22:14
#

Здрасте. Возникла проблема с уроком.
_debugGrid.bitmapData = bmpData;---вот этоткусок пишет что bmpData=null. Пробовал передать в bmpData.draw()-простой мувиклип, все ровно пишет нулл.

seegma
6 Сентября 2012
— 22:25
#

У вас опечатка с EnemySoldier(В предыдущих главах вы почему-то везде писали EnemySolder(Включая константу).
Я сначала тоже подумал, что вы хотели написать Soldier, но потом решил всё же следовать уроку, чтобы не запутаться, и сделал, как у вас, Solder. А вы теперь пишете Soldier(правильно).
Западло =(

SuriTheAngel
23 Декабря 2013
— 00:02
#

опечатка в 7 строке вместо "var" - "yar"...

Kill Flash
14 Февраля 2014
— 18:53
#

Добрый день!
Сразу хочу поблагодарить Вас за столь доходчивые уроки, а главное понятный код!

Хочу предложить маленькую модификацию обновления карты при нажатии на кнопку мыши

private function updateDebugCell():void
{
//текущая ячейка
var pCurrentCell:MovieClip = new debug_cell();
//Перевод получившейся сетки в растр, для оптимизации
var pMatrix:Matrix = new Matrix();

// Начальное положение текущей ячейки по высоте/ширине
pMatrix.tx = Universe.MAP_CELL_SIZE*this.nCellPosX + Universe.MAP_HALF_CELL_SIZE;
pMatrix.ty = Universe.MAP_CELL_SIZE * this.nCellPosY + Universe.MAP_HALF_CELL_SIZE;

//переключение состояния тайла
pCurrentCell.gotoAndStop(this.getCellState(this.nCellPosX, this.nCellPosY));
//отображение текущей ячейки
bmpData.draw(pCurrentCell, pMatrix)

//Перевод растрового холста в картинку
this.bmpDebugGrid.bitmapData = bmpData;

pCurrentCell = null;
}
Вызывать его точно так как и updateDebugGrid из mouseUpHandler

Если такое решение не верно, то хотелось бы услышать почему.
PS Если такое реализовано дальше, прошу меня простить за поспешность! ))

Евгений
27 Октября 2014
— 19:58
#

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

Вопрос. А почему мы не пользуемся свойствами mouseX, mouseY (DisplayObject)? Там где передаем координаты мыши. Вообще, зачем мы их передаем, gameplay их так и так знает.

Дан
4 Июня 2015
— 22:42
#