/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Single cell in the grid var Cell = Container.expand(function () { var self = Container.call(this); // Attach a square asset for the cell var cellAsset = self.attachAsset('cell', { anchorX: 0.5, anchorY: 0.5 }); // Add inner cell for better visual effect var innerCell = self.attachAsset('cell', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.85, scaleY: 0.85 }); self.isAlive = false; self.gridX = 0; self.gridY = 0; // Set cell state (alive/dead) self.setAlive = function (alive) { self.isAlive = alive; cellAsset.color = alive ? 0x9c27b0 : 0x1a1a1a; cellAsset.alpha = alive ? 0.9 : 0.3; innerCell.color = alive ? 0x8e24aa : 0x222222; innerCell.alpha = alive ? 1 : 0.2; }; // Flash cell when it changes state self.flash = function () { // Flash outer cell tween(cellAsset, { alpha: 1, scaleX: 1.1, scaleY: 1.1 }, { duration: 60, easing: tween.easeOut, onFinish: function onFinish() { tween(cellAsset, { alpha: self.isAlive ? 0.9 : 0.3, scaleX: 1, scaleY: 1 }, { duration: 90 }); } }); // Flash inner cell tween(innerCell, { scaleX: 1.2, scaleY: 1.2 }, { duration: 50, easing: tween.easeOut, onFinish: function onFinish() { tween(innerCell, { scaleX: 0.85, scaleY: 0.85 }, { duration: 75 }); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0a0a0a }); /**** * Game Code ****/ // Grid settings var GRID_COLS = 24; var GRID_ROWS = 24; var CELL_SIZE = 80; // Smaller cells to fit more var GRID_WIDTH = GRID_COLS * CELL_SIZE; var GRID_HEIGHT = GRID_ROWS * CELL_SIZE; var GRID_OFFSET_X = (2048 - GRID_WIDTH) / 2; var GRID_OFFSET_Y = (2732 - GRID_HEIGHT) / 2 + 60; // 2D array of cells var grid = []; var cellNodes = []; // Used to track drawing state var isDrawing = false; var drawState = true; // true = drawing alive, false = erasing // Create cell asset (square) // Create grid of cells for (var y = 0; y < GRID_ROWS; y++) { var row = []; var nodeRow = []; for (var x = 0; x < GRID_COLS; x++) { var cell = new Cell(); cell.gridX = x; cell.gridY = y; cell.x = GRID_OFFSET_X + x * CELL_SIZE + CELL_SIZE / 2; cell.y = GRID_OFFSET_Y + y * CELL_SIZE + CELL_SIZE / 2; cell.setAlive(false); game.addChild(cell); row.push(0); nodeRow.push(cell); } grid.push(row); cellNodes.push(nodeRow); } // Draw grid lines for visual styling // Horizontal lines for (var y = 0; y <= GRID_ROWS; y++) { var hLine = LK.getAsset('gridLine', { anchorX: 0, anchorY: 0.5, scaleX: GRID_WIDTH / 2, scaleY: 1 }); hLine.x = GRID_OFFSET_X; hLine.y = GRID_OFFSET_Y + y * CELL_SIZE; hLine.alpha = 0.3; game.addChild(hLine); } // Vertical lines for (var x = 0; x <= GRID_COLS; x++) { var vLine = LK.getAsset('gridLine', { anchorX: 0.5, anchorY: 0, scaleX: 1, scaleY: GRID_HEIGHT / 2 }); vLine.x = GRID_OFFSET_X + x * CELL_SIZE; vLine.y = GRID_OFFSET_Y; vLine.alpha = 0.3; game.addChild(vLine); } // Draw instructions var instructions = new Text2("Draw: Tap cells\nEvolve: Press ▶", { size: 70, fill: 0xE0E0E0 }); instructions.anchor.set(0.5, 0); LK.gui.top.addChild(instructions); // Add Glider text below instructions var gliderText = new Text2("Glaud", { size: 60, fill: 0x9c27b0 }); gliderText.anchor.set(0.5, 0); gliderText.y = 100; LK.gui.top.addChild(gliderText); // Add evolve/play button var playBtn = new Text2("▶", { size: 120, fill: 0x9c27b0 }); playBtn.anchor.set(0.5, 0.5); playBtn.x = 0; playBtn.y = -120; LK.gui.bottom.addChild(playBtn); // Add reset button var resetBtn = new Text2("⟳", { size: 90, fill: 0xFFFFFF }); resetBtn.anchor.set(0.5, 0.5); resetBtn.x = -180; resetBtn.y = -120; LK.gui.bottom.addChild(resetBtn); // Add step button var stepBtn = new Text2("⏭", { size: 90, fill: 0xFFFFFF }); stepBtn.anchor.set(0.5, 0.5); stepBtn.x = 180; stepBtn.y = -120; LK.gui.bottom.addChild(stepBtn); // Conway's Game of Life instructions.setText("Conway's Game of Life\nDraw & Press ▶"); // State var isRunning = false; var evolveTimer = null; // Helper: get alive neighbor count function countAliveNeighbors(gx, gy) { var count = 0; for (var dy = -1; dy <= 1; dy++) { for (var dx = -1; dx <= 1; dx++) { if (dx === 0 && dy === 0) { continue; } var nx = gx + dx; var ny = gy + dy; if (nx >= 0 && nx < GRID_COLS && ny >= 0 && ny < GRID_ROWS) { if (cellNodes[ny][nx].isAlive) { count++; } } } } return count; } // Evolve grid by one step function evolveGrid() { var toLive = []; var toDie = []; var toRegen = []; var changed = false; for (var y = 0; y < GRID_ROWS; y++) { for (var x = 0; x < GRID_COLS; x++) { var cell = cellNodes[y][x]; var alive = cell.isAlive; var neighbors = countAliveNeighbors(x, y); // Conway's Game of Life rules if (alive) { // Living cell survives with 2 or 3 neighbors if (neighbors < 2 || neighbors > 3) { toDie.push(cell); changed = true; } } else { // Dead cell becomes alive with exactly 3 neighbors if (neighbors === 3) { toRegen.push(cell); changed = true; } } } } // Apply changes for (var i = 0; i < toDie.length; i++) { toDie[i].setAlive(false); toDie[i].flash(); } if (toDie.length > 0) { LK.getSound('cellDie').play(); } for (var i = 0; i < toRegen.length; i++) { toRegen[i].setAlive(true); toRegen[i].flash(); } if (toRegen.length > 0) { LK.getSound('cellBorn').play(); } } // Start/stop evolution function startEvolve() { if (isRunning) { return; } isRunning = true; instructions.setText("Conway's Game of Life"); evolveTimer = LK.setInterval(function () { evolveGrid(); }, 200); } function stopEvolve() { if (!isRunning) { return; } isRunning = false; instructions.setText("Conway's Game of Life\nDraw & Press ▶"); if (evolveTimer) { LK.clearInterval(evolveTimer); evolveTimer = null; } } // Reset grid function resetGrid() { stopEvolve(); for (var y = 0; y < GRID_ROWS; y++) { for (var x = 0; x < GRID_COLS; x++) { cellNodes[y][x].setAlive(false); } } } // Step evolution once function stepEvolve() { if (isRunning) { return; } evolveGrid(); } // Draw GLAUD text pattern on grid function drawGlaud() { // Clear grid first for (var y = 0; y < GRID_ROWS; y++) { for (var x = 0; x < GRID_COLS; x++) { cellNodes[y][x].setAlive(false); } } // GLAUD pattern (3x5 letters with 1 space between) - smaller version // Starting position to center the text var startX = 3; var startY = 10; // G var G = [[1, 1, 1], [1, 0, 0], [1, 0, 1], [1, 0, 1], [1, 1, 1]]; // L var L = [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 1, 1]]; // A var A = [[1, 1, 1], [1, 0, 1], [1, 1, 1], [1, 0, 1], [1, 0, 1]]; // U var U = [[1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 1, 1]]; // D var D = [[1, 1, 0], [1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 1, 0]]; var letters = [G, L, A, U, D]; var xOffset = startX; // Draw each letter for (var letterIdx = 0; letterIdx < letters.length; letterIdx++) { var letter = letters[letterIdx]; for (var ly = 0; ly < letter.length; ly++) { for (var lx = 0; lx < letter[ly].length; lx++) { var cellX = xOffset + lx; var cellY = startY + ly; if (cellX < GRID_COLS && cellY < GRID_ROWS && letter[ly][lx] === 1) { cellNodes[cellY][cellX].setAlive(true); cellNodes[cellY][cellX].flash(); } } } xOffset += 4; // Move to next letter position (3 width + 1 space) } } // Find cell at game coordinates function getCellAt(x, y) { for (var row = 0; row < GRID_ROWS; row++) { for (var col = 0; col < GRID_COLS; col++) { var cell = cellNodes[row][col]; var left = cell.x - CELL_SIZE / 2; var right = cell.x + CELL_SIZE / 2; var top = cell.y - CELL_SIZE / 2; var bottom = cell.y + CELL_SIZE / 2; if (x >= left && x < right && y >= top && y < bottom) { return cell; } } } return null; } // Handle drawing on grid game.down = function (x, y, obj) { if (isRunning) { return; } var cell = getCellAt(x, y); if (cell) { isDrawing = true; drawState = !cell.isAlive; cell.setAlive(drawState); cell.flash(); LK.getSound('draw').play(); } }; game.move = function (x, y, obj) { if (isRunning) { return; } // Add hover effect even when not drawing var cell = getCellAt(x, y); if (cell && !isDrawing) { // Subtle hover effect tween(cell, { alpha: 0.8 }, { duration: 100 }); } if (!isDrawing) { return; } if (cell && cell.isAlive !== drawState) { cell.setAlive(drawState); cell.flash(); LK.getSound('draw').play(); } }; game.up = function (x, y, obj) { isDrawing = false; }; // Play button events playBtn.down = function (x, y, obj) { if (isRunning) { stopEvolve(); playBtn.setText("▶"); LK.getSound('evolveStop').play(); } else { startEvolve(); playBtn.setText("⏸"); LK.getSound('evolveStart').play(); } }; resetBtn.down = function (x, y, obj) { resetGrid(); playBtn.setText("▶"); LK.getSound('buttonPress').play(); }; stepBtn.down = function (x, y, obj) { stepEvolve(); LK.getSound('buttonPress').play(); }; // Prevent accidental grid drawing when using GUI LK.gui.bottom.down = function (x, y, obj) {}; LK.gui.bottom.move = function (x, y, obj) {}; LK.gui.bottom.up = function (x, y, obj) {}; // Initialize with GLAUD pattern drawGlaud(); // Play background music LK.playMusic('bgMusic'); // No update loop needed for this game game.update = function () { // No-op };
===================================================================
--- original.js
+++ change.js
@@ -13,50 +13,80 @@
var cellAsset = self.attachAsset('cell', {
anchorX: 0.5,
anchorY: 0.5
});
+ // Add inner cell for better visual effect
+ var innerCell = self.attachAsset('cell', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.85,
+ scaleY: 0.85
+ });
self.isAlive = false;
self.gridX = 0;
self.gridY = 0;
// Set cell state (alive/dead)
self.setAlive = function (alive) {
self.isAlive = alive;
- cellAsset.color = alive ? 0x4caf50 : 0x222222;
- cellAsset.alpha = alive ? 1 : 0.25;
+ cellAsset.color = alive ? 0x9c27b0 : 0x1a1a1a;
+ cellAsset.alpha = alive ? 0.9 : 0.3;
+ innerCell.color = alive ? 0x8e24aa : 0x222222;
+ innerCell.alpha = alive ? 1 : 0.2;
};
// Flash cell when it changes state
self.flash = function () {
+ // Flash outer cell
tween(cellAsset, {
- alpha: 1
+ alpha: 1,
+ scaleX: 1.1,
+ scaleY: 1.1
}, {
- duration: 120,
+ duration: 60,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(cellAsset, {
- alpha: self.isAlive ? 1 : 0.25
+ alpha: self.isAlive ? 0.9 : 0.3,
+ scaleX: 1,
+ scaleY: 1
}, {
- duration: 180
+ duration: 90
});
}
});
+ // Flash inner cell
+ tween(innerCell, {
+ scaleX: 1.2,
+ scaleY: 1.2
+ }, {
+ duration: 50,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(innerCell, {
+ scaleX: 0.85,
+ scaleY: 0.85
+ }, {
+ duration: 75
+ });
+ }
+ });
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
- backgroundColor: 0x181818
+ backgroundColor: 0x0a0a0a
});
/****
* Game Code
****/
// Grid settings
-var GRID_COLS = 16;
-var GRID_ROWS = 20;
-var CELL_SIZE = 96; // 2048/16 = 128, but use 96 for padding
+var GRID_COLS = 24;
+var GRID_ROWS = 24;
+var CELL_SIZE = 80; // Smaller cells to fit more
var GRID_WIDTH = GRID_COLS * CELL_SIZE;
var GRID_HEIGHT = GRID_ROWS * CELL_SIZE;
var GRID_OFFSET_X = (2048 - GRID_WIDTH) / 2;
var GRID_OFFSET_Y = (2732 - GRID_HEIGHT) / 2 + 60;
@@ -84,57 +114,96 @@
}
grid.push(row);
cellNodes.push(nodeRow);
}
+// Draw grid lines for visual styling
+// Horizontal lines
+for (var y = 0; y <= GRID_ROWS; y++) {
+ var hLine = LK.getAsset('gridLine', {
+ anchorX: 0,
+ anchorY: 0.5,
+ scaleX: GRID_WIDTH / 2,
+ scaleY: 1
+ });
+ hLine.x = GRID_OFFSET_X;
+ hLine.y = GRID_OFFSET_Y + y * CELL_SIZE;
+ hLine.alpha = 0.3;
+ game.addChild(hLine);
+}
+// Vertical lines
+for (var x = 0; x <= GRID_COLS; x++) {
+ var vLine = LK.getAsset('gridLine', {
+ anchorX: 0.5,
+ anchorY: 0,
+ scaleX: 1,
+ scaleY: GRID_HEIGHT / 2
+ });
+ vLine.x = GRID_OFFSET_X + x * CELL_SIZE;
+ vLine.y = GRID_OFFSET_Y;
+ vLine.alpha = 0.3;
+ game.addChild(vLine);
+}
// Draw instructions
var instructions = new Text2("Draw: Tap cells\nEvolve: Press ▶", {
size: 70,
- fill: 0xFFFFFF
+ fill: 0xE0E0E0
});
instructions.anchor.set(0.5, 0);
LK.gui.top.addChild(instructions);
+// Add Glider text below instructions
+var gliderText = new Text2("Glaud", {
+ size: 60,
+ fill: 0x9c27b0
+});
+gliderText.anchor.set(0.5, 0);
+gliderText.y = 100;
+LK.gui.top.addChild(gliderText);
// Add evolve/play button
var playBtn = new Text2("▶", {
size: 120,
- fill: 0x4CAF50
+ fill: 0x9c27b0
});
playBtn.anchor.set(0.5, 0.5);
playBtn.x = 0;
-playBtn.y = 0;
+playBtn.y = -120;
LK.gui.bottom.addChild(playBtn);
// Add reset button
var resetBtn = new Text2("⟳", {
size: 90,
fill: 0xFFFFFF
});
resetBtn.anchor.set(0.5, 0.5);
resetBtn.x = -180;
-resetBtn.y = 0;
+resetBtn.y = -120;
LK.gui.bottom.addChild(resetBtn);
// Add step button
var stepBtn = new Text2("⏭", {
size: 90,
fill: 0xFFFFFF
});
stepBtn.anchor.set(0.5, 0.5);
stepBtn.x = 180;
-stepBtn.y = 0;
+stepBtn.y = -120;
LK.gui.bottom.addChild(stepBtn);
-// Only one mode: Variant (original rules)
-instructions.setText("Draw: Tap cells\nEvolve: Press ▶");
+// Conway's Game of Life
+instructions.setText("Conway's Game of Life\nDraw & Press ▶");
// State
var isRunning = false;
var evolveTimer = null;
// Helper: get alive neighbor count
function countAliveNeighbors(gx, gy) {
var count = 0;
for (var dy = -1; dy <= 1; dy++) {
for (var dx = -1; dx <= 1; dx++) {
- if (dx === 0 && dy === 0) continue;
+ if (dx === 0 && dy === 0) {
+ continue;
+ }
var nx = gx + dx;
var ny = gy + dy;
if (nx >= 0 && nx < GRID_COLS && ny >= 0 && ny < GRID_ROWS) {
- if (cellNodes[ny][nx].isAlive) count++;
+ if (cellNodes[ny][nx].isAlive) {
+ count++;
+ }
}
}
}
return count;
@@ -149,64 +218,57 @@
for (var x = 0; x < GRID_COLS; x++) {
var cell = cellNodes[y][x];
var alive = cell.isAlive;
var neighbors = countAliveNeighbors(x, y);
- // Only one mode: original rules
+ // Conway's Game of Life rules
if (alive) {
- if (neighbors >= 5) {
+ // Living cell survives with 2 or 3 neighbors
+ if (neighbors < 2 || neighbors > 3) {
toDie.push(cell);
changed = true;
}
} else {
- if (neighbors === 9) {
+ // Dead cell becomes alive with exactly 3 neighbors
+ if (neighbors === 3) {
toRegen.push(cell);
changed = true;
}
}
}
}
- // If no cell would change, force a change: flip a random cell
- if (!changed) {
- var allCells = [];
- for (var y = 0; y < GRID_ROWS; y++) {
- for (var x = 0; x < GRID_COLS; x++) {
- allCells.push(cellNodes[y][x]);
- }
- }
- if (allCells.length > 0) {
- var idx = Math.floor(Math.random() * allCells.length);
- var cell = allCells[idx];
- if (cell.isAlive) {
- toDie.push(cell);
- } else {
- toRegen.push(cell);
- }
- }
- changed = true;
- }
// Apply changes
for (var i = 0; i < toDie.length; i++) {
toDie[i].setAlive(false);
toDie[i].flash();
}
+ if (toDie.length > 0) {
+ LK.getSound('cellDie').play();
+ }
for (var i = 0; i < toRegen.length; i++) {
toRegen[i].setAlive(true);
toRegen[i].flash();
}
+ if (toRegen.length > 0) {
+ LK.getSound('cellBorn').play();
+ }
}
// Start/stop evolution
function startEvolve() {
- if (isRunning) return;
+ if (isRunning) {
+ return;
+ }
isRunning = true;
- instructions.setText("Watch your pattern evolve!");
+ instructions.setText("Conway's Game of Life");
evolveTimer = LK.setInterval(function () {
evolveGrid();
- }, 400);
+ }, 200);
}
function stopEvolve() {
- if (!isRunning) return;
+ if (!isRunning) {
+ return;
+ }
isRunning = false;
- instructions.setText("Draw: Tap cells\nEvolve: Press ▶");
+ instructions.setText("Conway's Game of Life\nDraw & Press ▶");
if (evolveTimer) {
LK.clearInterval(evolveTimer);
evolveTimer = null;
}
@@ -221,11 +283,53 @@
}
}
// Step evolution once
function stepEvolve() {
- if (isRunning) return;
+ if (isRunning) {
+ return;
+ }
evolveGrid();
}
+// Draw GLAUD text pattern on grid
+function drawGlaud() {
+ // Clear grid first
+ for (var y = 0; y < GRID_ROWS; y++) {
+ for (var x = 0; x < GRID_COLS; x++) {
+ cellNodes[y][x].setAlive(false);
+ }
+ }
+ // GLAUD pattern (3x5 letters with 1 space between) - smaller version
+ // Starting position to center the text
+ var startX = 3;
+ var startY = 10;
+ // G
+ var G = [[1, 1, 1], [1, 0, 0], [1, 0, 1], [1, 0, 1], [1, 1, 1]];
+ // L
+ var L = [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 1, 1]];
+ // A
+ var A = [[1, 1, 1], [1, 0, 1], [1, 1, 1], [1, 0, 1], [1, 0, 1]];
+ // U
+ var U = [[1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 1, 1]];
+ // D
+ var D = [[1, 1, 0], [1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 1, 0]];
+ var letters = [G, L, A, U, D];
+ var xOffset = startX;
+ // Draw each letter
+ for (var letterIdx = 0; letterIdx < letters.length; letterIdx++) {
+ var letter = letters[letterIdx];
+ for (var ly = 0; ly < letter.length; ly++) {
+ for (var lx = 0; lx < letter[ly].length; lx++) {
+ var cellX = xOffset + lx;
+ var cellY = startY + ly;
+ if (cellX < GRID_COLS && cellY < GRID_ROWS && letter[ly][lx] === 1) {
+ cellNodes[cellY][cellX].setAlive(true);
+ cellNodes[cellY][cellX].flash();
+ }
+ }
+ }
+ xOffset += 4; // Move to next letter position (3 width + 1 space)
+ }
+}
// Find cell at game coordinates
function getCellAt(x, y) {
for (var row = 0; row < GRID_ROWS; row++) {
for (var col = 0; col < GRID_COLS; col++) {
@@ -242,24 +346,41 @@
return null;
}
// Handle drawing on grid
game.down = function (x, y, obj) {
- if (isRunning) return;
+ if (isRunning) {
+ return;
+ }
var cell = getCellAt(x, y);
if (cell) {
isDrawing = true;
drawState = !cell.isAlive;
cell.setAlive(drawState);
cell.flash();
+ LK.getSound('draw').play();
}
};
game.move = function (x, y, obj) {
- if (isRunning) return;
- if (!isDrawing) return;
+ if (isRunning) {
+ return;
+ }
+ // Add hover effect even when not drawing
var cell = getCellAt(x, y);
+ if (cell && !isDrawing) {
+ // Subtle hover effect
+ tween(cell, {
+ alpha: 0.8
+ }, {
+ duration: 100
+ });
+ }
+ if (!isDrawing) {
+ return;
+ }
if (cell && cell.isAlive !== drawState) {
cell.setAlive(drawState);
cell.flash();
+ LK.getSound('draw').play();
}
};
game.up = function (x, y, obj) {
isDrawing = false;
@@ -268,24 +389,32 @@
playBtn.down = function (x, y, obj) {
if (isRunning) {
stopEvolve();
playBtn.setText("▶");
+ LK.getSound('evolveStop').play();
} else {
startEvolve();
playBtn.setText("⏸");
+ LK.getSound('evolveStart').play();
}
};
resetBtn.down = function (x, y, obj) {
resetGrid();
playBtn.setText("▶");
+ LK.getSound('buttonPress').play();
};
stepBtn.down = function (x, y, obj) {
stepEvolve();
+ LK.getSound('buttonPress').play();
};
// Prevent accidental grid drawing when using GUI
LK.gui.bottom.down = function (x, y, obj) {};
LK.gui.bottom.move = function (x, y, obj) {};
LK.gui.bottom.up = function (x, y, obj) {};
+// Initialize with GLAUD pattern
+drawGlaud();
+// Play background music
+LK.playMusic('bgMusic');
// No update loop needed for this game
game.update = function () {
// No-op
};
\ No newline at end of file