Создание Flash-игр

         

Пазл

Исходный файл: Jigsawpuzzle.fla

Игра "Пазл" состоит из элементов одного размера, которые, соединяясь, образуют целостное изображение. Обычно они сделаны из картона и для составления картинки требуется большая площадь, например, обеденный стол. Так как экран монитора слишком мал по сравнению со столом, создать компьютерный аналог такой игры очень сложно.
Однако в упрошенном варианте подобная игра вполне применима для Web-сайта в качестве развлекательного материала. На рис. 13.1 показан кадр ролика Jigsawpuzzle.fla. На игровом поле имеются 24 элемента картинки и пустая сетка, куда эти элементы должны быть помещены.

Рисунок 13.1 Пазл почти собран

Задача проекта

Цель проекта - создать простую, но от этого не менее интересную игру "Пазл". Игрок сможет перетаскивать элементы мозаики с границы рабочего поля на сетку. Когда элемент окажется около того места, где должен располагаться, он будет зафиксирован.

Подход

Для создания этой игры можно просто прикрепить небольшой сценарий к клипу "actions", расположенному вне рабочего поля. Когда пользователь щелкнет по рабочему полю, сценарий определит, какой элемент находится под курсором, затем этот элемент будет перетаскиваться с использованием стандартных возможностей Flash.
Когда кнопка мыши отпускается, код определяет, находится ли элемент мозаики рядом со определенным для него местом, и, если да, элемент фиксируется.
Сначала устанавливаем для всех клипов, содержащих элементы мозаики, свойство _alpha=75, чтобы они стали немного светлее. Затем, когда игрок поместит элемент на свое место, соответствующий клип станет полностью непрозрачным. Таким образом, будет обеспечена некая обратная связь с игроком, ему будет сообщаться, что элемент находится на своем месте. Также будет проверяться, является ли элемент мозаики полностью непрозрачным в тот момент, когда пользователь щелкает по нему мышкой и начинает перетаскивать. Это необходимо, чтобы те элементы, которые уже находятся на своем месте, больше не перемешались.
Узнать, находится элемент на своем месте или нет, несложно, потому что они сделаны таким образом, чтобы их центр находился в центре основной картинки. Например, у элемента из верхнего левого угла центр будет правее и ниже (рис. 13.2).
Теперь представьте, что каждый элемент создан именно так. Центр элемента останется в центре картины не зависимо от того, где он будет располагаться. Если вы не совсем поняли, что я имею в виду, просмотрите исходный ролик Jigsawpuzzle.fla. Изучите несколько клипов, содержащих элементы мозаики, и увидите, что центр остается постоянным.
Это намного упрощает код. Каждый элемент должен быть помещен точно на свое место, чтобы вписаться в контур картинки. Так что способ определения надлежащего положения элемента будет одинаковым для всех клипов.

Рисунок 13.2 Центр этого элемента определяется по отношению к центру всей картинки

Подготовка ролика

Так как же я создал 24 элемента в игре? На самом деле, это была самая сложная часть работы. Однако здесь нет ничего сверхъестественного. просто данный процесс отнимает много сил. /Зля тех, кто хочет знать, я постараюсь объяснить. Нет одного универсального способа создания элементов с помощью Flash-графики, каждый выбирает то, что ему больше нравится.
Я начал с изображения, которое представляло собой набор линий и областей на одном слое, после чего преобразовал все линии в области, так чтобы в изображении остались только сплошные области.
Затем я создал кадр для мозаики (см. рис. 13.1). Я нарисовал только небольшую часть сетки вдоль направляющих Flash, затем скопировал и вставил этот кусочек несколько раз, так что получилось очертание картинки (как в пазле).
Затем каждую область сетки залил красным цветом и выделил все залитые области, кроме той, которая предназначена для элемента мозаики в верхнем правом углу. Скопировал выделение и вставил его в верхнюю часть моей картинки. Потом выделил и удалил всю красную область, таким образом, на рабочем поле остался только один элемент.
Так как мои действия уничтожили созданное ранее, я сохранил копии очертания и картинки в других слоях. Теперь я могу повторить эти действия для создания следующей картинки. Для 24 элементов пришлось проделать это 24 раза.
Когда все было сделано и получилось 24 клипа, понадобилась сетка для повторного выравнивания элементов, так чтобы их центр располагался в нужном месте. Для завершения мне понадобилось 20 минут. Однако, возможно, вы сделаете то же самое гораздо быстрее. ,
После того как у меня получились все элементы, я поместил экземпляр каждого клипа на рабочее поле и присвоил экземпляру клипа имя, соответствующее имени самого клипа. 24 элемента называются от "0-0" до "5-3" в зависимости от вертикального и горизонтального положения элемента. Однако я разместил элементы вокруг границы рабочего поля в произвольном порядке. Также каждому клипу присвоил значение _apha=75. Затем я поместил клип контура картинки в центр и назвал его "outline".

