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

об этом игроку:

if (distance < 8) {

alert("Клад найден! Сделано кликов: " + clicks);

}

Код игры

Теперь, когда у нас есть все части кода, объединим их в программу.

// Получить случайное число от 0 до size-1

var getRandomNumber = function (size) {

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

};

// Вычислить расстояние от клика (event) до клада (target)

var getDistance = function (event, target) {

var diffX = event.offsetX - target.x;

var diffY = event.offsetY - target.y;

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

};

// Получить для расстояния строку подсказки

var getDistanceHint = function (distance) {

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

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 "Замерзнешь!";

}

};

// Создаем переменные

 var width = 400;

var height = 400;

var clicks = 0;

// Случайная позиция клада

 var target = {

x: getRandomNumber(width),

y: getRandomNumber(height)

};

// Добавляем элементу img обработчик клика

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

clicks++;

// Получаем расстояние от места клика до клада

 var distance = getDistance(event, target);

// Преобразуем расстояние в подсказку

 var distanceHint = getDistanceHint(distance);

// Записываем в элемент #distance новую подсказку

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

// Если клик был достаточно близко, поздравляем с победой

 if (distance < 8) {

alert("Клад найден! Сделано кликов: " + clicks);

}

});

Начинается код с функций getRandomNumber, getDistance

и getDistanceHint, о которых мы уже говорили. Затем в строке 

мы создали необходимые переменные: width, height и clicks. Далее

в строке  задается случайная позиция для клада.

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

В строке  мы добавили элементу карты обработчик кликов. Первым

делом этот обработчик увеличивает на 1 переменную clicks. Затем

в строке  он вычисляет расстояние между event (местом клика) и target

(позицией клада). В строке  мы использовали функцию getDistanceHint

для преобразования этого расстояния в строку ("Холодно", "Тепло"

и т. д.). В строке  мы обновляем подсказку на экране, чтобы игрок видел,

насколько он близок к цели. И наконец, в строке  проверяем, уложился ли

игрок в расстояние меньше 8 пикселей от клада, и если уложился, мы сооб-

щаем ему о победе и количестве затраченных кликов.

Это весь JavaScript-код игры. Добавив его ко второму элементу

script в файле treasure.html, вы сможете запустить игру в браузере!

За сколько кликов вам удастся найти клад?

Что мы узнали

В этой главе вы создали настоящую игру, опираясь на знания о работе

с событиями. Также вы познакомились с элементом img, посредством кото-

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

брались, как с помощью JavaScript узнать расстояние между двумя точками.

В следующей главе мы познакомимся с объектно-ориентированным

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

зации и структурирования кода.

УПРА ЖНЕНИЯ

Вот несколько идей по изменению и усовершенствованию кода

игры.

#1. Увеличение игрового поля

Сделайте игру сложнее, увеличив размер игрового поля. Попробуйте

изменить его размер до 800 пикселей в ширину и 800 в высоту.

#2. Больше подсказок

Введите в игру дополнительные подсказки (например, «Очень-очень

холодно!») и добавьте соответствующие подсказкам расстояния.

#3. Ограничение по кликам

Установите ограничение количества кликов и показывайте

игроку сообщение «КОНЕЦ ИГРЫ», если он превысит это

ограничение.

#4. Отображение числа оставшихся кликов

После подсказки «Горячо» или «Холодно» выводите на экран

число оставшихся кликов, чтобы проигрыш не был для игрока

неожиданностью.

12

О Б Ъ Е К Т Н О  О Р И Е Н Т И Р О В А Н Н О Е

П Р О Г РА М М И Р О В А Н И Е

В этой главе мы узнаем, как создавать и использовать объекты в рамках объ-

ектно-ориентированного программирования. Объектно-ориентированное

программирование (ООП) — это способ проектирования и написания кода,

когда все важные части программы являются объектами. Например, если

вы пишете видеоигру «гонки», вы можете воспользоваться технологией

ООП и запрограммировать объект «машина», а затем создать множество

таких объектов, обладающих одинаковым набором свойств и одинаковой

функциональностью.

Простой объект

Как вы уже знаете из четвертой главы, объекты состоят из свойств, кото-

рые представляют собой пары «ключ-значение». Например, в следующем

