об этом игроку:
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 ссылается
на объект, для которого метод был вызван. Другими словами, при