site

Website's source files.
Log | Files | Refs | LICENSE

commit bd0735d5c21eff03b4ebdcb50857f984979300ff
parent 3b3ac734f8c9204530273446d6eaeacf22bf5e98
Author: Ryan Jeffrey <ryan@ryanmj.xyz>
Date:   Tue, 20 Apr 2021 14:39:46 -0700

background system test

Diffstat:
Mscripts/main.js | 232++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 189 insertions(+), 43 deletions(-)

diff --git a/scripts/main.js b/scripts/main.js @@ -1,43 +1,189 @@ -/* -@licstart The following is the entire license notice for the -JavaScript code in this tag. - -Copyright (C) 2012-2020 Free Software Foundation, Inc. - -The JavaScript code in this tag is free software: you can -redistribute it and/or modify it under the terms of the GNU -General Public License (GNU GPL) as published by the Free Software -Foundation, either version 3 of the License, or (at your option) -any later version. The code is distributed WITHOUT ANY WARRANTY; -without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. - -As additional permission under GNU GPL version 3 section 7, you -may distribute non-source (e.g., minimized or compacted) forms of -that code without the copy of the GNU GPL normally required by -section 4, provided you include this license notice and a URL -through which recipients can access the Corresponding Source. - - -@licend The above is the entire license notice -for the JavaScript code in this tag. -*/ -<!--/*--><![CDATA[/*><!--*/ - function CodeHighlightOn(elem, id) - { - var target = document.getElementById(id); - if(null != target) { - elem.cacheClassElem = elem.className; - elem.cacheClassTarget = target.className; - target.className = "code-highlighted"; - elem.className = "code-highlighted"; - } - } - function CodeHighlightOff(elem, id) - { - var target = document.getElementById(id); - if(elem.cacheClassElem) - elem.className = elem.cacheClassElem; - if(elem.cacheClassTarget) - target.className = elem.cacheClassTarget; - } +"use strict"; + +let stop = false; +let frameCount = 0; +let fps, fpsInterval, startTime, now, then, elapsed; + +let canvas; +let context; + +// Rows and columns of the board. +let rows = 200; +let cols = 100; + +// Divisor for likelyhood the cell starts out as alive. +// For example: 4 means 1/4 chance. +let chance = 4; + +// Enum of alive and dead states. +const lifeState = Object.freeze({"alive":1, "dead":2}); + + +// 2D array of cells. +// TODO presets like Gaspar gun +let cells = (_ => { + let retVal = [[]]; + for(let i = 0; i < rows; i++) { + retVal[i] = []; + for(let j = 0; j < cols; j++) { + retVal[i][j] = ((Math.floor((Math.random() * chance) + 1) == 1) ? lifeState.alive : lifeState.dead); + } + } + + return retVal; +})(); + +let tmpCanvas; +let tmpContext; + +function init() { + let newCanvas = document.createElement('canvas'); + newCanvas.setAttribute("id", 'bkg-canvas'); + newCanvas.style['position'] = 'absolute'; + newCanvas.style['left'] = 0; + newCanvas.style['right'] = 0; + newCanvas.style['z-index'] = -1; + newCanvas.width = window.innerWidth; + newCanvas.height = window.innerHeight; + document.body.style.backgroundColor = "black"; + + tmpCanvas = document.createElement('canvas'); + tmpContext = tmpCanvas.getContext('2d'); + tmpCanvas.width = window.innerWidth; + tmpCanvas.height = window.innerHeight; + document.body.style.backgroundColor = "black"; + + + document.body.appendChild(newCanvas); + + + canvas = document.getElementById('bkg-canvas'); + context = canvas.getContext('2d'); +} + + +// get the total number of neighboring cells that are alive. +function totalAliveNeighbors(x, y) +{ + let sum = 0; + let newX = 0; + let newY = 0; + for(let i = -1; i < 2; i++) + { + for(let j = -1; j < 2; j++) + { + newX = (x + i + rows) % rows; + newY = (y + j + cols) % cols; + if(cells[newX][newY] == lifeState.alive) + sum++; + } + } + + if(cells[x][y] == lifeState.alive) + sum--; + + return sum; +} + +// Update the cells. +function updateCells() +{ + // Deep copy the board. + let nextBoard = JSON.parse(JSON.stringify(cells)); + + // Update the new board. + for(let i = 0; i < rows; i++) + { + for(let j = 0; j < cols; j++) + { + let numAlive = totalAliveNeighbors(i, j); + let isAlive = (cells[i][j] == lifeState.alive); + + if(isAlive && (numAlive < 2 || numAlive > 3)) + nextBoard[i][j] = lifeState.dead; + else if(!isAlive && numAlive == 3) + nextBoard[i][j] = lifeState.alive; + } + } + cells = nextBoard; +} + + + +function startAnimating(fps) { + fpsInterval = 1000 / fps; + then = Date.now(); + startTime = then; + console.log("Starting on Unix timestamp: " + startTime); + animate(); +} + +// Optimized drawing function. +function draw() { + let wWidth = window.innerWidth; + let wHeight = window.innerHeight; + let drawCell = { 'x' : 0, 'y' : 0, 'width' : wWidth / rows, 'height' : wHeight / cols}; + + tmpContext.clearRect(0, 0, tmpCanvas.width, tmpCanvas.height); + context.clearRect(0, 0, canvas.width, canvas.height); + + tmpContext.beginPath(); + tmpContext.fillStyle = '#FFFFFF'; + for(let i = 0; i < rows; i++) { + for(let j = 0; j < cols; j++) { + drawCell.x = i * drawCell.width; + drawCell.y = j * drawCell.height; + + if(cells[i][j] === lifeState.alive) + tmpContext.rect(drawCell.x, drawCell.y, drawCell.width, drawCell.height); + } + } + tmpContext.fill(); + tmpContext.closePath(); + + context.drawImage(tmpCanvas, 0, 0, wWidth, wHeight); +} + +function animate() { + + // stop + if (stop) { + return; + } + + updateCells(); + + // request another frame + + requestAnimationFrame(animate); + + // calc elapsed time since last loop + + now = Date.now(); + elapsed = now - then; + + // if enough time has elapsed, draw the next frame + + if (elapsed > fpsInterval) { + + // Get ready for next frame by setting then=now, but... + // Also, adjust for fpsInterval not being multiple of 16.67 + then = now - (elapsed % fpsInterval); + draw(); + + + // TESTING...Report #seconds since start and achieved fps. + let sinceStart = now - startTime; + let currentFps = Math.round(1000 / (sinceStart / ++frameCount) * 100) / 100; + context.fillStyle = 'white'; + context.fillRect(0, 0, 200, 100); + context.font = '25px Arial'; + context.fillStyle = 'black'; + context.fillText("FPS: " + currentFps, 10, 30); + + } +} + + +init(); +startAnimating(20);