SCRIPT.com.ua
Логин: Пароль:
Регистрация Забыл пароль
МАТЕРИАЛЫ
Поиск
Новости
Материалы
Работа с WDDX в РНР [PHP]
Рецепт по установке web-сервера под Windows [PHP]
Инициализация для Flash Player 8 Beta [Flash]
Криптование [Action Script]
Настрока Homesite под Action Script [Action Script]
Учитесь писать код правильно [PHP]
Пасхальные яйца. [Action Script]
Flash-игры: проще, если знаешь как [Flash]
Установка Ming под win32 Apache+PHP [Action Script]
Wysiwyg HTML Редакторы [DHTML]
Исходники
"Объект" на JavaScript - аналог AsBroadcaster [DHTML]
Запрет кэширования [HTML]
Полупрозрачные картинки, которые 'востанавливаются' при наведении. [DHTML]
Новостная лента v1.2.1 [PHP]
Обход XML-дерева [Action Script]
CDATA и комментарии [XSL]
Кроссразмерный полноэкранный режим [Action Script]
KeyListener [Action Script]
Редирект [HTML]
Текстовый узел [XSL]
Лаборатория
Документация
Файлы
Ссылки
Пользователи
Контакты
Наш выбор
Властелин Колец: Битва за Средиземье 2. Под знаменем Короля-чародея
Наши партнеры
Вторник, 19 Октября, 2004
Flash-игры: проще, если знаешь как [Flash]
Предисловие
Вспоминаю свои негодования, когда у меня ничего не получалось, или получалось, но не так как у других. Причиной тому, как сейчас приходится осознавать, была элементарная неопытность. Особенно если это касалось проектов, включающих в себя некую систему решений, взаимодействующих между собой. Разработка игр во Flash как раз и есть такая система – здесь и работа с графикой, обработка ввода-вывода, загрузка XML и программирование логики. Сразу все охватить довольно тяжело, а найти оптимальные решения почти нереально.
В статье описаны этапы создания многоуровневой логической игры «Сокобан», а особое внимание будет уделено импорту растра во Flash и загрузке XML-файлов.



«Сокобан» (в переводе с японского – «человек, заведующий складом», попросту – кладовщик) – игра известная и многими любимая, изобретенная в далеком 1982 году японцем Хироюки Химабаяши. В 1984 году была издана на территории Европы компанией SPECTRUM HOLOBYTE для компьютеров Apple и с тех пор обрела огромную популярность по всему миру. Существует множество ее разновидностей, но нас интересует самый простой вариант: игровое поле 8x8 с кирпичными стенами в виде преград; несколько ящиков, такое же количество мест под них; наш главный герой – бульдозер-ящикоукладыватель.
Предполагается, что читатель знаком с пакетом Macromedia Flash MX (хотя в некоторых местах детально описан процесс разработки), а также имеет возможность загрузить архив с исходниками по адресу: http://www.script.com.ua/temp/Ready.rar
Архив желательно скачать и распаковать в отдельную папку. По ходу после каждого логического завершения будет указан исходник, как пример того, что должно получится.

Макет игры
Сразу скажу, что рисовать нам не придется, так как учить вас этому не мне. Используем уже готовый макет под именем maket.gif, который находится в архиве. Его можно видоизменить до неузнаваемости или оставить как есть. Главное – оставить те же размеры. По сему, ищем в архиве наш макет, и приступим к импорту растра во Flash.

Импорт графики
Растровое изображение можно и нужно классифицировать. Не зря же в Web сосуществуют два основных формата: GIF (или PNG) и JPEG. Для уменьшения размера файла используют тот или иной формат. GIF подходит для изображений с малым количеством цветов и большими участками одного цвета, а JPEG – для фотографий и сложных рисунков. Flash понимает все эти форматы, но не всегда так, как хотелось бы. Часто растровые изображения искажаются, и виной этому антиэластинг, сглаживание. В некоторых случаях этого можно избежать, но опять же нет полной уверенности, что все и везде будет гладко.
Поэтому рассмотрим один их приемов внедрения пиксельной GIF (или PNG) графики во Flash. Многие знают этот прием, но теперь будут знать все :)

Итак, взглянув на макет, мы видим фоновое изображение, кнопки в нажатом и отжатом состояниях и элементы 20x20, из которых будут строиться уровни.

