иваем его свойству nextDirection в строке .
Создаем яблоко
В этой игре яблоко представляет собой объект из трех компонентов: это
свойство position, которое хранит позицию яблока в виде объекта-
ячейки, метод draw, с помощью которого мы будем рисовать яблоко
на экране, и метод move, который нужен, чтобы задать яблоку новую
позицию после того, как змейка его съела.
Пишем конструктор Apple
Все, что делает конструктор, — это задает свойство position, присваи-
вая ему новый объект-ячейку.
266 Часть III. Графика
var Apple = function () {
this.position = new Block(10, 10);
};
Этот код создает новый объект-ячейку в столбце 10, строке 10 и при-
сваивает его свойству объекта-яблока position. Мы будем использовать
этот конструктор для создания объекта-яблока в самом начале игры.
Рисуем яблоко
Чтобы нарисовать яблоко, создадим метод draw:
Apple.prototype.draw = function () {
this.position.drawCircle("LimeGreen");
};
Этот метод очень прост, всю работу за него выполняет метод drawCircle
(созданный в разделе «Добавляем метод drawCircle» на с. 255). Чтобы
нарисовать яблоко, мы просто вызываем для хранящего объект-ячейку
свойства position метод drawCircle, передавая ему название цвета
"LimeGreen" (темно-зеленый) для отображения в заданной ячейке
зеленого кружка.
Чтобы проверить работу этого метода, выполните такой код:
var apple = new Apple();
apple.draw();
Перемещаем яблоко
Метод move перемещает яблоко в случайную новую позицию на игро-
вом поле (то есть в любую ячейку на «холсте», кроме области рамки).
Мы будем вызывать этот метод всякий раз, когда змейка съест яблоко,
чтобы оно появилось снова в другой позиции.
Apple.prototype.move = function () {
var randomCol = Math.floor(Math.random() * (widthInBlocks - 2)) + 1;
Random col —
var randomRow = Math.floor(Math.random() * (heightInBlocks - 2)) + 1;
случайный
this.position = new Block(randomCol, randomRow);
столбец
};
Random row —
случайная
В строке и следующей строке мы создаем переменные randomCol
строка
и randomRow, которые примут значения, соответствующие случайному
столбцу и случайной строке на игровом поле. Как показано на рис. 17.1
на с. 253, столбцы и строки игрового поля имеют номера от 1 до 38, сле-
довательно, нам нужно выбрать случайные числа из этого диапазона.
17. Пишем игру «Змейка»: часть 2 267
Для получения этих чисел мы воспользуемся выражением Math.
fl oor(Math.random() * 38), которое возвращает случайное число
от 0 до 37, и затем прибавим к нему 1, чтобы получить число от 1 до 38
(как работают методы Math.fl oor и Math.random, см. в разделе
«Случайный выбор» на с. 65).
Именно это мы и делаем в строке для получения случайного
столбца, однако вместо 38 мы пишем (widthInBlocks - 2). Это нужно
для того, чтобы у нас была возможность изменить размер игрового поля
без необходимости редактировать код программы. И таким же образом
мы получаем случайное значение строки с помощью Math.fl oor(Math.
random() * (heightInBlocks - 2)) + 1.
Наконец, в строке мы создаем новый объект-ячейку, позиция кото-
рого соответствует нашим случайным значениям для столбца и строки,
сохраняя его в this.position. Таким образом, позиция яблока изме-
нится на новую случайную позицию в пределах игрового поля.
Вы можете проверить работу метода move таким образом:
var apple = new Apple();
apple.move();
apple.draw();
Код игры
Наша игра состоит примерно из 200 строк JavaScript-кода! Если соеди-
нить все рассмотренные ранее фрагменты воедино, программа будет
выглядеть так:
// Настройка «холста»
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
// Получаем ширину и высоту элемента canvas
var width = canvas.width;
var height = canvas.height;
// Вычисляем ширину и высоту в ячейках
var blockSize = 10;
var widthInBlocks = width / blockSize;
var heightInBlocks = height / blockSize;
// Устанавливаем счет 0
var score = 0;
// Рисуем рамку
var drawBorder = function () {
ctx.fillStyle = "Gray";
268 Часть III. Графика
ctx.fillRect(0, 0, width, blockSize);
ctx.fillRect(0, height - blockSize, width, blockSize);
ctx.fillRect(0, 0, blockSize, height);
ctx.fillRect(width - blockSize, 0, blockSize, height);
};
// Выводим счет игры в левом верхнем углу
var drawScore = function () {
ctx.font = "20px Courier";
ctx.fillStyle = "Black";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Счет: " + score, blockSize, blockSize);
};
// Отменяем действие setInterval и печатаем сообщение «Конец игры»
var gameOver = function () {
clearInterval(intervalId);
ctx.font = "60px Courier";
ctx.fillStyle = "Black";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Конец игры", width / 2, height / 2);
};
// Рисуем окружность (используя функцию из главы 14)
var circle = function (x, y, radius, fillCircle) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
if (fillCircle) {
ctx.fill();
} else {
ctx.stroke();
}
};
// Задаем конструктор Block (ячейка)