Создание кода

Весь сценарий прикреплен к клипу "actions", расположенному за пределами рабочего поля. Он начинается с обработчика событий onClipEvent (mouseDown), который реагирует на щелчок мыши по рабочему полю.
Этот код просто просматривает элементы картинки и определяет, находится ли один из них под курсором, а также является ли элемент полностью непрозрачным, то есть размещен ли на своем месте.
Если элемент найден, программе Flash сообщается, что теперь он подвижный и может перемещаться с помощью команды startDrag. Затем программа завершается.

Команда startDrag - основное действие, позволяющее пользователю перетаскивать клип. Оно не такое универсальное, как методы перетаскивания, рассмотренные ранее, но в простых случаях работает хорошо. Команда stopDrag останавливает перетаскивание.

onClipEvent(mouseDown) {
// Определяем положение курсора.
mx = _root._xmouse;
my = _root._ymouse;
// Просматриваем все элементы картинки,
for (x=0;x<6;x++) {
for(y=0;y<4;y++) {
piece = _root[x+"-"+y];
// Выясняем, находится ли элемент под курсором
// и не находится ли он уже на своем месте?
if (piece.hitTest(mx,my) and (piece._alpha < 100)){
// Пользователь щелкнул по элементу.
piece.startDrag();
// Выходим из циклов.
х = 6 ;
У = 4;
break;
}}
}}

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

onClipEvent(mouseUp) {
// Прекращаем перемещение элемента.
stopDrag();
// Измеряем расстояние от центра элемента до центра контура.
dx = _root.outline._x - piece._x;
dy = _root.outline._x - piece._y;
dist = Math.sqrt(dx*dy+dy*dy);
// Если расстояние меньше 10 пикселов,
// элемент помещается на свое место,
if (dist < 10) {
piece._x = _root.outline._x;
piece. _y = _root.outline._y;
// Делаем элемент полностью непрозрачным,
piece._alpha = 100;
}
}

Другие возможности

Эта игра - самая простая из программ составных картинок-загадок, Вы без труда можете ее усовершенствовать. Например, можно зaпoминать исходное положение элемента при перетаскивании, а затем возвращать его на место, если игрок неправильно поместил его.
Еще один способ сделать игру интереснее - написать функцию, которая будет проверять, все ли элементы уже находятся на своем месте и если да, будет осуществлять переход к кадру с поздравлением с победой. Можно усложнить игру, создав более 24 кусочков, тем самым получив больше мелких элементов.
Если хотите, позвольте игроку поворачивать каждый элемент на 90°, 180° или 270°. Для этого пользователь мог бы нажимать клавишу Пробел. Элемент будет фиксироваться в своем положении только в том случае, если он правильно повернут.
Конечно, есть более сложные варианты, например, картинки-загадки, у которых нет очерченного контура. Игрок может соединить два или более элементов в любом месте экрана, а затем прикрепить их к целой картине. Однако для такой игры потребуется написать большой сценарий. Вместо этого давайте перейдем к другому виду составления картинок.

Пятнашки

Исходный файл: Slidingpuzzle.fla

В отличие от пазла игра "Пятнашки" куда интереснее в качестве компьютерной игры, чем в виде обычной игры. "Пятнашки" обычно состоят из 15 квадратных элементов, которые перемешаются вдоль сетки, рассчитанной на 16 элементов. Пустое место - дополнительная область, куда может быть перемещен элемент мозаики.
На рис. 13.3 показана мозаика с изображением лисы. Попробуйте сыграть в эту игру, открыв файл Slidingpuzzle.fla. Вы можете щелкнуть по любому из четырех элементов, смежных с пустым квадратиком, чтобы переместить его. Цель игры - правильно собрать картинку, оставив пустым место в нижнем правом углу.

