xxxxxxxxxx
326
const scale = 200;
let gameArray = [];
let calculateArray = [];
function setup() {
createCanvas(800, 800, WEBGL);
strokeWeight(3);
for (let f = 0; f < 6; f++) {
gameArray[f] = [];
calculateArray[f] = [];
for (let x = -2; x <= 2; x++) {
gameArray[f][x] = [];
calculateArray[f][x] = [];
for (let y = -2; y <= 2; y++) {
gameArray[f][x][y] = random(0, 10) > 8;
calculateArray[f][x][y] = false;
}
}
}
}
function draw() {
background(color('#8BD3E6'));
lights();
specularMaterial(color('#FFE6B5'));
shininess(95);
orbitControl();
rotateY(QUARTER_PI);
fill(color('#FEFBEA'));
stroke(color('#3C3F42'));
drawSphere();
drawGame();
if (frameCount % 18 == 0) {
advanceGame();
}
}
function advanceGame() {
for (let f = 0; f < 6; f++) {
for (let x = -2; x <= 2; x++) {
for (let y = -2; y <= 2; y++) {
calculateArray[f][x][y] = checkNeighbors(f, x, y);
}
}
}
gameArray = calculateArray;
}
function checkNeighbors(face, x, y) {
absX = abs(x);
absY = abs(y);
let liveNeighbors = 0;
let isSelfLive = gameArray[face][x][y];
if (absX <= 1 && absY <= 1) {
// Basic logic for all non-edge cases
for (i = x - 1; i <= x + 1; i++) {
for (j = y - 1; j <= y + 1; j++) {
if (!(i == x && j == y)) {
// Checks all squares in a 3x3 grid minus the center which is the main cell
if (gameArray[face][i][j]) {
liveNeighbors++;
}
}
}
}
} else {
let horizontalWrapFace;
let verticalWrapFace;
let cardinality;
if (face == 4) {
if (x == -2) {
horizontalWrapFace = 3;
} else {
horizontalWrapFace = 1;
}
if (y == -2) {
verticalWrapFace = 0;
} else {
verticalWrapFace = 2;
}
} else if (face == 5) {
if (x == -2) {
horizontalWrapFace = 3;
} else {
horizontalWrapFace = 1;
}
if (y == -2) {
verticalWrapFace = 2;
} else {
verticalWrapFace = 0;
}
} else {
horizontalWrapFace = (face + 4 + x / 2) % 4;
verticalWrapFace = (y == -2 ? 5 : 4);
cardinality = 1;
if (verticalWrapFace == 4) {
if (face == 0 || face == 3) {
cardinality = -1;
}
}
if (verticalWrapFace == 5) {
if (face == 3 || face == 2) {
cardinality = -1;
}
}
}
for (j = y - 1; j <= y + 1; j++) {
for (i = x - 1; i <= x + 1; i++) {
if (abs(i) == 3 && abs(j) == 3) {
if (gameArray[face][-x][-y]) {
liveNeighbors++;
}
} else if (abs(i) == 3 && abs(j) != 3) {
if (face >= 0 && face < 4) {
if (gameArray[horizontalWrapFace][-x][j]) {
// Wraps to the opposite x value and same y value if wrapping on side faces
liveNeighbors++;
}
} else {
if (gameArray[horizontalWrapFace][j][face == 4 ? 2 : -2]) {
// Wrapping from the top will touch the top row of a side face and wrapping from the bottom will touch the bottom row of a side face
liveNeighbors++;
}
}
} else if (abs(j) == 3 && abs(i) != 3) {
if (face >= 0 && face < 4) {
if (face % 2 == 0) {
if (
gameArray[verticalWrapFace][face == 2 ? -i : i][2 * cardinality]
) {
liveNeighbors++;
} // Logic to wrap to other face, if wrapping to the far side of the top face the x values have to be rotated so x = -1 on face 2 is x = +1 on top face
} else {
if (
gameArray[verticalWrapFace][2 * cardinality][face == 1 ? -i : i]
) {
liveNeighbors++;
} // Additional logic to wrap with a rotated y to bottom face
}
} else {
if (gameArray[verticalWrapFace][i][face == 4 ? 2 : -2]) {
// Wrapping from top or bottom face vertically will always touch the top or bottom row respectively
liveNeighbors++;
}
}
} else if (!(i == x && j == y)) {
if (gameArray[face][i][j]) {
liveNeighbors++;
}
}
}
}
}
if (isSelfLive) {
if (liveNeighbors == 2 || liveNeighbors == 3) {
return true;
} else {
return false;
}
} else {
if (liveNeighbors == 3) {
return true;
}
}
return false;
}
function drawGame() {
for (let f = 0; f < 6; f++) {
for (let x = -2; x <= 2; x++) {
for (let y = -2; y <= 2; y++) {
if (gameArray[f][x][y]) {
drawLife(f, x, y);
}
}
}
}
}
function drawLife(face, x, y) {
const rotationFactor = HALF_PI / 5;
const outerGridArcLength = QUARTER_PI / 3.1;
const innerGridArcLength = HALF_PI / 5.3;
let yRotationFactor;
let xFactor = abs(x) % 5;
if (xFactor == 1 || xFactor == 4) {
yRotationFactor = innerGridArcLength;
} else if (xFactor == 2 || xFactor == 3) {
yRotationFactor = outerGridArcLength;
} else {
yRotationFactor = rotationFactor;
}
push();
rotateY(-QUARTER_PI);
noStroke();
if (face == 4) {
rotateX(HALF_PI);
} else if (face == 5) {
rotateX(-HALF_PI);
} else {
rotateY(HALF_PI * face);
}
rotateY(rotationFactor * x);
rotateX(yRotationFactor * (abs(y) == 2 && x != 0 ? y * 1.04 : y));
translate(0, 0, scale);
fill(color('#9AC791'));
if (xFactor == 0 && y == 0) {
circle(0, 0, scale * 0.3);
} else if (xFactor == 2 || abs(y) == 2) {
circle(0, 0, scale * 0.225);
} else {
circle(0, 0, scale * 0.28);
}
pop();
}
function drawGrids() {
const gridArcLength = 1.44 / 2;
const outerGridArcLength = 1.45 / 2;
const innerGridArcLength = 1.55 / 2;
push();
noFill();
strokeWeight(1);
rotateY(HALF_PI / 5);
arc(0, 0, scale * 2, scale * 2, -outerGridArcLength, outerGridArcLength);
rotateY(HALF_PI / 5);
arc(0, 0, scale * 2, scale * 2, -innerGridArcLength, innerGridArcLength);
rotateY(HALF_PI / 5);
arc(0, 0, scale * 2, scale * 2, -innerGridArcLength, innerGridArcLength);
rotateY(HALF_PI / 5);
arc(0, 0, scale * 2, scale * 2, -outerGridArcLength, outerGridArcLength);
pop();
}
function drawSphere() {
const arcLength = 1.231 / 2;
push();
noFill();
drawGrids();
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
rotateY(HALF_PI);
drawGrids();
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
rotateY(HALF_PI);
drawGrids();
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
rotateY(HALF_PI);
drawGrids();
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
pop();
push();
noFill();
rotateX(HALF_PI);
rotateZ(QUARTER_PI);
rotateY(QUARTER_PI);
drawGrids();
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
rotateY(-QUARTER_PI);
rotateZ(HALF_PI);
rotateY(QUARTER_PI);
drawGrids();
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
rotateY(-QUARTER_PI);
rotateZ(HALF_PI);
rotateY(QUARTER_PI);
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
rotateY(-QUARTER_PI);
rotateZ(HALF_PI);
rotateY(QUARTER_PI);
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
pop();
push();
noFill();
rotateX(-HALF_PI);
rotateZ(QUARTER_PI);
rotateY(QUARTER_PI);
drawGrids();
rotateY(-QUARTER_PI);
rotateZ(HALF_PI);
rotateY(QUARTER_PI);
drawGrids();
pop();
push();
noFill();
rotateX(HALF_PI);
rotateZ(QUARTER_PI);
rotateY(-QUARTER_PI);
drawGrids();
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
rotateY(QUARTER_PI);
rotateZ(HALF_PI);
rotateY(-QUARTER_PI);
drawGrids();
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
rotateY(QUARTER_PI);
rotateZ(HALF_PI);
rotateY(-QUARTER_PI);
drawGrids();
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
rotateY(QUARTER_PI);
rotateZ(HALF_PI);
rotateY(-QUARTER_PI);
drawGrids();
arc(0, 0, scale * 2, scale * 2, -arcLength, arcLength);
pop();
push();
noStroke();
sphere(scale);
pop();
}