/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Pad class for colored buttons var Pad = Container.expand(function () { var self = Container.call(this); // Properties: colorName, soundId, assetId, index self.colorName = ''; self.soundId = ''; self.assetId = ''; self.index = 0; // Attach asset var padAsset = null; self.initPad = function (colorName, soundId, assetId, index) { self.colorName = colorName; self.soundId = soundId; self.assetId = assetId; self.index = index; padAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); // For touch feedback, store reference self.padAsset = padAsset; }; // Flash the pad (light up effect) self.flash = function (duration) { // Animate scale up and alpha up, then back tween(self.padAsset, { scaleX: 3, scaleY: 3, alpha: 1 }, { duration: duration / 2, easing: tween.easeOut, onFinish: function onFinish() { tween(self.padAsset, { scaleX: 2, scaleY: 2, alpha: 0.85 }, { duration: duration / 2, easing: tween.easeIn }); } }); }; // Play the pad's sound self.playSound = function () { LK.getSound(self.soundId).play(); }; // Enable/disable pad for input self.setEnabled = function (enabled) { self.enabled = enabled; self.padAsset.alpha = enabled ? 0.85 : 0.5; }; // Touch/click event self.down = function (x, y, obj) { if (!self.enabled) { return; } // Visual feedback self.flash(180); self.playSound(); // Notify game if (typeof self.onPadPressed === 'function') { self.onPadPressed(self.index); } }; // Set default alpha self.padAsset = padAsset; if (self.padAsset) { self.padAsset.alpha = 0.85; } return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Pad definitions // Four colored pads (Red, Blue, Green, Yellow) // Sounds for each pad // Simple background music (optional, can be replaced with actual music asset) var bg = LK.getAsset('retroArcadeGridBg', {}); game.addChild(bg); var padDefs = [{ colorName: 'red', soundId: 'sndRed', assetId: 'arcadeBtnRed64' // pixel art red arcade button, glowing, 64x64 }, { colorName: 'blue', soundId: 'sndBlue', assetId: 'arcadeBtnBlue64' // pixel art blue arcade button, glowing, 64x64 }, { colorName: 'green', soundId: 'sndGreen', assetId: 'arcadeBtnGreen64' // pixel art green arcade button, glowing, 64x64 }, { colorName: 'yellow', soundId: 'sndYellow', assetId: 'arcadeBtnYellow64' // pixel art yellow arcade button, glowing, 64x64 }]; // Pad positions (2x2 grid, centered) var padPositions = [{ x: 2048 / 2 - 340, y: 2732 / 2 - 340 }, // Top-left (Red) { x: 2048 / 2 + 340, y: 2732 / 2 - 340 }, // Top-right (Blue) { x: 2048 / 2 - 340, y: 2732 / 2 + 340 }, // Bottom-left (Green) { x: 2048 / 2 + 340, y: 2732 / 2 + 340 } // Bottom-right (Yellow) ]; // Game state variables var pads = []; var sequence = []; var playerStep = 0; var isPlayerTurn = false; var isAnimating = false; var score = 0; var highScore = 0; var sequenceTimer = null; var showSequenceIndex = 0; // Pattern and music speed control var patternStepDuration = 480; // ms, initial step duration var musicTempo = 1.0; // initial music rate // Score text var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // "Get Ready" text var infoTxt = new Text2('', { size: 90, fill: 0xFFFBE0 }); infoTxt.anchor.set(0.5, 0.5); infoTxt.visible = false; LK.gui.center.addChild(infoTxt); // Create pads and add to game for (var i = 0; i < 4; i++) { var pad = new Pad(); pad.initPad(padDefs[i].colorName, padDefs[i].soundId, padDefs[i].assetId, i); pad.x = padPositions[i].x; pad.y = padPositions[i].y; pad.setEnabled(false); // Pad press callback pad.onPadPressed = function (padIndex) { if (!isPlayerTurn || isAnimating) { return; } handlePlayerInput(padIndex); }; pads.push(pad); game.addChild(pad); } // Start background music LK.playMusic('bgmusic', { fade: { start: 0, end: 1, duration: 1200 } }); // Start the game startNewGame(); function startNewGame() { sequence = []; playerStep = 0; score = 0; isPlayerTurn = false; isAnimating = false; showSequenceIndex = 0; scoreTxt.setText('0'); infoTxt.setText('Get Ready!'); infoTxt.visible = true; setPadsEnabled(false); patternStepDuration = 480; musicTempo = 1.0; LK.playMusic('bgmusic', { rate: musicTempo }); // Short delay before first round LK.setTimeout(function () { infoTxt.visible = false; addToSequence(); showSequence(); }, 900); } function setPadsEnabled(enabled) { for (var i = 0; i < pads.length; i++) { pads[i].setEnabled(enabled); } } // Add a random color to the sequence function addToSequence() { var next = Math.floor(Math.random() * 4); sequence.push(next); } // Show the sequence to the player (one by one) function showSequence() { isAnimating = true; isPlayerTurn = false; setPadsEnabled(false); showSequenceIndex = 0; playSequenceStep(); } function playSequenceStep() { if (showSequenceIndex >= sequence.length) { // Sequence done, player's turn isAnimating = false; isPlayerTurn = true; setPadsEnabled(true); playerStep = 0; return; } var padIndex = sequence[showSequenceIndex]; var pad = pads[padIndex]; pad.flash(320); pad.playSound(); showSequenceIndex++; sequenceTimer = LK.setTimeout(playSequenceStep, patternStepDuration); } // Handle player input function handlePlayerInput(padIndex) { if (!isPlayerTurn || isAnimating) { return; } // Check if correct if (padIndex === sequence[playerStep]) { playerStep++; if (playerStep === sequence.length) { // Completed sequence, next round score++; scoreTxt.setText(score + ''); isPlayerTurn = false; setPadsEnabled(false); // Speed up pattern and music every 2 levels if (score % 2 === 0) { // Calculate new pattern speed (minimum 180ms) patternStepDuration = Math.max(180, 480 - Math.floor(score / 2) * 80); // Calculate new music tempo (1.0 + 0.1 per 2 levels, max 2.0) musicTempo = Math.min(2.0, 1.0 + score / 2 * 0.1); LK.playMusic('bgmusic', { rate: musicTempo }); } LK.setTimeout(function () { addToSequence(); showSequence(); }, 700); } } else { // Wrong input, game over pads[padIndex].flash(400); LK.effects.flashScreen(0xff0000, 800); setPadsEnabled(false); infoTxt.setText('Game Over'); infoTxt.visible = true; LK.setTimeout(function () { infoTxt.visible = false; LK.showGameOver(); }, 1200); } } // Optional: allow restart on game over by tapping anywhere game.down = function (x, y, obj) { // Only allow restart if not animating and not player's turn if (!isPlayerTurn && !isAnimating && !infoTxt.visible) { startNewGame(); } }; // Clean up on destroy (not strictly needed, but good practice) game.destroy = function () { if (sequenceTimer) { LK.clearTimeout(sequenceTimer); } LK.stopMusic(); }; // Main update loop (not much needed here) game.update = function () { // No per-frame logic needed for this game };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Pad class for colored buttons
var Pad = Container.expand(function () {
var self = Container.call(this);
// Properties: colorName, soundId, assetId, index
self.colorName = '';
self.soundId = '';
self.assetId = '';
self.index = 0;
// Attach asset
var padAsset = null;
self.initPad = function (colorName, soundId, assetId, index) {
self.colorName = colorName;
self.soundId = soundId;
self.assetId = assetId;
self.index = index;
padAsset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
// For touch feedback, store reference
self.padAsset = padAsset;
};
// Flash the pad (light up effect)
self.flash = function (duration) {
// Animate scale up and alpha up, then back
tween(self.padAsset, {
scaleX: 3,
scaleY: 3,
alpha: 1
}, {
duration: duration / 2,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.padAsset, {
scaleX: 2,
scaleY: 2,
alpha: 0.85
}, {
duration: duration / 2,
easing: tween.easeIn
});
}
});
};
// Play the pad's sound
self.playSound = function () {
LK.getSound(self.soundId).play();
};
// Enable/disable pad for input
self.setEnabled = function (enabled) {
self.enabled = enabled;
self.padAsset.alpha = enabled ? 0.85 : 0.5;
};
// Touch/click event
self.down = function (x, y, obj) {
if (!self.enabled) {
return;
}
// Visual feedback
self.flash(180);
self.playSound();
// Notify game
if (typeof self.onPadPressed === 'function') {
self.onPadPressed(self.index);
}
};
// Set default alpha
self.padAsset = padAsset;
if (self.padAsset) {
self.padAsset.alpha = 0.85;
}
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Pad definitions
// Four colored pads (Red, Blue, Green, Yellow)
// Sounds for each pad
// Simple background music (optional, can be replaced with actual music asset)
var bg = LK.getAsset('retroArcadeGridBg', {});
game.addChild(bg);
var padDefs = [{
colorName: 'red',
soundId: 'sndRed',
assetId: 'arcadeBtnRed64' // pixel art red arcade button, glowing, 64x64
}, {
colorName: 'blue',
soundId: 'sndBlue',
assetId: 'arcadeBtnBlue64' // pixel art blue arcade button, glowing, 64x64
}, {
colorName: 'green',
soundId: 'sndGreen',
assetId: 'arcadeBtnGreen64' // pixel art green arcade button, glowing, 64x64
}, {
colorName: 'yellow',
soundId: 'sndYellow',
assetId: 'arcadeBtnYellow64' // pixel art yellow arcade button, glowing, 64x64
}];
// Pad positions (2x2 grid, centered)
var padPositions = [{
x: 2048 / 2 - 340,
y: 2732 / 2 - 340
},
// Top-left (Red)
{
x: 2048 / 2 + 340,
y: 2732 / 2 - 340
},
// Top-right (Blue)
{
x: 2048 / 2 - 340,
y: 2732 / 2 + 340
},
// Bottom-left (Green)
{
x: 2048 / 2 + 340,
y: 2732 / 2 + 340
} // Bottom-right (Yellow)
];
// Game state variables
var pads = [];
var sequence = [];
var playerStep = 0;
var isPlayerTurn = false;
var isAnimating = false;
var score = 0;
var highScore = 0;
var sequenceTimer = null;
var showSequenceIndex = 0;
// Pattern and music speed control
var patternStepDuration = 480; // ms, initial step duration
var musicTempo = 1.0; // initial music rate
// Score text
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// "Get Ready" text
var infoTxt = new Text2('', {
size: 90,
fill: 0xFFFBE0
});
infoTxt.anchor.set(0.5, 0.5);
infoTxt.visible = false;
LK.gui.center.addChild(infoTxt);
// Create pads and add to game
for (var i = 0; i < 4; i++) {
var pad = new Pad();
pad.initPad(padDefs[i].colorName, padDefs[i].soundId, padDefs[i].assetId, i);
pad.x = padPositions[i].x;
pad.y = padPositions[i].y;
pad.setEnabled(false);
// Pad press callback
pad.onPadPressed = function (padIndex) {
if (!isPlayerTurn || isAnimating) {
return;
}
handlePlayerInput(padIndex);
};
pads.push(pad);
game.addChild(pad);
}
// Start background music
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 1,
duration: 1200
}
});
// Start the game
startNewGame();
function startNewGame() {
sequence = [];
playerStep = 0;
score = 0;
isPlayerTurn = false;
isAnimating = false;
showSequenceIndex = 0;
scoreTxt.setText('0');
infoTxt.setText('Get Ready!');
infoTxt.visible = true;
setPadsEnabled(false);
patternStepDuration = 480;
musicTempo = 1.0;
LK.playMusic('bgmusic', {
rate: musicTempo
});
// Short delay before first round
LK.setTimeout(function () {
infoTxt.visible = false;
addToSequence();
showSequence();
}, 900);
}
function setPadsEnabled(enabled) {
for (var i = 0; i < pads.length; i++) {
pads[i].setEnabled(enabled);
}
}
// Add a random color to the sequence
function addToSequence() {
var next = Math.floor(Math.random() * 4);
sequence.push(next);
}
// Show the sequence to the player (one by one)
function showSequence() {
isAnimating = true;
isPlayerTurn = false;
setPadsEnabled(false);
showSequenceIndex = 0;
playSequenceStep();
}
function playSequenceStep() {
if (showSequenceIndex >= sequence.length) {
// Sequence done, player's turn
isAnimating = false;
isPlayerTurn = true;
setPadsEnabled(true);
playerStep = 0;
return;
}
var padIndex = sequence[showSequenceIndex];
var pad = pads[padIndex];
pad.flash(320);
pad.playSound();
showSequenceIndex++;
sequenceTimer = LK.setTimeout(playSequenceStep, patternStepDuration);
}
// Handle player input
function handlePlayerInput(padIndex) {
if (!isPlayerTurn || isAnimating) {
return;
}
// Check if correct
if (padIndex === sequence[playerStep]) {
playerStep++;
if (playerStep === sequence.length) {
// Completed sequence, next round
score++;
scoreTxt.setText(score + '');
isPlayerTurn = false;
setPadsEnabled(false);
// Speed up pattern and music every 2 levels
if (score % 2 === 0) {
// Calculate new pattern speed (minimum 180ms)
patternStepDuration = Math.max(180, 480 - Math.floor(score / 2) * 80);
// Calculate new music tempo (1.0 + 0.1 per 2 levels, max 2.0)
musicTempo = Math.min(2.0, 1.0 + score / 2 * 0.1);
LK.playMusic('bgmusic', {
rate: musicTempo
});
}
LK.setTimeout(function () {
addToSequence();
showSequence();
}, 700);
}
} else {
// Wrong input, game over
pads[padIndex].flash(400);
LK.effects.flashScreen(0xff0000, 800);
setPadsEnabled(false);
infoTxt.setText('Game Over');
infoTxt.visible = true;
LK.setTimeout(function () {
infoTxt.visible = false;
LK.showGameOver();
}, 1200);
}
}
// Optional: allow restart on game over by tapping anywhere
game.down = function (x, y, obj) {
// Only allow restart if not animating and not player's turn
if (!isPlayerTurn && !isAnimating && !infoTxt.visible) {
startNewGame();
}
};
// Clean up on destroy (not strictly needed, but good practice)
game.destroy = function () {
if (sequenceTimer) {
LK.clearTimeout(sequenceTimer);
}
LK.stopMusic();
};
// Main update loop (not much needed here)
game.update = function () {
// No per-frame logic needed for this game
};