Рисунок 13.3 В "Пятнашках" используется 15 элементов и один пустой квадрат

Задача проекта

Цель проекта - создать простую, легкую игру по принципу "Пятнашек". Игрок будет щелкать по элементу: если рядом есть пустой квадрат, элемент будет перемешен.
Очень важно в начале игры случайным образом расположить элементы. Для этого Flash-ролик сначала нарисует все элементы мозаики на своих местах, а затем будет выполнено 100 произвольных перемещений. Таким образом, элементы окажутся перемешаны, и собрать такую мозаику будет сложно, но возможно.

Подход

Большая часть рассматриваемой программы представляет собой по сути подготовку к собственно игре, обеспечивая перемешивание элементов мозаики. Сначала случайным образом выбирается элемент. Потом выполняется проверка, является ли один из четырех смежных элементов пустым. Если да, то выбранный элемент перемещается туда. В противном случае выбирается другой элемент до тех пор, пока не будет найден элемент, смежный с пустым квадратом. Этот процесс повторяется 100 раз.
Когда перемешивание закончено, пользователь может передвигать элементы сам. Когда он щелкает по элементу, код проверяет, есть ли рядом с этим элементом пустой квадрат, если да, выбранный элемент перемещается туда.

Подготовка ролика

Можно воспользоваться любым понравившимся вам методом создания элементов. Чтобы получить 15 элементов, я выделял квадраты на графическом изображении. В отличие от элементов составной картинки-загадки здесь не нужно размешать их определенным образом. Центром каждого элемента мозаики может бьпъ его собственный геометрический центр. То есть для этой игры создать элементы гораздо проще.
После того как вы создали все элементы, поместите их на рабочее поле так, как они должны располагаться в собранной мозаике. Я сделал кусочки размером 54x54 пиксела, то есть они должны бьпъ расположены друг от друга на расстоянии 54 пиксела как по вертикали, так и по горизонтали. Поскольку Flash не гарантирует точность при размещении клипов вручную, даже если показана сетка, выравнивать элементы перед началом игры лучше с помощью ActionScript.
Очень важно поместить элементы близко к их исходному положению и присвоить им имена. Я дал им имена от tilel до tileis, чтобы к ним можно было обращаться в коде программы.

Создание кода

Большая часть кода находится в основной временной шкале. Он начинается с выравнивания элементов на расстоянии точно в 54 пиксела, затем 100 раз выполняется цикл, перемещающий случайно выбранный элемент на пустую позицию.

function initGame() {
// Устанавливаем горизонтальное и вертикальное расстояние
// между элементами.
tileDist = 54;
// Помещаем все элементы на свои места,
for (x=l;x<=4;x++) {
for (y=0;y<=3;y++) {
tile = х+у*4;
_root["tile"+tile];
_x = x*tileDist;
_root["tile"+tile];
_y = y*tileDist+tileDist;
}}
// Совершаем 100 произвольных перемещений,
for(tilenum=0;tilenum<100;tilenum++) {
do {
// Выбираем элемент случайным образом.
tile = "tile"+(random(15)+1);
//- Проверяем, есть ли рядом свободный квадрат.
emptySpace = findEmpty(tile);
// Цикл продолжается до тех пор, пока не будет найден
// элемент, рядом с которым расположен свободный квадрат.
} while (emptySpace == "none");
// Перемещаем элемент на свободное место.
moveTile(tile,findEmpty(tile));
}}

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

// Проверяем, есть ли свободное место около данного элемента,
function findEmpty (tile) {
// Определяем положение элемента.
tilex = _root[tile]._x;
tiley = _root[tile]._y;
// Проверяем, есть ли элемент мозаики слева,
if (tilex > tileDist) {
if (!tileThere(tilex-tileDist, tiley)) {
return("left");
}}
// Проверяем, есть ли элемент мозаики справа,
if (tilex > tileDistM) {
if (!tileThere(tilex+tileDist, tiley)) {
return("right");
}} // Проверяем, есть ли элемент мозаики сверху. if (tiley > tileDist) { if (!tileThere(tilex, tiley-tileDist)) { return)"above");
}}
// Проверяем, есть ли элемент мозаики снизу,
if (tiley > tileDistM) {
if (!tileThere(tilex, tiley+tileDist)) {
return("below");
}}
// Элементы мозаики имеются со всех сторон,
return ("none");
}

