Файл: Беляев С А - Разработка игр на языке JavaScript - 2016.pdf
Добавлен: 25.10.2018
Просмотров: 7594
Скачиваний: 136
86
Глава 5
ИЗМЕНЕНИЕ ДВУХ КООРДИНАТ
С УЧЕТОМ СВОБОДНОГО ПАДЕНИЯ
Для более глубокого понимания свободного падения
предлагается рассмотреть пример, в котором с его учетом
изменяются две координаты. Данный пример не суще
ственно отличается от рассмотренного выше свободного
падения (рис. 5.2).
<html>
<body>
<canvas id="canvasId" width="450" height="350" style=
"border: 3px dotted violet"></canvas>
<script>
var canvas = document.getElementById("canvasId");
var ctx = canvas.getContext("2d");
var pos = {x:20, y:320, dx:5, dy:-15}; // êîîðäèíàòû, ñêîðîñòè
ctx.strokeStyle = "#f00";
function draw() {
ctx.arc(pos.x, pos.y, 10, 0, Math.PI*2); // îêðóæíîñòü
ctx.stroke(); // íàðèñîâàòü
}
function update() {
if(pos.x < canvas.width - 20)
pos.x += pos.dx; // äâèæåíèå âïðàâî
else
pos.x = 20;
Рис. 5.2
Имитация свободного падения
Реализация логики поведения объектов
87
if(pos.y < canvas.height - 20) {
pos.y += pos.dy; // äâèæåíèå âíèç
pos.dy += 0.4; // óñêîðåíèå
}
else {
pos.y = 320;
pos.dy = -15; // ñáðîñ â 0
pos.x = 20;
ctx.clearRect(0, 0, canvas.width, canvas.height);
// î÷èñòèòü
ctx.beginPath(); // íà÷àòü ðèñîâàòü ñ íà÷àëà
}
draw(); // íàðèñîâàòü îáúåêò
}
setInterval(update, 100); // âûçîâ update êàæäûå 100 ìñåê
</script>
</body>
</html>
Бóльшая часть кода мало отличается от приведенного
ранее примера свободного падения, поэтому рассмотрим
только отличия.
var pos = {x:20, y:320, dx:5, dy:-15};
Изменены начальные координаты объекта, теперь он
появляется в левом нижнем углу. Изменен начальный век
тор скорости, он направлен вправо и вверх.
Функция draw содержит только две строки:
ctx.arc(pos.x, pos.y, 10, 0, Math.PI*2);
ctx.stroke();
Вторая строка отображает контур, в первой рисуется
дуга. Параметры pos.x и pos.y указывают координаты цент
ра, относительно которого рисуется дуга, третий пара
метр — радиус, четвертый и пятый параметры указывают
углы начала и окончания дуги (в данном примере дуга от
0 до 360
° — полная окружность). Здесь Math — встроен
ный объект JavaScript, который предоставляет констан
ту PI (3,1415926...).
Существенные изменения в функции update.
if(pos.x < canvas.width - 20) pos.x += pos.dx; else pos.x = 20;
88
Глава 5
Первое условие проверяет горизонтальное положение
объекта. Если он не достиг границы холста, то увеличива
ет координату pos.x на pos.dx, иначе — «сбрасывает» в
начальное состояние.
if(pos.y < canvas.height - 20) { pos.y += pos.dy; pos.dy += 0.4; }
Данное условие не отличается от примера «Свободное
падение»: если не достигли границы холста, то изменяем
координату по вертикали и увеличиваем pos.dy на кон
станту свободного падения. Существенные отличия пре
терпела часть else приведенного условия.
pos.y = 320;
pos.dy = -15;
pos.x = 20;
Данные три строки предназначены для восстановле
ния значения объекта pos.
ctx.clearRect(0, 0, canvas.width, canvas.height);
Очистка холста выполняется один раз, чтобы можно
было наблюдать весь путь объекта. Соответственно, не ото
бражаются все положения объекта на холсте, а холст очи
щается в самом конце.
ctx.beginPath();
Данная команда инициирует новый контур, который
будет отображаться с помощью ctx.stroke().
При изучении рисунка 5.2 видно, что расстояние меж
ду объектами постоянно меняется, чем выше находится
объект, тем ближе он к своему предыдущему состоянию.
Данное поведение объекта наиболее естественно при сво
бодном падении.
УПРУГОЕ ПАДЕНИЕ
Изменение координат с учетом свободного падения
подразумевает движение вплоть до остановки на какой
то поверхности, но при этом не учитывается возможность
отскока объекта от поверхности. При отскоке необходи
Реализация логики поведения объектов
89
мо учитывать степень упругости поверхности, объекта,
кинетическую энергию, которую передает падающий объ
ект, потерю энергии при столкновении и т. п. В случае
программной реализации можно ограничиться упрощен
ной моделью (рис. 5.3).
<html>
<body>
<canvas id="canvasId" width="650" height="350" style="border:
3px dotted violet"></canvas>
<script>
var canvas = document.getElementById("canvasId");
var ctx = canvas.getContext("2d");
var pos = {x:20, y:320, dx:4, dy:-15, imp:-15}; // êîîðäèíàòû,
// ñêîðîñòè, èìïóëüñ
ctx.strokeStyle = "#f00";
function draw() {
ctx.arc(pos.x, pos.y, 10, 0, Math.PI*2); // îêðóæíîñòü
ctx.stroke(); // íàðèñîâàòü
}
Рис. 5.3
Упругое столкновение
90
Глава 5
function update() {
if(pos.x < canvas.width - 20) {
pos.x += pos.dx; // äâèæåíèå âíèç
}
else
pos.x = 20;
if(pos.y < canvas.height - 20) {
pos.y += pos.dy; // äâèæåíèå
pos.dy += 0.4; // óñêîðåíèå
} else
if(Math.abs(pos.imp) > 0.01) { // ïðîâåðêà èìïóëüñà
pos.imp = pos.dy = pos.imp / 2; // óìåíüøåíèå
// èìïóëüñà è îòñêîê
pos.y += pos.dy; // äâèæåíèå
}
else {
pos = {x:20, y:320, dx:4, dy:-15, imp:-15};
ctx.clearRect(0, 0, canvas.width, canvas.height);
// î÷èñòèòü
ctx.beginPath(); // íà÷àòü ðèñîâàòü ñ íà÷àëà
}
draw(); // íàðèñîâàòü îáúåêò
}
setInterval(update, 100); // âûçîâ update êàæäûå 100 ìñåê
</script>
</body>
</html>
Приведенный код очень похож на «Изменение двух
координат с учетом свободного падения» за исключением
некоторых изменений.
var pos = {x:20, y:320, dx:4, dy:-15, imp:-15};
В объект pos добавлен импульс, который характеризу"
ет энергию, с которой начинает двигаться объект. В дан"
ном случае импульс — потенциальная энергия, накопле"
ная объектом. С физической точки зрения это неверно, но
для упрощенной модели вполне подходит.
В функции update изменено условие движения по вер"
тикали.
if(pos.y < canvas.height - 20) { pos.y += pos.dy; pos.dy += 0.4; }