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

использовать для проверки совпадения позиций метод объектов-ячеек

equal. Если обнаружится, что какой-либо из сегментов тела находится

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

присваиваем selfCollision значение true .

И наконец, в строке  мы возвращаем из метода wallCollision ||

selfCollision — это выражение даст true, если змейка столкнулась

либо со стенкой, либо сама с собой.

Управляем змейкой с клавиатуры

Теперь мы напишем код, позволяющий игроку задавать направление

движения змейки с клавиатуры. Мы добавим в программу обработ-

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

виш-стрелок и менять направление движения в соответствии с нажа-

той клавишей.

Обработчик события keydown

Этот код обрабатывает события клавиатуры:

 var directions = {

37: "left",

38: "up",

39: "right",

40: "down"

};

 $("body").keydown(function (event) {

var newDirection = directions[event.keyCode];

 if (newDirection !== undefined) {

snake.setDirection(newDirection);

}

});

В строке  мы создаем объект для преобразования кодов кла-

виш-стрелок в строки, обозначающие направления движения (этот

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

264 Часть III. Графика

в разделе «Реакция на нажатия клавиш» на с. 231). В строке  мы задаем

обработчик для событий keydown внутри элемента body. Этот обработ-

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

(если сначала он кликнет мышкой по странице браузера).

Первым делом этот обработчик преобразовывает полученный

из объекта-события код клавиши в строку с названием направления

и сохраняет эту строку в переменной newDirection. Если же получен-

ный код клавиши не равен 37, 38, 39 или 40 (это коды клавиш-стрелок),

выражение directions[event.keyCode] вернет undefi ned.

В строке  мы сравниваем переменную newDirection с undefi ned

и, если она не равна undefi ned, вызываем метод объекта-змейки

setDirection, передавая ему строку newDirection. (Поскольку в этой

конструкции if нет ветви else, в случае если newDirection равняется

undefi ned, мы просто проигнорируем нажатие клавиши.)

Сейчас этот код не будет работать, поскольку мы еще не определили

метод объекта-змейки setDirection. Давайте это исправим.

Создаем метод setDirection

Метод setDirection принимает от обработчика клавиатуры, код кото-

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

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

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

которых змейка сразу же врезается сама в себя. Например, если змейка,

двинувшись вправо, тут же начнет двигаться влево, не повернув перед

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

жется сама в себя. Мы будем называть такие смены направления недопу-

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

шать. Например, на рис. 17.6 для движения змейки вправо показано два

допустимых направления и одно недопустимое.

Текущее

Допустимые

направление

новые

направления

Текущее

Недопустимое

направление

новое

направление

Рис. 17.6. Допустимые направления относительно текущего

17. Пишем игру «Змейка»: часть 2 265

Метод setDirection проверяет, не пытается ли игрок выбрать недо-

пустимое направление. Когда это так, метод использует команду return

для досрочного выхода. В противном случае он обновляет свойство объ-

екта-змейки nextDirection.

Вот код метода setDirection:

Snake.prototype.setDirection = function (newDirection) {

 if (this.direction === "up" && newDirection === "down") {

return;

} else if (this.direction === "right" && newDirection === "left") {

return;

} else if (this.direction === "down" && newDirection === "up") {

return;

} else if (this.direction === "left" && newDirection === "right") {

return;

}

 this.nextDirection = newDirection;

};

Конструкция if... else в строке  состоит из четырех частей — для

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

предотвратить. В первой части говорится, что, если змейка движется

вверх (this.direction равняется "up"), а игрок нажал стрелку вниз

(newDirection равняется "down"), мы должны совершить досрочный

выход из метода с помощью return. Остальные части конструкции обра-

батывают другие недопустимые смены направления тем же образом.

Последняя строка метода setDirection будет выполнена, только

если в newDirection находится допустимое новое направление —

иначе до нее дело не дойдет, потому что одна из команд return в преды-

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

Если направление newDirection является допустимым, мы присва-