Выбрать главу

иваем его свойству 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 (ячейка)