коде объект dog описывает собаку, и у него есть свойства — name (имя),

legs (количество лап) и isAwesome (обозначает, хороша ли эта собака):

var dog = {

name: "Оладушек",

legs: 4,

isAwesome: true

};

176

К свойствам созданного объекта можно обращаться через точечную

нотацию (о ней мы говорили на с. 72 в разделе «Доступ к значениям

внутри объектов»). Например, так мы можем получить свойство name

нашего объекта dog:

dog.name;

"Оладушек"

Кроме того, с помощью точечной нотации можно добавлять объекту

новые свойства:

dog.age = 6;

При этом у объекта появится еще одна пара «ключ-значение» (age: 6),

в чем можно легко убедиться:

dog;

Object {name: "Оладушек", legs: 4, isAwesome: true, age: 6}

Добавление к объектам новых методов

В последнем примере мы создали несколько свойств, которые хранят

значения разных типов: строку ("Оладушек"), числа (4 и 6) и булево

значение (true). Помимо строк, чисел и булевых значений в свойствах

объектов можно хранить функции — тогда эти свойства называют

методами. В сущности, мы уже пользовались некоторыми встроенными

в JavaScript методами: например, это метод join для массивов и метод

toUpperCase для строк.

А теперь давайте посмотрим, как создавать собственные методы.

Один из способов — воспользоваться точечной нотацией. К примеру,

научим нашу собаку лаять, добавив к объекту dog метод под названием

bark:

Bark — лай

 dog.bark = function () {

 console.log("Гав-гав! Меня зовут " + this.name + "!");

};

 dog.bark();

Гав-гав! Меня зовут Оладушек!

В строке  мы добавили к объекту dog свойство bark и задали

в качестве его значения функцию. В строке , в теле этой функции, мы

177

использовали console.log, чтобы напечатать: «Гав-гав! Меня зовут

Оладушек!» Обратите внимание на запись this.name — таким обра-

зом мы получаем значение, сохраненное в свойстве name этого объекта.

Давайте разберемся подробнее, как работает ключевое слово this.

Ключевое слово this

This — этот,

Ключевое слово this можно использовать в теле метода, чтобы обра-

это

титься к объекту, для которого этот метод вызывается. Например, при

вызове метода bark для объекта dog, this обозначает объект dog, а зна-

чит this.name — это свойство dog.name. Ключевое слово this делает

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

гим объектам так, чтобы он имел доступ к свойствам того объекта, для

которого в данный момент вызывается.

Используем один метод с разными объектами

Speak —

Давайте создадим новую функцию speak, чтобы затем использовать ее

говорить

как метод с разными объектами, обозначающими разных животных.

В случае вызова для какого-нибудь объекта метод speak будет

обращаться к имени объекта (this.name) и звуку, который издает

Sound — звук

животное (this.sound), чтобы вывести в консоль сообщение.

var speak = function () {

console.log(this.sound + "! Меня зовут " + this.name + "!");

};

Теперь создадим еще один объект, чтобы добавить к нему функцию

speak в качестве метода:

var cat = {

sound: "Мяу",

name: "Варежка",

 speak: speak

};

Cat — кошка

Здесь мы создали новый объект cat со свойствами sound, name

и speak. В строке  мы присвоили свойству speak значение —

созданную ранее функцию speak. Теперь cat.speak является мето-

дом, который можно вызывать командой cat.speak(). Поскольку

в коде метода используется ключевое слово this, в случае вызова для

объекта cat он получит доступ к свойствам именно этого объекта.

Давайте проверим:

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

cat.speak();

Мяу! Меня зовут Варежка!

Когда мы вызываем метод cat.speak, он запрашивает значения

двух свойств объекта cat: this.sound (это "Мяу") и this.name (это

"Варежка").

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

других объектов:

var pig = {


Pig —

sound: "Хрю",

поросенок

name: "Чарли",

speak: speak


Horse —

лошадь

};

var horse = {

sound: "И-го-го",

name: "Мэри",

speak: speak

};

pig.speak();

Хрю! Меня зовут Чарли!

horse.speak();

И-го-го! Меня зовут Мэри!

Повторюсь: в коде метода ключевое слово this ссылается

на объект, для которого метод был вызван. Другими словами, при