Если перед выражением стоит восклицательный знак, значит, OHO отрицается, то есть true превращается в false, a false в true. Эта операция известна как логическое не (not). Например, в предыдущем коде проверяется не tileThere, a not tileThere.

Функция findEmpty использует метод tileThere, чтобы определить, находится ли элемент на определенном месте. Метод tileThere вызывается для определения элементов слева, справа, снизу и сверху.

// Проверяем, находится ли элемент мозаики на определенном месте,
function tileThere (thisx, thisy) {
// Просматриваем элементы на предмет совпадения координат,
for (i=l;i<=15;i++) {
// Выясняем, совпадают ли значения положения
//по горизонтали,
if (_root["tile"+i]._x == thisx) {
// Совпадает ли положение по вертикали,
if (_root["tile"+i]._у == thisy) {
return true;
}
}} // Эти координаты соответствуют пустому квадратику,
return false;
}

После того как было решено переместить элемент, вызывается функция moveTile. Эта же функция используется, когда игрок перемешает элементы.

// Перемещаем элемент в определенном направлении,
function moveTile (tile, direction) {
if (direction == "above") {
_root[tile]._y -= tileDist;
} else if (direction == "below") {
_root[tile]._y += tileDist;
} else if (direction == "left") {
_root[tile]._x -= tileDist;
} else if (direction == "right") {
_root[tile]._x += tileDist;
}}

После того как контроль передается игроку, надо определить, по какому элементу щелкнули мышкой. Для этого вызывается функция tileUnderMouse.

// Определяем, по какому элементу щелкнул игрок,
function tileUnderMouse О {
for (i = l; i< = 15; i + +) {
if (_root["tile"+i].hitTest(_xmouse, _ymouse)) {
return (i);
}
}}

Сценарий в основной временной шкале заканчивается вызовом функции initGame и выводом на экран перемешанных элементов.

initGame();
stop();

Игрок взаимодействует с картинкой мозаики посредством клипа "actions», расположенным вне рабочего поля. Клип воспринимает щелчок мыши, определяет, по какому элементу щелкнул пользователь, и перемещает этот элемент.

onClipEvent (mouseDown) {
// Определяем, по какому элементу щелкнул пользователь.
tileClicked = _root.tileUnderMouse();
// Определяем, есть ли рядом пустое пространство.
emptySpace = _root.findEmpty("tile"+tileClicked);
// Перемещаем элемент на свободное место.
_root.moveTile("tile"+tileClicked, emptySpace);
}

К сведению

В рассмотренном варианте игры элементы мозаики расположены друг от друга на расстоянии 54 пиксела, а игровое пространство представлено сеткой 4x4. Если вы хотите изменить один из этих параметров, необходимо тщательно проверить код и внести необходимые изменения.

Другие возможности

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


Игра совпадений

Исходный файл: Matching.fla

Следующая программа, наверное, является самой популярной Web-игрой. Существуют ее варианты, созданные с помощью Shockwave, Flash, Java, JavaScript и даже простого HTML с применением CGI. Такую игру просто создать, в нее быстро привыкаешь играть и ее легко можно приспособить для любого сайта или ситуации.
Игра совпадений (или игра памяти, как ее иногда называют) использует сетку с картами, расположенными рубашками вверх. Существует две карты каждого типа. Игрок может одновременно открыть две карты. Если они совпадают, карты удаляются. В противном случае обе карты снова переворачиваются рубашками вверх. Игрок пытается запомнить, где какая карта расположена, чтобы было проще отыскать совпадения.
На рис. 13.4 показан фрагмент этой игры (файл Matching.fla): в ней 36 карт, из которых четыре уже удалены и две только что открыты. Эти две карты не совпадают, следовательно, они снова будут перевернуты, как только игрок выберет следующую карту.

Рисунок 13.4 Цель игры совпадений - удалить все карты, чтобы стала видна фоновая картинка

Задача проекта

