function GameCanvas(settings) {
let top = this;
this.functions = [];
this.keys = [];
this.images = [];
this.spheres = [];
this.font = "Arial";
this.imageData = undefined;
this.imageDataData = undefined;
this.lastLoop = performance.now();
this.calculateFPS = true;
this.fps = -1;
this.deltaTime = 1;
let mouseLookupTable = [
"left",
"middle",
"right"
];
this.contextMenuDisabled = false;
this.disableScrollOnMobile = false;
this.eventFunctions = {
"mousedown": typeof OnMouseDown !== "undefined",
"mouseup": typeof OnMouseUp !== "undefined",
"mousemove": typeof OnMouseMove !== "undefined",
"contextmenu": typeof OnContextMenu !== "undefined",
"touchstart": typeof OnTouchStart !== "undefined",
"touchend": typeof OnTouchEnd !== "undefined",
"touchmove": typeof OnTouchMove !== "undefined",
};
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
this.createCanvas = function() {
let canvas = document.createElement("canvas");
document.body.appendChild(canvas);
return canvas;
}
this.setSize = function(width, height) {
if (top.canvas) {
top.canvas.width = top.width = width;
top.canvas.height = top.height = height;
window.width = this.width;
window.height = this.height;
}
else {
console.error("There is no canvas!");
}
}
this.fillPageWithCanvas = function() {
top.canvas.style.position = "fixed";
top.canvas.style.top = "0px";
top.canvas.style.left = "0px";
top.setSize(window.innerWidth, window.innerHeight);
top.disableScrollOnMobile = true;
top.contextMenuDisabled = true;
this.updateSizeOnResize = true;
}
this.requestFullscreen = function() {
if (top.canvas.requestFullscreen)
top.canvas.requestFullscreen();
else if (top.canvas.mozRequestFullScreen)
top.canvas.mozRequestFullScreen();
else if (top.canvas.webkitRequestFullscreen)
top.canvas.webkitRequestFullscreen();
else if (top.canvas.msRequestFullscreen)
top.canvas.msRequestFullscreen();
}
this.exitFullscreen = function() {
if(document.exitFullscreen)
document.exitFullscreen();
else if(document.mozCancelFullScreen)
document.mozCancelFullScreen();
else if(document.webkitExitFullscreen)
document.webkitExitFullscreen();
else if(document.msExitFullscreen)
document.msExitFullscreen();
}
this.lockPointer = function() {
top.canvas.requestPointerLock = top.canvas.requestPointerLock || top.canvas.mozRequestPointerLock;
top.canvas.requestPointerLock();
}
this.unlockPointer = function() {
document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock;
document.exitPointerLock();
}
this.disableContextMenu = function() {
top.contextMenuDisabled = true;
}
this.enableContextMenu = function() {
top.contextMenuDisabled = false;
}
this.key = function(key) {
return top.keys[key];
}
this.update = function() {
if (top.calculateFPS) {
var thisLoop = performance.now();
top.fps = 1000 / (thisLoop - top.lastLoop);
top.deltaTime = 60 / top.fps;
top.lastLoop = thisLoop;
if (top.globalFunctions) {
window.fps = top.fps;
window.deltaTime = top.deltaTime;
}
}
top.mouse.movementX = 0;
top.mouse.movementY = 0;
top.mouse.lastX = top.mouse.x;
top.mouse.lastY = top.mouse.y;
}
/******************
Rendering
******************/
this.clearScreen = function() {
top.ctx.clearRect(0, 0, top.width, top.height);
}
this.background = function(color) {
top.ctx.fillStyle = color;
top.ctx.fillRect(0, 0, top.width, top.height);
}
this.circle = function(x, y, radius, color, strokeColor, lineWidth) {
top.ctx.beginPath();
top.ctx.arc(x, y, radius, 0, Math.PI * 2);
top.ctx.fillStyle = color;
if (strokeColor) top.ctx.strokeStyle = strokeColor;
if (lineWidth) top.ctx.lineWidth = lineWidth;
top.ctx.fill();
if (strokeColor) top.ctx.stroke();
}
this.ring = function(x, y, radius, color, lineWidth) {
top.ctx.beginPath();
top.ctx.arc(x, y, radius, 0, Math.PI * 2);
top.ctx.strokeStyle = color;
if (lineWidth) top.ctx.lineWidth = lineWidth;
top.ctx.stroke();
}
this.ellipse = function(x, y, radiusX, radiusY, color, rotation = 0, strokeColor, lineWidth) {
top.ctx.beginPath();
top.ctx.ellipse(x, y, radiusX, radiusY, rotation, 0, Math.PI * 2);
top.ctx.fillStyle = color;
if (strokeColor) top.ctx.strokeStyle = strokeColor;
if (lineWidth) top.ctx.lineWidth = lineWidth;
top.ctx.fill();
if (strokeColor) top.ctx.stroke();
}
this.rectangle = function(x, y, width, height, color, strokeColor, lineWidth) {
top.ctx.fillStyle = color;
if (lineWidth) top.ctx.lineWidth = lineWidth;
if (strokeColor) {
top.ctx.beginPath();
top.ctx.strokeStyle = strokeColor;
top.ctx.rect(x, y, width, height);
top.ctx.fill();
top.ctx.stroke();
}
else
top.ctx.fillRect(x, y, width, height);
}
this.triangle = function(x1, y1, x2, y2, x3, y3, color, strokeColor, lineWidth) {
top.ctx.beginPath();
top.ctx.moveTo(x1, y1);
top.ctx.lineTo(x2, y2);
top.ctx.lineTo(x3, y3);
top.ctx.closePath();
top.ctx.fillStyle = color;
if (lineWidth) top.ctx.lineWidth = lineWidth;
top.ctx.fill();
if (strokeColor) {
top.ctx.strokeStyle = strokeColor;
top.ctx.stroke();
}
}
this.setLineCap = function(lineCap) {
top.ctx.lineCap = lineCap;
}
this.resetLineCap = function() {
top.ctx.lineCap = "butt";
}
this.line = function(x1, y1, x2, y2, strokeWeight, color) {
top.ctx.beginPath();
top.ctx.moveTo(x1, y1);
top.ctx.lineTo(x2, y2);
if (color) top.ctx.strokeStyle = color;
if (strokeWeight) top.ctx.lineWidth = strokeWeight;
top.ctx.stroke();
}
this.picture = function(url, x, y, width, height) {
var imageElement = top.images[url];
if (!imageElement) {
var img = new Image();
img.src = url;
img.onload = function() {
top.ctx.drawImage(img, x, y, width, height);
}
top.images[url] = img;
}
else if (imageElement.complete) {
top.ctx.drawImage(imageElement, x, y, width, height);
}
}
this.setFont = function(font) {
top.font = font;
}
this.setTextAlign = function(align) {
top.ctx.textAlign = align;
}
this.setTextXAlign = function(align) {
top.ctx.textAlign = align;
}
this.setTextYAlign = function(align) {
top.ctx.textBaseline = align;
}
this.resetTextXAlign = function() {
top.ctx.textAlign = "left";
}
this.resetTextYAlign = function() {
top.ctx.textBaseline = "alphabetic";
}
this.text = function(textString, x, y, fontSize, color, strokeColor, lineWidth) {
top.ctx.beginPath();
top.ctx.font = fontSize + "px " + top.font;
top.ctx.fillStyle = color;
if (lineWidth) top.ctx.lineWidth = lineWidth;
top.ctx.fillText(textString, x, y);
if (strokeColor) {
top.ctx.strokeStyle = strokeColor;
top.ctx.strokeText(textString, x, y);
}
}
this.getPixelData = function() {
top.imageData = top.ctx.getImageData(0, 0, top.width, top.height);
top.imageDataData = top.imageData.data;
}
this.updatePixel = function(x, y, r, g, b, a = 255) {
let i = (x + y * top.width) * 4;
top.imageDataData[i] = r;
top.imageDataData[i + 1] = g;
top.imageDataData[i + 2] = b;
top.imageDataData[i + 3] = a;
}
this.updatePixelIndex = function(index, r, g, b, a =