Эффективно вы ищете Столкновение ограничивающих осей столкновений .Тем не менее, здесь есть несколько проблем с кодом, которые я расскажу в своем ответе, чтобы эффективно использовать коллизии.Есть еще несколько вещей, которые можно улучшить, это только для того, чтобы охватить больше ключевых элементов.
Самое большое, что я бы порекомендовал всем, кто занимался разработкой (или разработкой в целом), это использовать * 1005.* Объектно-ориентированное программирование (ООП) .Вместо того, чтобы иметь в игре кучу магических чисел и разделять переменные для всех значений x, y, ширины, высоты и т. Д. (, что может быстро запутаться ), вы можете создавать свои собственные объекты для использования со свойствами иметоды, которые вы определяете.Я буду использовать ES5 для этого примера (, поскольку этот код выглядит так: ), хотя я рекомендую ES6 классы .
Первое, что нам нужно, этообщий класс Block
, который могут использовать как препятствия, так и наш игрок.Просто класс, который хранит его положение (x, y), размерность (ширина, высота).И способ рисовать и перемещать себя:
function Block(x, y, w, h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.draw = function() {
ctx.fillStyle = "lightblue";
ctx.fillRect(this.x+3, this.y, this.w , this.h);
ctx.fillStyle = "green";
ctx.fillRect(this.x, this.y, this.w, this.h);
}
this.move = function(dx, dy) {
this.x += dx;
this.y += dy;
}
}
Таким образом, вы можете создавать множество препятствий и сохранять их в массив, чтобы легко рисовать и перемещать каждое из них.Далее мы хотим класс для нашего Player
.Player
будет похож на класс Block
, но ему понадобится способ обновить себя, когда пользователь использует клавиши со стрелками:
function Player(x, y, w, h) {
this.moveingUp = this.movingDown = false; // Tracks if the arrow keys are pressed/released
this.speed = 1;
Block.call(this, x, y, w, h); // Player inherits from Block
this.draw = function() {
ctx.fillStyle = "#ff6961";
ctx.fillRect(this.x, this.y, this.w, this.h);
}
this.update = function() {
if(this.movingUp) this.move(0, -this.speed);
if(this.movingDown) this.move(0, this.speed);
}
}
Одна мысль, которую вы можете заметить, - это движение вашего игрокапохоже на то, что когда вы держите пробел в Word, он сначала немного перемещается, а затем продолжает двигаться после слов.Чтобы обеспечить плавное движение, вместо этого вы можете отслеживать, используя логические переменные (this.moveingUp
, this.movingDown
), чтобы быть истинными при нажатии клавиш со стрелками и ложными при отпускании клавиш со стрелками:
window.addEventListener( "keydown", function(e) { check(e, true)} );
window.addEventListener( "keyup", function(e) { check(e, false)} );
function check(e, isDown) {
if ( e.keyCode == 38 ) player.movingUp = isDown; // player is defined below
if ( e.keyCode == 40 ) player.movingDown = isDown;
}
Вы можете использовать startGame
как способ инициализации вашей игры (и может использоваться как перезапуск).Здесь вы можете создать своего игрока и препятствия:
function startGame() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
obstacles = [ new Block(500, 100, 40, 205),
new Block(800, 0, 40, 205), new Block(1200, 100, 40, 300) ];
player = new Player(20, 110, 40, 35);
}
С двумя определенными объектами, которые имеют общие свойства (x, y, w, h).Вы можете создать метод столкновений, аналогичный методу, описанному в первом связанном:
function collides(a, b) {
return (a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y);
};
Наконец, с определением объектов основная логика игры становится довольно простой и легкой для понимания:
function makeObstaclesMOVE() {
createBackground(); // Draw the background
player.update(); // Moves the player if the user moved them
player.draw(); // Draws the player on the screen
obstacles.forEach(function(obstacle) {
obstacle.move(-1, 0); // Moves all obstacles to the left
obstacle.draw(); // Draws all obstacles
if(collides(player, obstacle)) // If the player touches an obstacle it's game over
stopGame = true;
});
if(stopGame) clearInterval(moveOBstacles); // Clear the interval when the game is over
}
Вот полный код в виде кодовой ручки