Создаем метод setDirection
Теперь нужно выяснить, как задавать направление движения мяча.
Set direction —
Мы будем делать это в методе setDirection, который будет вызы-
задать
ваться из обработчика события keydown (речь о котором пойдет ниже).
направление
Обработчик передаст методу setDirection информацию о нажатой
клавише в виде строки ("left", "up", "right", "down" или "stop").
230 Часть III. Графика
На основе этого setDirection будет менять свойства мяча xSpeed
и ySpeed — таким образом, чтобы направление полета мяча соответ-
ствовало направлению, выбранному нажатием клавиши. Например,
если методу передана строка "down", мы сбросим this.xSpeed в 0,
а this.ySpeed присвоим значение 5. Добавьте этот код после метода draw:
Ball.prototype.setDirection = function (direction) {
if (direction === "up") {
this.xSpeed = 0;
this.ySpeed = -5;
} else if (direction === "down") {
this.xSpeed = 0;
this.ySpeed = 5;
} else if (direction === "left") {
this.xSpeed = -5;
this.ySpeed = 0;
} else if (direction === "right") {
this.xSpeed = 5;
this.ySpeed = 0;
} else if (direction === "stop") {
this.xSpeed = 0;
this.ySpeed = 0;
}
};
Тело этого метода представляет собой одну большую конструкцию
if... else. Новое направление передается в аргументе direction —
если это "up", мы сбросим свойство xSpeed в 0, а ySpeed присвоим
значение −5. Остальные направления обрабатываются аналогично.
Наконец, если в метод передана строка "stop", мы сбросим в 0 оба свой-
ства xSpeed и ySpeed, что приведет к остановке мяча.
Реакция на нажатия клавиш
Следующий фрагмент кода создает объект-мяч с помощью конструктора
Ball и отслеживает события keydown, чтобы менять направление мяча
в соответствии с нажатыми клавишами. Добавьте этот код после метода
setDirection:
var ball = new Ball();
var keyActions = {
32: "stop",
37: "left",
38: "up",
39: "right",
15. Управление анимациями с клавиатуры 231
40: "down"
};
$("body").keydown(function (event) {
var direction = keyActions[event.keyCode];
ball.setDirection(direction);
});
В строке мы создаем объект мяча вызовом new Ball(). В строке
создаем объект keyActions для преобразования кодов клавиш в соот-
ветствующие им направления. Этот объект практически ничем не отли-
чается от объекта keyNames со с. 226, лишь коду 32 (клавиша «пробел»)
соответствует обозначение "stop", а не "space", поскольку мы хотим,
чтобы нажатие на пробел останавливало движение мяча.
В строке мы с помощью jQuery-функции $ находим элемент body
и вызываем его метод keydown, чтобы обрабатывать события клавиа-
туры. Функция, переданная в этот метод, будет вызываться каждый раз
при нажатии клавиши на клавиатуре.
В теле этой функции, в строке , мы используем выражение
keyActions[event.keyCode] для поиска названия нажатой клавиши
и присваиваем это значение переменной direction. Таким образом,
в direction оказывается направление: "left", если нажата стрелка
влево, "right" для стрелки вправо, "up" для стрелки вверх, "down" для
стрелки вниз и "stop" для пробела. Если была нажата какая-то другая
клавиша, direction примет значение undefi ned и на анимацию это
никак не повлияет.
И наконец, в строке мы вызываем метод объекта-мяча
setDirection, передавая в него строку с направлением. Как уже было
сказано, setDirection обновляет свойства xSpeed и ySpeed в соответ-
ствии с новым направлением.
Анимация мяча
Нам осталось лишь анимировать мяч. Следующий код наверняка
покажется вам знакомым, поскольку примерно то же самое мы делали
в главе 14. Аналогично предыдущим анимациям, для периодического
обновления позиции мяча здесь используется функция setInterval.
Добавьте эти строки после кода из предыдущего раздела:
setInterval(function () {
ctx.clearRect(0, 0, width, height);
ball.draw();
ball.move();
ctx.strokeRect(0, 0, width, height);
}, 30);
232 Часть III. Графика
Мы используем setInterval, чтобы вызывать функцию
анимации раз в 30 миллисекунд. Функция сначала очищает весь
«холст» с помощью clearRect, а затем вызывает методы объ-
екта-мяча draw и move. Как мы уже знаем, метод draw просто
рисует окружность в текущей позиции мяча, а метод move обнов-
ляет позицию мяча в соответствии со значениями его свойств
xSpeed и ySpeed. И наконец, наша функция рисует с помощью
strokeRect рамку, делая границы «холста» видимыми.
Код программы
Мы уже рассмотрели все части кода, но для вашего удобства
вот вся программа целиком.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
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();
}
};
// Конструктор Ball
var Ball = function () {
this.x = width / 2;
this.y = height / 2;
this.xSpeed = 5;
this.ySpeed = 0;
};
// Обновляем позицию мяча соответственно его скорости
Ball.prototype.move = function () {
this.x += this.xSpeed;
this.y += this.ySpeed;
if (this.x < 0) {
this.x = width;
} else if (this.x > width) {
this.x = 0;
} else if (this.y < 0) {
this.y = height;
} else if (this.y > height) {
this.y = 0;
}
};
15. Управление анимациями с клавиатуры 233
// Рисуем мяч в его текущей позиции
Ball.prototype.draw = function () {
circle(this.x, this.y, 10, true);
};
// Задаем направление движения по строке с названием действия
Ball.prototype.setDirection = function (direction) {
if (direction === "up") {
this.xSpeed = 0;
this.ySpeed = -5;
} else if (direction === "down") {
this.xSpeed = 0;
this.ySpeed = 5;
} else if (direction === "left") {
this.xSpeed = -5;
this.ySpeed = 0;
} else if (direction === "right") {
this.xSpeed = 5;
this.ySpeed = 0;
} else if (direction === "stop") {
this.xSpeed = 0;
this.ySpeed = 0;
}
};
// Создаем объект-мяч
var ball = new Ball();
// Объект для перевода кодов клавиш в названия действий
var keyActions = {
32: "stop", // остановка
37: "left", // влево
38: "up", // вверх
39: "right",// вправо
40: "down" // вниз
};
// Обработчик события keydown, будет вызван при каждом нажатии
// клавиши
$("body").keydown(function (event) {
var direction = keyActions[event.keyCode];
ball.setDirection(direction);
});
// Функция анимации, вызывается раз в 30 мс
setInterval(function () {
ctx.clearRect(0, 0, width, height);
ball.draw();
ball.move();
ctx.strokeRect(0, 0, width, height);
}, 30);
234 Часть III. Графика
Запуск программы
Наша программа завершена. При запуске вы увидите черный мяч, дви-
жущийся слева направо по «холсту», как на рис. 15.3. Дойдя до правого
края, мяч должен появиться с левой стороны, продолжая движение
вправо. При нажатии клавиш-стрелок мяч должен менять направление,
а при нажатии на «пробел» остановиться.
Рис. 15.3. Скриншот анимации мяча
! Если анимация не реагирует на нажатия кла-
виш, кликните по странице, чтобы убедиться,
что у программы есть доступ к клавиатуре.
Что мы узнали
В этой главе мы научились писать программы, реа-
гирующие на нажатия клавиш. Мы создали анима-
цию мяча, направление движения которого можно
менять с клавиатуры.
Теперь мы знаем, как рисовать на «холсте», создавать анимации
и управлять этими анимациями с клавиатуры, а значит, уже готовы
написать простую игру, использующую элемент canvas! В следующих
главах мы создадим вариант классической видеоигры «Змейка», пустив
в ход все, что научились делать.
15. Управление анимациями с клавиатуры 235
УПРА ЖНЕНИЯ
Вот несколько способов сделать последнюю анимацию сложнее
и интереснее.
#1. Отскоки от границ «холста»
Измените код так, чтобы мяч отскакивал от границ при столкно-
вении, а не появлялся с другой стороны.
Подсказка: при столкновении просто измените направление
на противоположное.
#2. Управление скоростью
Сейчас на каждом шаге анимации мяч перемещается на 5 пиксе-
лей, поскольку setDirection всегда задает свойствам xSpeed
и ySpeed значения −5 или 5. Создайте в конструкторе Ball
новое свойство speed, хранящее скорость мяча, и используйте
его в методе setDirection вместо цифры 5.
Теперь добавьте в код возможность задавать скорость (speed)
нажатием цифровых клавиш от 1 до 9.
Подсказка: создайте объект speeds с разными значениями
скоростей и в обработчике события keydown выбирайте из него
соответствующую клавише скорость.
#3. Гибкое управление
Измените код так, чтобы при нажатии клавиши Z мяч замед-
лял движение, а при нажатии X разгонялся. Затем сделайте так,
чтобы клавиша C уменьшала размер мяча, а V — увеличивала.
Что произойдет, если скорость станет отрицательной? А раз-
мер? Добавьте в код проверку, гарантирующую, что скорость
и размер никогда не станут меньше 0.
16
П И Ш Е М И Г Р У « З М Е Й К А »: Ч АС Т Ь 1