Цель проекта заключается в создании простой, но при этом каждый раз разной игры совпадений. Игрок сможет выбрать одну карту, затем другую. Каждая карта будет перевернута при щелчке мышью, так что будет видна ее картинка. Если карты совпадают, они обе удаляются, в противном случае снова переворачиваются, как только пользователь выберет следующую карту.

Подход

В игре используется только два библиотечных элемента. Первый – клип, в первом кадре которого представлена рубашка карты. В остальных кадрах содержатся картинки. Так как будет 18 различных картинок, в клипе окажется 19 кадров. Если вы хотите, чтобы клип отобразил рубашку, карты, перейдите к первому кадру; если хотите увидеть картинку, перейдите к одному из кадров 2-19.
Второй элемент библиотеки - кнопка, расположенная внутри карт клипа Она будет использоваться для реагирования на действия пользователя.
Игра начинается с создания 36 клипов, помещенных в сетку на рабочем поле. Каждый клип отображает рубашку карты, но если карта перевернута, показывается другая картинка. Каждая картинка будет содержаться в двух клипах, таким образом, получится 18 пар карт.
Когда игрок выбирает первую карту, отображается соответствующая ей картинка. Когда игрок выбирает вторую карту, она тоже переворачивается и появившаяся картинка сравнивается с первой открытой картой. Если они совпадают, карты удаляются, в противном случае ничего не произойдет до тех пор, пока игрок не щелкнет еще раз. Тогда первые две карты переворачиваются обратно, и отображается картинка новой выбранной карты.

Подготовка ролика

В ролике Matching.fla есть клип "Cards", временная шкала которого содержит 19 кадров (рис. 13.5).

Рисунок 13.5 Во временной шкале клипа "Cards" имеется 19 кадров, первый без картинки и остальные 18 с различными картинками

В первом кадре расположена рубашка карты, то есть никакой картинки нет. В остальных 18 кадрах содержатся изображения, соответствующие разным картам.
Кнопка - просто прямоугольник такого же размера, что и карта. Она расположена в третьем слое клипа "Cards" (см. рис. 13.5), то есть за фоном.
Хотя кнопку не будет видно, она будет реагировать на действия пользователя.
Также в клипе "Cards" присутствует фон. У первого кадра, содержащего рубашку карты, фон серый. У остальных кадров, в которых находится какая-либо картинка, белый фон.

Создание кода

Почти весь код этой игры находится в основной временной шкале. Ролик начинается с вызова функции initGame, которая создает список 18 пар карт, случайным образом выбирает карты из первого списка, а затем помешает их во второй список, чтобы перемешать колоду карт.
Потом функция создает 36 карт. Каждый клип автоматически начинается с того, что карта помещается рубашкой вверх, а свойству клипа ("picture") присваивается номер картинки, которую карта будет представлять.

initGame();
stop();
function initGame() {
// Создаем отсортированный список карт.
cardsListOrdered = [];
cardsListOrdered.push(i,i);
}
// Список перемешанных карт.
cardsListSorted = [];
while (cardsListOrdered.length > 0) {
r = int(Math.random()*cardsListOrdered.length);
cardsListSorted.push(cardsListOrdered[r]};
cardsListOrdered.splice(r,1);}
// Создаем клипы карт и определяем их положение и картинки,
х = 0; У = 'О; for(i=0;i<36;i++) {
attachMovie("card", "card" + i, i) ;
_root["card"+i].picture = cardsListSorted[i];
_root["card"+i]._x = x*60+200;
_root["card"+i]._y = y*60+50;
// Переходим к следующей карт
х++;
if (х > 5) {
х = 0;
У++;
}} // Располагаем эти две карты рубашками вверх,
firstclip.gotoAndStop(1);
secondclip.gotoAndStop(1);
firstclip = 0; secondclip = 0;
firstdip = 0;
}

Обратите внимание, что с помощью команды push в массив можно добавить сразу более одного элемента, Например, выражение myArray.push(7,12) добавит в массив myArray числа 7 и 12.

