Flappy Bird Simple

by ElijahCirioli

HTML

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Flappy Bird</title>
	</head>
	<body>
		<canvas id="myCanvas" width="640" height="480" style="border: 1px solid black"></canvas>
		<h1 id="scoreText">Score: 0</h1>
		<p>Press space to flap</p>
	</body>
</html>

JavaScript

const canvas = document.getElementById("myCanvas");
const context = canvas.getContext("2d");

// these are constants which define our "pixel" size
const boundX = 64;
const boundY = 48;

const birdX = 4; // this defines what the bird's X position is
const pipeVel = 1; // this defines how fast the pipes move
const pipeGap = 10; // this defines the size of the gaps in the pipe
const pipeWidth = 5; // how wide the pipes are
const maxPipeOffset = 10; // this defines how far up and down the pipe can move

// each of these will be a register
let pipeX, birdY, birdVel, pipeOffset, clockTick, score;

// this are single flip flops (buttonFlag is actually more to simulate a synchronizer here)
let buttonFlag, started;

// this gets run at the start and when you die
function reset() {
	pipeX = boundX;
	birdY = Math.floor(boundY / 2); // this would also be a constant
	birdVel = 0;
	pipeOffset = Math.floor(maxPipeOffset / 2); // this would also be a constant
	clockTick = 0;
	score = 0;
	buttonFlag = false;
	started = false;
}

function gameLogic() {
	// if we scale this right this won't have to be a decimal
	const acceleration = buttonFlag ? -2 : 0.25; // ternary operator is even in verilog
	birdVel += acceleration; // this is an adder
	birdY += birdVel; // this is an adder
	pipeX -= pipeVel; // this is a subtractor

	if (detectCollisions()) {
		reset();
	}

	// we have been talking about these looping counters
	if (pipeX + pipeWidth < 0) {
		score++;
		pipeX = boundX;
		pipeOffset = clockTick % maxPipeOffset; // "randomize" pipe height
	}
}

function detectCollisions() {
	// this is all combinational logic that can be done with comparators

	// offscreen
	if (birdY >= boundY || birdY < 0) {
		return true;
	}

	// pipe collisions
	if (pipeX <= birdX + 1 && pipeX + pipeWidth >= birdX) {
		const bottomY = Math.floor(boundY / 2) + Math.floor(pipeGap / 2) - Math.floor(maxPipeOffset / 2) + pipeOffset;
		const topY = Math.floor(boundY / 2) - Math.floor(pipeGap / 2) -...