Создаем новый файл во Flash-редакторе. Размер рабочей области для данного случая – 260x180 пикселей. Далее File->Import, выбираем раскройку-макет (maket.gif). Прямая вставка графики с помощью Copy-Paste некорректна, так как искажается реальный размер картинки. Теперь картинку нужно раскроить (как на швейной фабрике, честное слово :)). Выделяем картинку и трейсим ее в кривые (Modify->Trace Bitmap...), установив параметры Color Treshold и Minimum Area равными 1. Curve Fit устанавливаем как Pixel. Теперь каждый пиксель есть не что иное, как векторный квадрат со стороной равной единице. Причем, сравнив размер макета в формате gif и скомпилированного swf-файла, можно убедится в целесообразности такого хода. И это еще не все прелести такого приема. Практически доказано, что прямая линия, нарисованная в Flash-редакторе будет увесистей такого же прямоугольника и более ресурсоемкой при прорисовке. Но самый главный аргумент – пиксельная графика красивее и качественней выглядит, чем линии с антиэластингом. Хотя есть и недостатки, – необходимо постоянно следить, чтобы все объекты на сцене не имели дробных координат (от этого можно в какой-то мере застраховаться, установив качество проигрывания ролика в “low”). Приняв это во внимание, продолжаем кроить графику.

Сначала удалим лишние белые поля, выделим фон для игрового поля, поместим его в отдельный слой на сцене и прибьем к левому верхнему краю. Можно смело заблокировать этот слой.
Дальше разберем кнопки. У каждой два состояния – отжатое и нажатое. Выбираем отжатую кнопку «заново» и жмем F8, Behavior определяем как Button, а контрольную точку ставим слева вверху (чтобы избежать дробных координат, такое расположение контрольной точки обязательно для всех объектов в клипе). Дальше копируем второе, нажатое состояние, заходим внутрь недавно созданной кнопки и вставляем ее в кадр “Down”. Проделываем ту же процедуру для кнопок со стрелками для листания уровней. Теперь создаем новый слой и закидываем все три кнопки в него, разместив их, согласно макету. Проследите, чтобы координаты были целыми числами. Для надежности включите привязку к пикселям (View->Snap to Pixels).

Осталось только залинковать некоторые элементы – их мы будем подгружать с библиотеки для построения игровых уровней.
Первой возьмем стену. Выделяем, жмем F8, Behavior определяем как Movie Clip, даем имя “wall”. Дальше – ящик. Ему даем имя “box”. Ящик с красным крестом, который сигнализирует, что он находится над целью, нужно поместить вторым кадром в только что созданный мувиклип “box”. Для каждого из кадров прописываем stop(). Синий крест тоже превращаем в мувик и даем ему имя “target”.
И последний спрайт – это наш главный герой и неутомимый труженик – бульдозер. Ему даем имя “macho” :). Его нужно отобразить в четырех положениях на протяжении четырех кадров. Порядок таков: вверх, вправо, вниз, влево. Для всех кадров прописываем stop().

Теперь удалим “wall”, “box”, “target” и “macho” из главной сцены и перейдем в библиотеку (F11). В библиотеке для каждого делаем такую процедуру: выделяем, кликаем правой клавишей мыши и выбираем Linkage..., ставим флажок Export for Action Script и жмем ОК. Имя каждого элемента в библиотеке будет его идентификатором на временной шкале.
Чтобы завершить композицию, нужно еще добавить пару текстовых полей на сцену. Одно динамическое текстовое поле помещаем под надписью «ходов», в списке шрифтов выбираем Verdana, размер – 18, в поле Var пишем step_txt. Второе вставляем между двумя кнопками листания уровней. В списке шрифтов выбираем Verdana, размер – 11, в поле Var пишем level_txt. Для обоих выравнивание устанавливаем по центру.

Все, компоновка закончена. Но, прежде чем приступить к скриптованию, уделим внимание формату XML...

Исходник этой стадии разработки в файле soco_100.fla.

Формат уровней.
Уровни хранятся в формате XML, что неудивительно :). Кроме формата файла нам нужно определиться и с форматом уровней. Согласно макету размер игровой области 8x8 квадратов, и, значит, для каждого уровня должна быть создана матрица 8x8. Обозначим элементы так:
_ (подчеркивание) – пустое место;
w – стена;
b – ящик;
t – цель;
m – игрок;

В XML уровень будет выглядеть так:
выделить
<stage_1>
<r>wwwwwwww</r>
<r>ww__tm_w</r>
<r>ww_wtw_w</r>
<r>ww___b_w</r>
<r>wwtbb_ww</r>
<r>ww__wwww</r>
<r>wwwwwwww</r>
<r>wwwwwwww</r>
</stage_1>
Каждый последующий уровень добавляется в конец XML-файла. При загрузке Flash сам определит их количество.

Создавая уровни, следует учитывать, что ящиков (b) и мест для них (t) должно быть равное количество (для уровней размером 8x8 неписаным правилом является три ящика и три места под них). Ну и, само собой, игрок (m) должен быть один.

Файл stage.xml в архиве содержит этот и еще пару десятков уровней для игры.