Функция initGame заканчивается тем, что обнуляется переменная firstclip. В этой переменной содержится ссылка на карту, по которой щелкнули первой. Когда щелкают по клипу, кнопка внутри этого клипа отреагирует и на основную временную шкалу с помощью функции clickCard будет добавлена ссылка к клипу.
Функция clickCard может выполнить одну из 3-х функций. Если значение переменной firstclip равно 0, ей присваивается клип, по которому щелкнули, карта переворачивается, то есть программа переходит к кадру, содержащему соответствующую картинку.
Если в переменной firstclip хранится ссылка на некий клип, значит, одна карта уже перевернута. В этом случае программа пepeвopaчивает и вторую карту, присваивает переменной secondclip значение клипа и сравнивает два клипа. Если они совпадают, оба клипа удаляются.
Третье условие, которое, на самом деле, проверяется до двух первых, возникает тогда, когда игрок щелкает по одной и той же карте дважды. В таком случае значение переменной clip будет равно firstclip. Карта просто снова переворачивается и значение firstclip обнуляется.
Прежде чем проверить эти три условия, функция clickCard определяет, перевернуты ли уже две карты. Если да, значит, игрок уже выбрал две карты, но они не совпали. Прежде чем перевернуть следующую карту, эти две карты поворачиваются рубашками вверх

function clickCard (clip){
// Проверяем, отображены ли две карты,
if (secondclip != 0) {
// Располагаем эти две карты рубашками вверх,
firstclip.gotoAndStop(1);
secondclip.gotoAndStop(1);
firstclip = 0;
secondclip = 0;
}
// Проверяем, щелкнул ли пользователь дважды
//по одной и той же карте,
if (firstclip == clip) {
// Переворачиваем карту,
firstclip.gotoAndStop(1);
firstclip = 0;
// Выясняем, есть ли хоть одна перевернутая карта.
} else if (firstclip == 0); {
// Переворачиваем первую карту,
clip.gotoAndStop(clip.picture+1);
firstclip = clip;
// Одна карта должна быть перевернута
} else {
// Переворачиваем вторую карту.
clip.gotoAndStop(clip.picture+1);
secondclip = clip;
// Проверяем, совпадают ли карты.
if (firstclip.picture == secondclip.picture) {
// Удаляем обе карты.
firstclip.removeMovieClip();
secondclip.removeMovieClip();
firstClip = 0;
secondclip = 0;
}
}}

Вот все, что нужно для игры. У кнопки внутри клипа "Cards" только одна строчка кода, которая передает основной временной шкале информацию о том, что по клипу щелкнули.

on (press) {
// Передаем основной временной шкале информацию о щелчке мышью
_root.clickCard(this);
}

К сведению

Не забудьте вставить команду stop () в первый кадр клипа "Cards". В противном случае во всех картах будут отображаться все картинки.

Другие возможности

Самый простой способ изменить эту игру - добавить фоновый рисунок, который будет отображаться за картами. Картинки на картах могут соответствовать теме фоновой картинки. Вы можете выбрать практически любую тему. Также в первый кадр клипа "Cards" нетрудно добавить картинку для рубашки карты.
Хотя в примере 36 карт, ничто не мешает вам уменьшить или увеличить это число. Просто не забудьте откорректировать размер сетки, а также длину массива в начале игры. Если число карт не будет вписываться в квадратную сетку, вам понадобится изменить код или написать новый, чтобы определить расположение карт.
Еще одна возможность - использовать четыре однотипные карты, а не две. Так будет гораздо проще найти совпадения.
Если вы хотите, чтобы игра определяла, когда найдены все совпадения, добавьте счетчик, который будет увеличиваться при каждом совпадении. Когда счетчик станет равен 18, игра закончится. Затем можно перейти к кадру "you win".


Найди картинку

Исходный файл: Findthepicture.fla

Эта игра необычная, ее можно найти скорее в книге пазлов, чем на компьютере. Создание Flash-версии этой игры помогает показать несколько полезных приемов.
В игре "Найди картинку" игрок ищет не целую картинку, а ее сегмент. Целиком картинка показана; справа, а слева показана ее увеличенная часть. Задача состоит в том, чтобы быстро найти место увеличенного сегмента на целой картинке.
Игра показана на рис. 13.6. Сегмент слева выбран случайно и увеличен в три раза. Игрок должен щелкнуть по соответствующему месту большой картинки. В зависимости от того, насколько быстро он нашел правильное место, начисляются дополнительные очки.

