Skip to content

Instantly share code, notes, and snippets.

@olliebennett
Created March 30, 2019 00:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olliebennett/26028e6a584670522b124c63e74143d8 to your computer and use it in GitHub Desktop.
Save olliebennett/26028e6a584670522b124c63e74143d8 to your computer and use it in GitHub Desktop.
Colour Spill Game in JavaScript

Colour Spill Game

A simple game inspired by Ink Spill (in turn by Flood It) in which cells are populated with colour spreading to adjacent cells from the top left of a grid.

<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<title>Colour Spill</title>
<style>
canvas {
width: 750px;
height: 500px;
border: 1px solid black;
}
.control-button {
height: 50px;
width: 200px;
}
</style>
</head>
<body>
<h1>Colour Spill</h1>
<canvas id="world">
</canvas>
<div id="control-panel">
</div>
<script>
// CONFIGURATION
const gridX = 5;
const gridY = 5;
const cellWidth = 15;
const cellHeight = 10;
// List of possible colours
var colours = ['red', 'orange', 'green'];
// CODE
// Build empty matrix (2D Array) with cells containing `value`
// Note: seemingly redundant .fill(0) required to bypass shallow copy constructor
var buildMatrix = function(x, y, value) {
return new Array(x).fill(0).map(row => new Array(y).fill(value));
}
// 2D Grid of colours
var matrix = buildMatrix(gridX, gridY, 'blue');
// 2D Grid of 'infested' cells
var mask;
// Colour currently being applied
var colour = colours[0];
const canvas = document.getElementById('world');
const ctx = canvas.getContext('2d');
var setRandom = function() {
for (var i=0; i < gridX; i++) {
for (var j=0; j < gridY; j++) {
matrix[i][j] = colours[Math.floor(Math.random()*colours.length)];
}
}
}
var markAdjacent = function() {
var changed = false;
for (var i=0; i < gridX; i++) {
for (var j=0; j < gridY; j++) {
// mark this cell if ...
if (
// cell not already tagged
!mask[i][j] &&
// ... and the matrix cell is a matching colour
matrix[i][j] === colour &&
// ... and any adjacent cell in the mask is infected
(
(i > 0 && mask[i-1][j]) ||
(j > 0 && mask[i][j-1]) ||
(i < (gridX - 1) && mask[i+1][j]) ||
(j < (gridY - 1) && mask[i][j+1])
)
) {
mask[i][j] = true;
changed = true;
}
}
}
// Iterate repeatedly until no changes are required
if (changed) {
applyMask()
drawMatrix();
// Repeat recursively
window.setTimeout(function() { markAdjacent(); }, 10);
}
}
var buildMask = function() {
mask = buildMatrix(gridX, gridY, false);
// Initially, top left cell is 'infected'
mask[0][0] = true;
markAdjacent();
}
var applyMask = function() {
for (var i=0; i < gridX; i++) {
for (var j=0; j < gridY; j++) {
if (mask[i][j]) {
matrix[i][j] = colour;
}
}
}
}
var setSpill = function(col) {
// Update current colour we're tracking
colour = col;
// Update all matching cells (according to 'mask') with the new colour
applyMask();
// Re-build the 'mask' to flag all adjacent cells of same colour
buildMask();
// Render the matrix on the canvas
drawMatrix();
};
var logMatrix = function() {
logArray(matrix);
};
var logMask = function() {
logArray(mask);
};
var logArray = function(arr) {
for (var i=0; i<gridX; i++) {
console.log(`row#${i}: ${arr[i].join(',')}`)
}
}
var drawMatrix = function() {
for (var i=0; i < gridX; i++) {
for (var j=0; j < gridY; j++) {
ctx.fillStyle = matrix[i][j];
ctx.fillRect(i * cellWidth, j * cellHeight, cellWidth-1, cellHeight-1);
}
}
};
var buildControlPanel = function() {
colours.forEach(function(col) {
var spillBtn = document.createElement("button");
spillBtn.className = 'control-button';
spillBtn.style.backgroundColor = col;
var spillBtnLabel = document.createTextNode(col.toUpperCase());
spillBtn.appendChild(spillBtnLabel);
var controlPanel = document.getElementById("control-panel");
document.body.insertBefore(spillBtn, controlPanel);
spillBtn.addEventListener('click', function() {
setSpill(col);
});
});
};
var setupGame = function() {
// Initial randomisation and render
setRandom();
drawMatrix();
// Prepare blank mask
buildMask();
// Initial 'guess' of top-left corner
setSpill(colours[0]);
buildControlPanel();
};
setupGame();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment