Глава 11. Подарки и сокровища
В этой главе рассмотрим, как научить нашего Героя собирать подарки с земли. Вы догадываетесь, что это такое, - кристалы, денежки, мертвые паучки, горшочки здоровья, аммуниция, да и мало ли чего еще. Артефакты очень разнообразны в своем действии на Героя (или Врага), некоторые увеличивают его здоровье или дают большую силу оружию, другие наоборот. В нашем примере все артефакты делают только одно они увеличивают славу Героя (кстати Слава Героя изменяется в баллах или очках, в общем, в попугаях). Поняв идею и способы, вы сможете создавать любые артефакты. Мы начнем с кода из главы 6 «Открывание двери». Мы не хотим писать слишком большой код, чтобы он перестал пониматься. Первое, нарисуем клип артефакта. Как и клипы Героя или Врага, клип артефакта должен иметь центральную точку. В первом кадре добавим команду "Stop",чтобы остановить на короткое время игру для прорисовки артефактов. Убедитесь, что клип, как и другие клипы, имеет имя "items" для связывания с объектом. Имея клип артефакта, мы можем размещать его в любом месте без необходимости его рисования. Что за баллы?Чтобы показать набранные баллы, рисуем элемент - динамический текстовой блок на экране. Его положение за пределами карты, в каком-нибудь углу. Динамический текст будет показывать значение переменной "points". 
Переменная "points" хранит число набранных баллов, даже, если мы переходим на другую карту. Мы должны аккуратно присоединить переменную к объекту game. При объявлении объекта game добавим свойство points и установим его значение 0. game = {tileW:30, tileH:30, currentMap:1, points:0};
Что-то подняли Посмотрим на код, первое, объявляем объекты Артефакты и создаем массив, который будет хранить их позицию на различных картах. // Массив артефактов двумерный, 1-ый массив пустышка для совмещения с номерами карт myItems = [ [0], [[1,1,1],[1,1,2],[2,1,3]], [[2,1,3],[2,6,3],[1,5,4]] ]; // Артефакт тип 1, очки +1 game.Item1= function () {}; game.Item1.prototype.points=1; // Артефакт тип 2, очки +10 game.Item2= function () {}; game.Item2.prototype.points=10;
Массив myItems построен также, как и массив Врагов (см. Главу 9). Один массив для одной карты. Мы не используем карту map0, поэтом первый массив пустышка. Для карты 1 установлены 3 артефакта: [1,1,1],[1,1,2],[2,1,3]. Каждый артефакт имеет 3 параметра: первый параметр тип артефакта (здесь число 1 или 2), следующие 2 параметра - позиция клипа Артефакта на карте, т.е. к клипу какой плитки он должен быть присоединен. Посмотрим на последний артефакт: тип его 2, и он будет размещен на плитке x=1, y=3. Последняя часть кода объявляет два типа Артефакта. Для упрощения, Артефакты имеют одно свойство "points" (очки). Свойство показывает сколько очков будет добавлено игроку за их поднятие. Артефакт Type1 добавляет 1 очко игроку, а Артефакт Type2 10 очков. Теперь, модифицируем функцию buildMap, чтобы добавить Артефакты при создании карты. Добавим этот код до строк создания Героя. // Скопируем массив артефактов game.items = myItems[game.currentMap]; // Цикл по артефактам, можно начать и с 1 for (var i = 0; i<game.items.length; ++i) { // Формируем имя объекта var name = "item"+game.items[i][2]+"_"+game.items[i][1]; // Создаем объект game[name]= new game["Item"+game.items[i][0]]; // Запомним номер артефакта game[name].position= i; // Присоединяем клип артефакта items из библиотеки под именем item_У_Х и // кладем его на уровень 11001+i game.clip.attachMovie("items", name, 11001+i); // Запомним клип в общей структуре клипов game[name].clip=game.clip[name]; // Вычисляем координаты Х / У клипа game[name].clip._x = (game.items[i][1]*game.tileW)+game.tileW/2; game[name].clip._y = (game.items[i][2]*game.tileH)+game.tileH/2; // Показываем клип нужным кадром game[name].clip.gotoAndStop(game.items[i][0]);
} _root.points=game.points;
Первое, мы создаем копию массива артефактов для текущей карты. Этот массив называется game.items и будет хранить информацию об Артефактах текущей карты. Затем в цикле для каждого элемента массива создается объект. В строке var name = "item"+game.items[i][2]+"_"+game.items[i][1];
Создаем имя нового объекта Артефакт. Имя формируется по стандартным правилам именования объектов - <имя><номер плитки по У>_<номер плитки по Х>. После создания объекта на основе шаблона объекта артефакта, сохраняем позицию Артефакта на карте в свойствах объекта. Что за позиция? Счетчик по i дает номер Артефакта в массиве, поэтому его и сохраняем, что очень удобно при собирании Артефактов. Например: когда мы создаем карту 1 и i=1, мы создаем объект артефакт на основе даннымх [1,1,2], артефакт будет назван "item2_1" и можно легко получить доступ к его свойствам в массиве - item2_1.position. Больше нам ничего и не надо, этих данных достаточно для удаления Артефакта. После этого размещаем новые экземпляры клипов Артефактов на карте согласно указанным местам. Последняя строка в цикле переводит новый клип на кадр с изображением Артефакта. Все Артефакты типа 1 будут показываться кадром 1. Наконец, обновляем переменную , которая будет показывать количество очков игрока. На старте игрок возможно будет иметь 0 очков, но когда карта сменится, мы будем использовать туже самую функцию и игрок к тому времени уже может даже что-то наберет, что и будет показываться. Найди егоУ нас есть Артефакты. А как Герой узнает, когда ему надо нагнуться и взять что-то. Добавим в конце функции moveChar следующий код: // Сформируем имя артефакта по текущей позиции объекта var itemname=game["item"+ob.ytile+"_"+ob.xtile]; // Проверим (Артефакт ЕСТЬ и Герой здесь)? if (itemname and ob == _root.char) { // ДА увеличиваем количество попугаев game.points=game.points+itemname.points; // Запоминаем на табло _root.points=game.points; // Удаляем клип артефакта removeMovieClip(itemname.clip); // Очищаем ссылку на артефакт в массиве game.items[itemname.posi]=0; // Удаляем объект артефакта delete game["item"+ob.ytile+"_"+ob.xtile];
}
Переменная itemname используется для формирования имени артефакта по значению текущей позиции Героя. Когда Герой станет на плитку x=4, y=9, в переменную запишется значение "item9_4". Остается проверить - есть ли такой объект. Если объекта нет, то и подарка не будет. Если объект найден, то Герой перемещается, а мы добавим очки из свойств объекта в переменную game.points и обновим переменную _root.points, чтобы показать новые данные с наградами. Теперь самое время удалить клип Артефакт с экрана. Каждый Артефакт должен быть удален из 3 мест: - Удаление клипа
- Удаление из массива артефактов
- Удаление объекта.
Нужно не забывать, что массив Артефактов копия массива myItems, и, если мы уходим с карты и возвращаемся на нее, то все Артефакты опять создаются. Это не очень хорошо, поэтому нужно будет обновить функцию changeMap. Добавим код в начало функции changeMap: // Объявим пустой временный массив артефактов var tempitems=[]; // Цикл по артефактам for (var i = 0; i<game.items.length; ++i) { // Проверим (Номер артефакта НЕ 0) if(game.items[i]) { // ДА формируем имя объекта артефакт var name = "item"+game.items[i][2]+"_"+game.items[i][1]; // Удаляем объект артефакта delete game[name]; // Информацию об артефакте переносим во временный массив tempitems.push(game.items[i]); }
} // Сохраним временный массив артефактов текущей карты в массиве артефактов myItems[game.currentMap]=tempitems;
Здесь используем массив, чтобы скопировать еще не собранные Артефакты . Когда элемент в позиции не равен 0, значит Артефакт еще не собран и его надо сохранить для сбора при переходе к этой карте. В тоже время, чтобы быть уверенным в появлении объекта Артефакт на следующей карте , нам нужно удалить его первым (тут что-то не догоняю). Когда же Артефакт поднимут, он (артефакт) не должен снова появиться. Можно загрузить исходный код и клипы отсюда. Ну, а здесь я добавил Врагов (простейший вариант), стрельбу, лестницы и сокровища. Для артефактов изменения в том, что ранее сбор Артефактов производился в функции moveChar, а теперь этот код перехал в конец функции updateChar , которой и не было. Если перестраивать основную версию этой главы, то нужно очень много всего добавлять. Поэтому лучше взять за основу пример главы 10 и добавить изменения, сделанные для Артефактов. (Объявление сокровищ, их создание в функции buildMap, сбор сокровищ в функции updateChar и расположение оставшихся медалек при смене карты функция changeMap. Единственное неудобство одно из сокровищ попало на стенку и теперь его оттуда не снять. Здесь два выхода (1) переместить местоположение сокровища (изменения в массиве описания артефактов) и (2) добавить возможность сбора сокровищ прямо с лестницы. Кстати вопросик, а что будет, если сокровище расположить в двери, сможет ли Герой взять его при расположении кода сбора сокровищ в конце функии updateChar? Правильно, не сможет. Код нужно размещать до вызова функции смены карты.) Исходный код с Врагами, стрельбой, попрыгушками и сокровищами можно загрузить отсюда. Исправление ошибок. 31.12.2003. Благодарности Джозу (José), нашедшему ошибку в коде артефактов при изменении карт. Проблема в том, что если артефакт не подняли, то объект артефакт не был удален в процессе смены карты и он присутствует на следующей карте, но клипа для его показа нет. Таким образом появляются невидимые сокровища. Я обновил исходный коди и клипы, но, пожалста,проверьте строки: var name = "item"+game.items[i][2]+"_"+game.items[i][1]; delete game[name];
В функции changeMap. Ошибка 09.08.2004. Примечание для версии Flash MX и выше. В версии Flash MX ключевое слово position используется для объектов . Если не хотите конфликтов, пожалста, замените имя position, используемое в учебнике на posi . Благодарность Роберту (Robert) за это. Есть вопросы - пишите мне на semikin@dionaholding.ru Читаем дальше - Глава 12. Платформы и лифты Возвращаемся на Начало учебника
|