Рис. 13.6 В этой игре ваша задача найти место маленького изображения слева на большом изображении справа

Задача проекта

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

Подход

Способ, каким сегмент картинки отображается на экране, основан на использовании слоев. В клипе картинка находится на одном слое, а маленький квадрат используется как маска для этого слоя. Только та часть картинки, которая находится под квадратом, оказывается видимой, когда клип отображается на экране.
Картинка имеет размер 400x300. Квадрат - размер 36x36. Когда картинка передвигается под квадратиком маски, видна только та часть картинки размером 36x36, которая находится под квадратом. Хотя перемещение
картинки сделано в ActionScript, маска создана во временной шкале клипа во время подготовки ролика.
Когда пользователь отмечает положение сегмента на целой картинке, ему нужно щелкнуть по этому месту. Было бы естественно расположить на этом месте невидимую кнопку, дело только в том, что кнопка должна сама себя уничтожить, поскольку курсор пользователя заменяется на руку. Вместо этого поместите обычный клип на это место и используйте hitTest, чтобы определить, когда по нему щелкнут.
В ролике используются Flash МХ-листенеры, чтобы поместить весь код в главную временную шкалу. Это значит, что реакция на щелчок мыши и обслуживание изменяющегося таймера должны быть частью сценария главной временной шкалы, а не одного из "actions''-клипов.

С помощью Flash MX и Flash 6 плеера стало возможным делать почти что угодно с помощью всего лишь одного сценария в главной временной шкале. Для этого необходимо регистрировать события, такие как onMouseUp и onEnterFrame, в функциях. Это может заменить обработчик onclipEvent в "actions''-клипах. Но поскольку эта технология не совместима сверху вниз с Flash 5, может пройти некоторое время, прежде чем она начнет широко применяться.

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

Подготовка ролика

Имя эталона основного клипа в библиотеке — "picture". Он содержит три растровых изображения, по одному в каждом кадре. В первом кадре находится команда stop (). Картинки выстроены так, что верхний левый угол каждой располагается в центральной точке клипа.
Клип "picture" никогда не находится в рабочем поле сам по себе, а внутри двух других клипов: "fullPicture" и "maskedPicture".
В клипе "fullPicture", клип "picture" находится на одном слое, а маленький квадратный клип "button" - поверх него в другом слое.
В клипе "maskedPicture" клип "picture" также находится на одном слое, а клип "button" - на другом. Однако слой кнопки - это слой-маска, маскирующий слой картинки. Это значит, что только сегмент картинки под квадратом остается видимым, когда клип "maskedPicture" расположен в рабочем поле.
В рабочем поле клипы "fullPicture" и "maskedPicture" расположены бок о бок. Размешать клип "maskedPicture" достаточно сложно, поскольку, когда вы его двигаете, он показывает свои границы, которые довольно велики и покрывают все рабочее поле. Як тому же увеличил этот клип до 300%, что сделало его еще больше.
Главная временная шкала содержит четыре кадра. Первый - это страница с правилами. Потом идет кадр "play". Когда игрок заканчивает одну картинку, ролик переходит к кадру "next", чтобы дать игроку передохнуть перед следующей картинкой. Последний кадр - это кадр "game over".
В ролике используются два динамических текстовых поля. Первое, displayBonus, используется в кадре "play". Поле displayScore используется в кадрах "next" и "game over".

Создание кода

В начале ролика задаются функции roundNum и score. Переменная roundNum содержит номер картинки, которая должна появиться.

// Начинаем с первой картинки.
roundNum = 1;
score = 0;
stop();

Игра начинается, когда пользователь нажимает кнопку в первом кадре. Все коды содержатся на главной временной шкале, в первом слое. Нажатие кнопки вызывает функцию setUpRound.
После того как функция отправляет ролик к кадру "Play", она определяет два клипа. Содержащийся в каждом из них клип "picture" устанавливается в кадр, определяемый переменной roundNum.
После этого выбирается случайное место на картинке. Это происходит с учетом того, что площадь сегмента 36x36, таким образом, это случайное место должно быть не ближе 18 пикселов от края изображения.
В клипе "maskedPicture" положение картинки изменяется таким образом, что случайное место располагается в позиции (0,0), на которой располагается квадрат-маска. Таким образом, если сегмент выбрана из позиции (100, 150), то увеличенная картинка должна быть сдвинута на -100 пикселов по горизонтали и на -150 - по вертикали.
В клипе "fullPicture" картинка остается неподвижной, а движется клип "button", пока не займет нужное положение. Свойство _alpha равно 0, чтобы кнопка была невидимой.

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

