Game Obstacles
- Previous Page Game Controllers
- Next Page Game Scores
Press the button to move the red block:
Add some obstacles
Now we want to add some obstacles to the game.
Add a new component to the game area. Set it to green, width 10 pixels, height 200 pixels, and then place it at the position 300 pixels to the right and 120 pixels down.
Update the obstacle component in each frame:
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(); {}
Collision = Game Over
In the above example, nothing happens when you hit an obstacle. In the game, this is not satisfying.
How do we know if our red block has collided with an obstacle?
In the constructor of the component, create a new method to check if the component collides with another component. This method should be called every frame update, 50 times per second.
also to myGameArea
object addition stop()
The method, which clears an interval of 20 milliseconds.
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(); {} {}
Move obstacles
Obstacles are not dangerous when stationary, so we want them to move.
Change on each update myObstacle.x
The attribute value:
instance
function updateGameArea() { if (myGamePiece.crashWith(myObstacle)) { myGameArea.stop(); } else { myGameArea.clear(); myObstacle.x += -1; myObstacle.update(); myGamePiece.newPos(); myGamePiece.update(); {} {}
Multiple obstacles
How about adding multiple obstacles?
To this end, we need a property for calculating the frame number and a method to execute certain operations at a given frame rate.
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; {}
If the current frame number corresponds to the given interval, the everyinterval function returns true.
Firstly, if you need to define multiple obstacles, declare the obstacle variable as an array.
In addition, we need to make some changes to the updateGameArea function.
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(); {}
In updateGameArea
In the function, we must loop through each obstacle to check for collisions. If a collision occurs, the updateGameArea function will stop and no longer draw.
updateGameArea
The function counts the frames and adds an obstacle every 150 frames.
Randomly sized obstacles
To increase the difficulty and fun of the game, we will send obstacles of random sizes so that the red block must move up and down to avoid collisions.
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(); {}
- Previous Page Game Controllers
- Next Page Game Scores