JSFiddle - React, Tailwind, and code Playground

by Santiago J

CSS

body {
    background-color: #333;
    color: #eee;
}

#stage {
    background-color: #000;
}

JavaScript

// Utils
function bind(fn, obj) {
    return function() {
        return fn.apply(obj, arguments);
    };
}
function $(s, a, p) {
    if (!p || !p.querySelector) p = document;
    return a ? p.querySelectorAll(s) : p.querySelector(s);
}
function mkEl(tag, attr, parent) {
    var el = document.createElement(tag), a;
    for (a in attr) el.setAttribute(a, attr[a]);
    if (parent && parent.appendChild) parent.appendChild(el);
    return el;
}

// GameManager object
function GameManager() {
    var G = {};
    
    G.init = function() {
        this.stageContainer = $("#stageContainer") || $("body");
        this.stage = mkEl( "canvas",
                           {id: "stage", width: 640, height: 480},
                           this.stageContainer);
        this.ctx = this.stage.getContext("2d");
        this.load();
        
        if (this.onkeydown) {
            window.addEventListener("keydown", bind(this.onkeydown, this), false);
        }
        if (this.onkeyup) {
            window.addEventListener("keyup", bind(this.onkeyup, this), false);
        }
        
        this.time = Date.now();
        setInterval(bind(this.loop, this), 20);
    };
    
    G.load = function() {
        this.ctx.fillStyle = "#fff";
        this.entities = [];
    };
    
    G.update = function(dt) {
        var ents = this.entities, i = ents.length;
        while (i-->0) {
            ents[i].update(dt);
        }
    };
    
    G.draw = function(ctx) {
        ctx.clearRect(0, 0, this.stage.width, this.stage.height);
        
        var ents = this.entities, i = ents.length;
        while (i-->0) {
            ents[i].draw(ctx);
        }
    };
    
    G.loop = function() {
        var dt = Date.now() - G.time;
        G.time += dt;
        G.update(dt/1000);
        G.draw(G.ctx);
    };
    
    G.onkeydown = function(e) {
        this.ctx.fillStyle = "red";
    };
    
    G.onkeyup = function(e) {
        this.ctx.fillStyle = "#fff";
    };

    return G;
}

var...