function setUpRound(pictureNum) {
// Переходим к кадру игры. gotoAndStop("Play");
// Выбираем картинку в обоих клипах.
fullPicture.picture.gotoAndStop(pictureNum);
maskedPicture.picture.gotoAndStop(pictureNum);
// Задаем случайное положение картинки.
w = fullPicture._width;
h = fullPicture._height;
x = Math.random()*(w-36)+18;
у = Math.random))*(h-36)+18;
// Передвигаем картинку под маской в это положение.
maskedPicture.picture._x = -х;
maskedPicture.picture. _y = -у;
// Задаем координаты кнопки.
fullPicture.button._x = х;
fullPicture.button._y = у;
// Делаем кнопку невидимой.
fullPicture.button._alpha = 0;
// Запускаем таймер.
startTime = getTimer();
}

В конце функции setupRound. переменной startTime присваивается текущее время. Это время используется следующим фрагментом кода, который все время пересчитывает бонусные очки. Он берет текущее время,вычитает startTime, а потом вычитает итог из 30000 миллисекунд. В результате бонусное время начинается с 30000 миллисекунд и происходит обратный отсчет до 0. Вместо того чтобы поместить этот процесс в клип "actions", я просто назначил функцию событию onEnterFrame. Это новый прием, появившийся в версии MX.

// Пересчитывем бонусные очки при каждом обращении к кадру.
_root.onEnterFrame = function!) {
// Бонус равен 30000 минус значение startTime.
bonus = 30000-Math.floor(getTimer() - startTime);
if (bonus< 0) bonus = 0;
displayBonus = "BONUS: "+bonus;
}

Другое событие, нуждающееся в отслеживании, это onMouseDown. Когда оно происходит, используется hitTest, чтобы определить, нажал ли пользователь на скрытую кнопку. Если да, то кнопка становится видимой (полупрозрачной) и ролик переходит к другому кадру. Количество бонусных очков прибавляется к общему количеству, и очки показываются на экране.

// Определяем функцию, отслеживающую нажатие кнопки мыши
// (листенер).
- _root.onMouseDown = function!) {
// Смотрим,щелкнул ли пользователь по мыши,
if (fullPicture.button.hitTest (_root ._xmouse,_root ._ymouse)) {
// Смотрим, была ли кнопка спрятана,
if (fullPicture.button._alpha < 50) {
// Показываем кнопку.
fullPicture.button._alpha = 50;
// Начисляем очки, score += bonus;
displayScore = "SCORE:"+score;
i f (roundNum < 3) {
// Если не все картинки пройдены,показываем
// следующую.
gotoAndStop("next");
} else{
// Если была последняя - заканчиваем игру.
gotoAndStop("game over");
}}
}}

К сведению

Клип "maskedPicture", кроме маски и картинки, содержит еще границы слоя, соответствующие маске. Это помогает ему выделяться на экране. Также в каждом кадре ролика содержатся статичные участки текста, объясняющие играющему, что происходит.
Вы можете задать свойства каждого растрового изображения, чтобы определить уровень сжатия и сглаживание. Вам придется потрудиться, пока вы не добьетесь удовлетворительных результатов.

Другие возможности

Вам должно быть легко добавлять картинки в эту игру. Вы можете иметь их столько, сколько хотите. Только помните, что надо установить код, узнающий последнюю картинку в обработчике onMouseDown.
Вы также можете сделать клип "button" больше, чем 36x36. Помните только, что тогда вам придется переделать функцию setUpRound так, чтобы она помещала кнопку дальше, чем на 18 пикселов от каждого края.
Вместо растрового изображения вы можете использовать векторный рисунок. Это сделает игру более простой и доступной для маленьких детей. Сделав соответствующее оформление и добавив анимационное вступление, можно создать хорошую игру даже для самых маленьких детей, которые еще не умеют читать.