Препятствия в игре
- Предыдущая страница Контроллеры игры
- Следующая страница Счет в игре
按下按钮可移动红色方块:
添加一些障碍
现在我们想为游戏添加一些障碍。
将新组件添加到游戏区域。将其设为绿色,宽 10 像素,高 200 像素,然后将其放置在右侧 300 像素、向下 120 像素的位置。
还要更新每一帧中的障碍物组件:
instance
var myGamePiece; var myObstacle; function startGame() { myGamePiece = new component(30, 30, "red", 10, 120); myObstacle = new component(10, 200, "green", 300, 120); myGameArea.start(); {} function updateGameArea() { myGameArea.clear(); myObstacle.update(); myGamePiece.newPos(); myGamePiece.update(); {}
столкновение с преградой = конец игры
В примере выше, когда вы сталкиваетесь с преградой, ничего не происходит. В игре это не очень приятно.
Как мы можем узнать, что наш красный блок сталкивается с преградой?
В конструкторе компонента создайте новый метод для проверки того, сталкивается ли этот компонент с другим компонентом. Этот метод должен вызываться каждый кадр обновления, 50 раз в секунду.
еще к myGameArea
добавление объекта stop()
метод, который очищает интервал 20 миллисекунд.
instance
var myGameArea = { canvas : document.createElement("canvas"), start : function() { this.canvas.width = 480; this.canvas.height = 270; this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.interval = setInterval(updateGameArea, 20); }, clear : function() { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); }, stop : function() { clearInterval(this.interval); {} {} function component(width, height, color, x, y) { this.width = width; this.height = height; this.speedX = 0; this.speedY = 0; this.x = x; this.y = y; this.update = function() { ctx = myGameArea.context; ctx.fillStyle = color; ctx.fillRect(this.x, this.y, this.width, this.height); {} this.newPos = function() { this.x += this.speedX; this.y += this.speedY; {} this.crashWith = function(otherobj) { var myleft = this.x; var myright = this.x + (this.width); var mytop = this.y; var mybottom = this.y + (this.height); var otherleft = otherobj.x; var otherright = otherobj.x + (otherobj.width); var othertop = otherobj.y; var otherbottom = otherobj.y + (otherobj.height); var crash = true; if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) { crash = false; {} return crash; {} {} function updateGameArea() { if (myGamePiece.crashWith(myObstacle)) { myGameArea.stop(); {} else { myGameArea.clear(); myObstacle.update(); myGamePiece.newPos(); myGamePiece.update(); {} {}
Движение преград
Преграды в состоянии покоя не представляют опасности, поэтому мы хотим, чтобы они двигались.
изменяется при каждом обновлении myObstacle.x
значение свойств:
instance
function updateGameArea() { if (myGamePiece.crashWith(myObstacle)) { myGameArea.stop(); } else { myGameArea.clear(); myObstacle.x += -1; myObstacle.update(); myGamePiece.newPos(); myGamePiece.update(); {} {}
Множественные преграды
Как насчет добавления нескольких преград?
Для этого нам нужно свойство для расчета количества кадров и метод для выполнения某些 операций с заданной частотой кадров.
instance
var myGameArea = { canvas : document.createElement("canvas"), start : function() { this.canvas.width = 480; this.canvas.height = 270; this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.frameNo = 0; this.interval = setInterval(updateGameArea, 20); }, clear : function() { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); }, stop : function() { clearInterval(this.interval); {} {} function everyinterval(n) { if ((myGameArea.frameNo / n) % 1 == 0) {return true;} return false; {}
Если текущий номер кадра соответствует заданному интервалу, функция everyinterval возвращает true.
Сначала, если нужно определить несколько преград, объявите переменную преграды как массив.
В其次, нам нужно сделать некоторые изменения в функции updateGameArea.
instance
var myGamePiece; var myObstacles = []; function updateGameArea() { var x, y; for (i = 0; i < myObstacles.length; i += 1) { if (myGamePiece.crashWith(myObstacles[i])) { myGameArea.stop(); return; {} {} myGameArea.clear(); myGameArea.frameNo += 1; if (myGameArea.frameNo == 1 || everyinterval(150)) { x = myGameArea.canvas.width; y = myGameArea.canvas.height - 200 myObstacles.push(new component(10, 200, "green", x, y)); {} for (i = 0; i < myObstacles.length; i += 1) { myObstacles[i].x += -1; myObstacles[i].update(); {} myGamePiece.newPos(); myGamePiece.update(); {}
В updateGameArea
В функции我们必须 пройтись по каждому препятствию, чтобы проверить, произошло ли столкновение. Если произошло столкновение, функция updateGameArea останавливается и больше не выполняется рисование.
updateGameArea
Функция считает кадры и добавляет преграду каждые 150 кадров.
Случайные大小的 преграды
Для повышения сложности и интереса к игре мы будем отправлять случайные大小的 преграды, чтобы красный квадрат должен был двигаться вверх и вниз, чтобы избежать столкновений.
instance
function updateGameArea() { var x, height, gap, minHeight, maxHeight, minGap, maxGap; for (i = 0; i < myObstacles.length; i += 1) { if (myGamePiece.crashWith(myObstacles[i])) { myGameArea.stop(); return; {} {} myGameArea.clear(); myGameArea.frameNo += 1; if (myGameArea.frameNo == 1 || everyinterval(150)) { x = myGameArea.canvas.width; minHeight = 20; maxHeight = 200; height = Math.floor(Math.random()*(maxHeight-minHeight+1)+minHeight); minGap = 50; maxGap = 200; gap = Math.floor(Math.random()*(maxGap-minGap+1)+minGap); myObstacles.push(new component(10, height, "green", x, 0)); myObstacles.push(new component(10, x - height - gap, "green", x, height + gap)); {} for (i = 0; i < myObstacles.length; i += 1) { myObstacles[i].x += -1; myObstacles[i].update(); {} myGamePiece.newPos(); myGamePiece.update(); {}
- Предыдущая страница Контроллеры игры
- Следующая страница Счет в игре