JSFiddle - React, Tailwind, and code Playground

by Josh Pullen

HTML

<canvas id="canvas"></canvas>

CSS

#canvas {
  border: 1px solid black;
}

JavaScript

class GameBase {
	constructor(canvas, questions) {
  	this.canvas = canvas;
    this.ctx = canvas.getContext("2d");
    
    this.canvas.width = 640;
    this.canvas.height = 480;

  	this.questions = questions;
    
    this.init();
    
    this._stopping = false;
  }
  
  _tick() {
  	if (this._stopping) return;

  	requestAnimationFrame(this._tick.bind(this));

    this.update();
    
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    this.render();
  }
  
  start() {
  	this._tick();
  }

  stop() {
  	this._stopping = false;
  }

	init() {}
  update() {}
  render() {}
}

const Asteroids = {
	Game: class Game extends GameBase {
    init() {
    	this.asteroids = [];
    }

    render() {
    	this.ctx.fillStyle = "black";
    	for (let i = 0; i < this.asteroids.length; i++) {
      	const asteroid = this.asteroids[i];
        this.ctx.beginPath();
        this.ctx.arc(asteroid.x, asteroid.y, 10, 0, 2 * Math.PI);
        this.ctx.fill();
        
        if (i === 0) {
          this.ctx.strokeStyle = "red";
          this.ctx.lineWidth = 2;

        	this.ctx.beginPath();
          this.ctx.arc(asteroid.x, asteroid.y, 14, 0, 2 * Math.PI);
          this.ctx.stroke();
          
          for (let j = 0; j < 4; j++) {
          	this.ctx.beginPath();
            const direction = j * Math.PI / 2;
            this.ctx.moveTo(
            	asteroid.x + Math.cos(direction) * 14,
              asteroid.y + Math.sin(direction) * 14
            );
            this.ctx.lineTo(
            	asteroid.x + Math.cos(direction) * 6,
              asteroid.y + Math.sin(direction) * 6
            );
            this.ctx.stroke();
          }
          
          this.ctx.beginPath();
          this.ctx.moveTo(35, canvas.height / 2);
          const dir = Math.atan2(canvas.height / 2 - asteroid.y, 35 - asteroid.x);
          this.ctx.lineTo(
          	asteroid.x + 14 * Math.cos(dir),
            asteroid.y + 14 * Math.sin(dir)
          );
          
 ...