Go back
15
We wrote a collision that checks if one rectangle is overlapping another, often called AABB collision.

This is done using conditionals and number comparisons. Check the code for details.

If a touch occurs, the score resets.
<canvas id="canvas" width=300 height=300 style="border: 1px solid black; background: #EEEEEE"></canvas>

<script>

	let canvas = document.getElementById('canvas')
	let ctx = canvas.getContext('2d')

	function drawRect(rect) {
		ctx.fillStyle = rect.color
		ctx.fillRect(rect.x, rect.y, rect.width, rect.height)
	}
	
	function updateRect(rect) {
		rect.x += rect.xspeed
		rect.y += rect.yspeed
		
		if (rect.x > canvas.width)
			rect.x = -rect.width
		if (rect.y > canvas.height)
			rect.y = -rect.height
			
		if (rect.x < -rect.width)
			rect.x = canvas.width
		if (rect.y < -rect.height)
			rect.y = canvas.height
	}
	
	//We check for the following:
	//	if A's left is behind B's right, and
	//	if A's top is below B's bottom, and
	//	if A's right is in front of B's left, and
	//	if A's bottom is below B's top
	//
	//Combining all those together, we have a way to check if one rectangle is overalapping another
	//This function returns a value, which is the result of our expression.
	//For example, let result = aabbCollision(A, B) can be be set either true or false depending on the conditions
	
	function aabbCollision(rect1, rect2) {
		return rect1.x < rect2.x + rect2.width &&
			rect1.x + rect1.width > rect2.x &&
			rect1.y < rect2.y + rect2.height &&
			rect1.y + rect1.height > rect2.y
	}
	
	function updatePlayer(player) {
		player.xspeed = 0
		player.yspeed = 0
		
		let speed = 1;
		
		if (keyboard.ArrowLeft)
			player.xspeed -= speed
		if (keyboard.ArrowRight)
			player.xspeed += speed
		if (keyboard.ArrowUp)
			player.yspeed -= speed
		if (keyboard.ArrowDown)
			player.yspeed += speed
	}
	
	let rect1 = { x: 0, y: 0, width: 32, height: 32, color: "blue", xspeed: 0.4, yspeed: 0.1 }
	let rect2 = { x: 0, y: 0, width: 20, height: 20, color: "green", xspeed: -0.2, yspeed: 0.05 }
	let rect3 = { x: 0, y: 0, width: 40, height: 40, color: "orange", xspeed: 0.5, yspeed: -0.1 }
	
	let player = { x: 150, y: 150, width: 32, height: 32, color: "red", xspeed: 1, yspeed: 1 }
	
	let rectArray = [player, rect1, rect2, rect3]
	
	let keyboard = {}
	
	function keyDownEvent(eventInfo) {
		keyboard[eventInfo.code] = true;
	}
	
	function keyUpEvent(eventInfo) {
		keyboard[eventInfo.code] = false;
	}
	
	addEventListener("keyup", keyUpEvent);
	addEventListener("keydown", keyDownEvent);
	
	let scoreValue = 0;
	
	function drawText(text, x, y) {
		ctx.fillStyle = 'black'
		ctx.font = '20px serif'
		ctx.fillText(text, x, y);
	}
	
	function incrementScore() {
		scoreValue++
	}
	
	function update() {
		ctx.clearRect(0, 0, canvas.width, canvas.height)
		
		updatePlayer(player)
		
		for (let rect of rectArray) {
			updateRect(rect)
			drawRect(rect)
			
			//We reset the score if the player is touched.
			//Since player is also in the rectArray, we don't want to check if it collides with itself
			if (rect != player && aabbCollision(player, rect))
				scoreValue = 0
		}
		
		drawText("Score: " + scoreValue, 10, 20)
	}
	
	setInterval(update, 4)
	setInterval(incrementScore, 500)

</script>