JavaScript для детей — страница 29 из 48

treasuremap.png, которое

находится на сайте издательства No Starch Press.

В строке , после img, мы добавили пустой элемент p, задав ему id

"distance" (расстояние). В этот элемент мы будем с помощью JavaScript

выводить текст подсказок, сообщающих игроку, насколько он близок

к цели.

Выбор случайного места для клада

Теперь давайте писать JavaScript-код игры. Первая

наша задача — выбрать на карте случайное место для

клада. Поскольку размер карты 400 × 400 пикселей,

координаты ее верхнего левого угла равны { x: 0,

y: 0 }, а координаты нижнего правого угла — { x: 399,

y: 399 }.

Получение случайных значений

Чтобы указать на карте сокровищ случайную точку, нам нужно выбрать

случайное значение в диапазоне от 0 до 399 для координаты x и случай-

ное значение в том же диапазоне для координаты y. Для этого напишем

функцию, которая принимает размер в качестве аргумента и возвращает

случайное число от 0 до этого размера (но не включая его):

Get random

var getRandomNumber = function (size) {

number —

return Math.floor(Math.random() * size);

взять

};

случайное

число

Size — размер

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

значений в предыдущих главах. Мы генерируем случайное число от 0

до 1 с помощью Math.random, умножаем его на аргумент size и затем

используем Math.fl oor для округления до ближайшего снизу целого

числа. Далее мы возвращаем полученный результат из функции. Вызов

getRandomNumber(400) вернет случайное число от 0 до 399, что нам

и требуется .

168 Часть II. Продвинутый JavaScript

Задаем координаты клада

Теперь используем функцию getRandomNumber для задания координат

клада:

 var width = 400;

var height = 400;

 var target = {

Target — цель

x: getRandomNumber(width),

y: getRandomNumber(height)

};

Во фрагменте кода начиная со строки  задаются переменные width

и height, соответствующие ширине и высоте элемента img, который мы

используем в качестве карты. В строке  мы создали объект под назва-

нием target с двумя свойствами x и y, обозначающими координаты

клада. Значения x и y мы получаем из функции getRandomNumber.

Каждый раз при запуске этого кода мы получим новую случайную

позицию на карте и координаты этой позиции будут сохранены в свой-

ствах x и y переменной target.

Обработчик кликов

Обработчик кликов — функция, которая будет вызываться каждый раз,

когда игрок кликнет по карте. Начнем писать эту функцию со следую-

щего кода:

$("#map").click(function (event) {

// Здесь будет код обработчика

});

Сначала мы используем $("#map"), чтобы найти карту (поскольку

"map" — это id элемента img), а затем указываем обработчик кликов.

Всякий раз, когда игрок кликнет по карте, начнется выполнение тела

функции между фигурных скобок. Информация о клике будет передана

в функцию через аргумент event.

В обработчике нужно выполнить несколько действий: увеличить

счетчик кликов, вычислить, насколько точка клика отстоит от коорди-

нат клада, и отобразить сообщения. Перед тем как писать код обработ-

чика, мы создадим переменные и функции, которые помогут нам запро-

граммировать нужные действия.

11. Пишем игру «Найди клад!» 169

Подсчет кликов

Первое, что должен делать обработчик, — отслеживать число кликов.

Для этого нам понадобится переменная clicks, которую мы создадим

в начале программы (за пределами кода обработчика) и присвоим ей

значение 0:

var clicks = 0;

В код обработчика кликов мы включим команду clicks++, чтобы

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

Вычисляем расстояние от клика до клада

Чтобы выяснить, «горячо» или «холодно» (вблизи клада сделан клик или

далеко от него), нужно найти расстояние между точкой клика и местом,

Get distance —

где лежит клад. Для этого создаем функцию getDistance, вот такую:

получить

расстояние

var getDistance = function (event, target) {

var diffX = event.offsetX - target.x;

var diffY = event.offsetY - target.y;

return Math.sqrt((diffX * diffX) + (diffY * diffY));

};

0

1

2

3

4

5

Функция getDistance принимает

0

x

два аргумента: event и target. Объект

event — тот же самый, что передается

1

обработчику кликов, и в нем содержится

diffX = 3 – 1

информация о событии. В частности, это

target: (1, 2)

= 2

свойства offsetX и offsetY, хранящие

2

x- и y-координаты клика — как раз они

diffY = 3 – 2

нам и нужны.

= 1

В коде функции переменная diffX

3

event: (3, 3)

хранит горизонтальное расстояние между

кликом и кладом, которое мы получаем,

4