Прорисовка уровней
Не буду приводить здесь листинг всего кода загрузки и прорисовки уровня, разберем только некоторые места.
После события onLoad объекта stageXML вызывается функция drawStage(num), которая рисует уровень. Чтобы выудить и записать значения всех элементов в двумерный массив, запустим два цикла. В теле первого читаем строку, а внутри второго разбиваем ее на отдельные символы с помощью метода charAt():

выделить
...
for (j=0; j<8; j++) {
    tempString = stageXML.childNodes[num].childNodes[j].childNodes+"";
    for (i=0; i<8; i++) {
        stage_arr[i][j] = tempString.charAt(i);
    }
}
...
Анализируя заполненный массив – рисуем уровень. Необходимые элементы графики подгружаем из библиотеки:
выделить
...
if (stage_arr[i][j] == "w") {
stage_mc.attachMovie("wall", "wall_"+i+"_"+j, (i+1)*100+j, {_x:20*i, _y:20*j});
}
...
Исходник этой стадии разработки в файле soco_101.fla.

Управление
Минимальным набором для управления в игре есть четыре курсорные клавиши – вверх, вниз, влево, вправо. Кроме них мы заведем несколько горячих клавиш для наших кнопок: начать уровень заново – Space; PgUp и PgDown – для листания уровней. В итоге игрок не будет метаться от мышки к клавиатуре, что, согласитесь, намного удобнее.
Начнем с кнопки «Заново». Выделяем и вписываем туда вот такой код:
выделить
on (release, keyPress "<Space>") {
    //перерисовка
    drawStage(current_stage);
    //обнуляем счетчик ходов
    step_txt = 0;
}
Все просто – если кликнуть на кнопке или притопить пробел – текущий уровень (current_stage) рисуется заново. Для кнопок листания уровней код схож.

Исходник этой стадии разработки в файле soco_102.fla.

Теперь научим двигаться наш бульдозер. Воспользуемся методом addListener объекта Key.
Код будет выглядеть приблизительно так:
выделить
keyListener = new Object();
keyListener.onKeyDown = function() {
    //Вверх
    if (Key.getCode() == 38) {
        checkMove(0, -1);
        stage_mc.macho_mc.gotoAndStop(1);
    }
    //Вниз

    //Влево

    //Вправо

};
Key.addListener(keyListener);
Как видите, ничего сложного. Каждая клавиша обрабатывается, наш бульдозер крутится на месте, но не перемещается. Сложности начнутся дальше, после вызова функции checkMove(t_x, t_y). Ей передается два параметра – смещение по x и по y, в зависимости от направления движения. В двух словах, что происходит:
выделить
function checkMove(t_x, t_y) {
Получив параметры смещения, нужно проверить, что стоит на дороге. Дергаем массив – смотрим:
выделить
//что стоит на клетку вперед?
str_t = stage_arr[macho_poz_x+t_x][macho_poz_y+t_y];
//что там на две клетки дальше?
str_t2 = stage_arr[macho_poz_x+t_x*2][macho_poz_y+t_y*2];
Данные в массиве stage_arr представлены в виде имен мувиков-елементов уровня (например: box_12, wall_23). Извлекая первый символ с помощью строковой функции substr() определяем, что ждет его впереди…
Если на пути ящик и за ним свободно:
выделить
if (str_t.substr(0, 1) == "b" and str_t2.substr(0, 1) == "_") {
перемещаем ящик и бульдозер
выделить
}
если впереди пусто – перемещаем бульдозер вперед.
Если впереди стена или ящик, а за ним стена или еще один ящик – ни с места.

Полный листинг смотрите в исходнике soco_103.fla. И да помогут вам комментарии.

Последние штрихи
Осталось совсем немного – включить проверку прохождения уровня. За это отвечает функция Complete(), которая вызывается всякий раз, когда был перемещен один из ящиков. От нее требуется сопоставить два массива: stage_arr[][] – общий и stage_t_arr[][] для мишеней. Если координаты ящиков совпадают с координатами мишеней – уровень пройден, вызывается еще одна функция levelUp(), которая переносит игрока в следующий уровень.
По-хорошему надо бы уведомить пользователя, что, мол, – круто! – вы прошли уровень, но это уже вы можете проделать сами.

Исходник этой стадии разработки в файле soco_104.fla.

Вот, собственно, и все. У нас получилась маленькая и компактная (~ 5 Kb) головоломка. Для полноты ощущений можно добавить туда звуков, нарисовать заставку, сделать редактор уровней. Надеюсь, что эта статья поспособствует приумножению качественных и интересных игр.
Возможно возникнут вопросы – пишите и будут ответы.


Опубликовал: Syo (17:37) | комментарии [1]
< назад
Вверх © Copyright 2004-2014 Script.com.ua



Версия для печати