вычитая target.x ( x-координата клада)

из event.offsetX ( x-координата клика).

Тем же образом мы находим вертикальное

5

расстояние, сохраняя его в переменной

diffY. На рис. 11.2 показано, как вычисля-

y

ются diffX и diffY для двух точек.

Рис. 11.2. Вычисление горизонтального и вертикального

расстояний между кликом и кладом

170 Часть II. Продвинутый JavaScript

Используем теорему Пифагора

И наконец, чтобы найти расстояние между двумя

точками в коде функции getDistance, исполь-

зуется теорема Пифагора. Эта теорема гласит,

что для прямоугольного треугольника, где сто-

роны, прилежащие к прямому углу, обозначены

как a и b, а диагональная сторона (гипотенуза)

обозначена как c, a2 + b2 = c2. Зная длины a и b,

мы можем найти длину гипотенузы, взяв ква-

дратный корень от a2 + b2.

Чтобы найти расстояние между кликом и кла-

дом, мы рассматриваем эти две точки как углы

прямоугольного треугольника (см. рис. 11.3).

В функции getDistance переменная diffX — это длина горизонталь-

ной стороны треугольника, а diffY — длина вертикальной стороны.

Найти нужное нам расстояние — значит найти длину гипоте-

нузы, зная длины diffX и diffY. Пример такого вычисления показан

на рис. 11.3.

0

1

2

3

4

5

0

x

1

diffX = 3 – 1

target: (1, 2)

= 2

2

diffY = 3 – 2

= 1

3

event: (3, 3)

4

Гипотенуза = √(diffX2 + diffY2)

= √(22 + 12)

= √(4 + 1)

= √5

5

= 2.236

y

Рис. 11.3. Вычисление гипотенузы как расстояния между кликом и кладом

Чтобы найти гипотенузу, сначала нужно возвести diffX и diffY

в квадрат. Затем мы складываем эти значения и извлекаем из суммы

11. Пишем игру «Найди клад!» 171

квадратный корень с помощью JavaScript-функции Math.sqrt.

Целиком формула для вычисления расстояния между кликом и кладом

выглядит так:

Math.sqrt((diffX * diffX) + (diffY * diffY))

Функция getDistance вычисляет это выражение и возвращает

результат.

Сообщаем игроку, насколько он близок к цели

Зная расстояние между кликом и кладом, остается отобразить под-

сказку, которая сообщала бы игроку, насколько близко он подошел, —

но без конкретных цифр. Для этого создадим следующую функцию

Hint —

getDistanceHint:

подсказка

var getDistanceHint = function (distance) {

if (distance < 10) {

return "Обожжешься!";

} else if (distance < 20) {

return "Очень горячо";

} else if (distance < 40) {

return "Горячо";

} else if (distance < 80) {

return "Тепло";

} else if (distance < 160) {

return "Холодно";

} else if (distance < 320) {

return "Очень холодно";

} else {

return "Замерзнешь!";

}

};

Эта функция возвращает одну из строк в зависимости от передан-

ного ей расстояния до клада. Если это расстояние меньше 10, она вер-

нет «Обожжешься!». Для расстояния от 10 до 20 функция вернет «Очень

горячо». По мере увеличения расстояния функция будет сообщать о все

большем холоде, вплоть до расстояния в 320 пикселей, начиная с кото-

рого функция возвращает строку «Замерзнешь!».

Отображать эти сообщения мы будем, задавая их как текстовое

содержимое элемента p на нашей странице. Следующий код вычис-

лит расстояние, получит нужную строку с сообщением и отобразит эту

строку:

172 Часть II. Продвинутый JavaScript

var distance = getDistance(event, target);

var distanceHint = getDistanceHint(distance);

$("#distance").text(distanceHint);

Как видите, сначала мы вызываем getDistance, сохраняя возвра-

щенное значение в переменной distance. Затем мы передаем distance

в функцию getDistanceHint, чтобы получить соответствующую

строку подсказки и сохранить ее в переменной distanceHint.

Код $("#distance").text(distanceHint); находит элемент, id

которого равен "distance" (в нашем случае это элемент p), и меняет его

текст на значение distanceHint, так что всякий раз при клике по карте

наша веб-страничка сообщает игроку, насколько близко он подошел к цели.

Проверка на выигрыш

И наконец, наш обработчик кликов должен проверить, не попал ли игрок

в цель. Поскольку один пиксель очень мал, мы не будем вынуждать

игрока кликать в точности по месту с кладом, а засчитаем за победу клик

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

Этот код проверяет расстояние до клада, в случае победы сообщая