User prompt
make the create account buttton work and when done signing up it saves your data for your account ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
remove the create account text
User prompt
now add the asset for the create account button to the button
User prompt
make an asset for the create account button
User prompt
for some reason when i click on password field it types into the enter name field fix it
User prompt
under the enter your name field make a password one and under that make a button thats says create account
User prompt
if a player cant get a match in 5 seconds then they should see bouncing gems and it should be a hint how u could match do that for me ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
still good job u reduced but its still not working sometimes please fix
User prompt
sometimes when i move somewhere i can match with gems it doesnt work sometimes fix it please
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Gem = Container.expand(function (type) {
var self = Container.call(this);
self.gemType = type;
self.gridX = 0;
self.gridY = 0;
self.isAnimating = false;
self.isScaling = false;
var gemAssets = ['gem_red', 'gem_blue', 'gem_green', 'gem_yellow', 'gem_purple', 'gem_orange', 'gem_cyan', 'gem_pink'];
var gemGraphics = self.attachAsset(gemAssets[type], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: CELL_SIZE / 256,
scaleY: CELL_SIZE / 256
});
self.setGridPosition = function (gridX, gridY) {
self.gridX = gridX;
self.gridY = gridY;
self.x = boardStartX + gridX * CELL_SIZE + CELL_SIZE / 2;
self.y = boardStartY + gridY * CELL_SIZE + CELL_SIZE / 2;
};
self.animateToPosition = function (targetX, targetY, duration, onComplete) {
if (duration === undefined) duration = 300;
self.isAnimating = true;
tween(self, {
x: targetX,
y: targetY
}, {
duration: duration,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isAnimating = false;
if (onComplete) onComplete();
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x8B4513 // Brown background
});
/****
* Game Code
****/
// Gold yellow
// Deep pink
// Medium slate blue
var GAME_STATE_HOME = 0;
var GAME_STATE_PLAYING = 1;
var GAME_STATE_PAUSED = 2;
var currentGameState = GAME_STATE_HOME;
// Pause menu elements
var pauseMenuContainer = null;
var pauseMenuBg = null;
var volumeButton = null;
var exitButton = null;
var resumeButton = null;
var volumeEnabled = storage.volumeEnabled !== undefined ? storage.volumeEnabled : true;
var BOARD_SIZE = 8; // Smaller board for kids - easier to see patterns
var CELL_SIZE = Math.floor(Math.min(2048, 2732 - 500) / BOARD_SIZE * 0.95); // Bigger gems, leave more space for UI
var BOARD_TOTAL_SIZE = BOARD_SIZE * CELL_SIZE;
var boardStartX = (2048 - BOARD_TOTAL_SIZE) / 2;
var boardStartY = (2732 - BOARD_TOTAL_SIZE) / 2 + 100; // Offset for top UI
var board = [];
var gems = [];
var selectedGem = null;
var isProcessingMatches = false;
var isDragging = false;
var dragStartX = 0;
var dragStartY = 0;
var score = 0;
// Home screen elements
var homeContainer = null;
var playButton = null;
var titleText = null;
var textInputField = null;
var textInputBorder = null;
var textInputText = null;
var inputText = '';
var passwordInputField = null;
var passwordInputBorder = null;
var passwordInputText = null;
var passwordText = '';
var createAccountButton = null;
var activeInputField = 'name'; // Track which field is active: 'name' or 'password'
var keyboardContainer = null;
var keyboardVisible = false;
var keyboardKeys = [];
var keyboardLayout = [['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'], ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'], ['Z', 'X', 'C', 'V', 'B', 'N', 'M']];
function createPauseMenu() {
pauseMenuContainer = new Container();
game.addChild(pauseMenuContainer);
// Create semi-transparent background
pauseMenuBg = pauseMenuContainer.attachAsset('pauseMenuBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
// Pause menu title
var pauseTitle = new Text2('GAME PAUSED', {
size: 80,
fill: 0xFFFFFF
});
pauseTitle.anchor.set(0.5, 0.5);
pauseTitle.x = 2048 / 2;
pauseTitle.y = 2732 / 2 - 200;
pauseMenuContainer.addChild(pauseTitle);
// Resume button
resumeButton = pauseMenuContainer.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 100
});
var resumeText = new Text2('RESUME GAME', {
size: 50,
fill: 0xFFFFFF
});
resumeText.anchor.set(0.5, 0.5);
resumeText.x = 2048 / 2;
resumeText.y = 2732 / 2 - 100;
pauseMenuContainer.addChild(resumeText);
// Volume toggle button
volumeButton = pauseMenuContainer.attachAsset('volumeToggle', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
var volumeText = new Text2(volumeEnabled ? 'VOLUME: ON' : 'VOLUME: OFF', {
size: 40,
fill: 0xFFFFFF
});
volumeText.anchor.set(0.5, 0.5);
volumeText.x = 2048 / 2;
volumeText.y = 2732 / 2;
pauseMenuContainer.addChild(volumeText);
// Exit button
exitButton = pauseMenuContainer.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 100
});
var exitText = new Text2('EXIT TO MENU', {
size: 50,
fill: 0xFFFFFF
});
exitText.anchor.set(0.5, 0.5);
exitText.x = 2048 / 2;
exitText.y = 2732 / 2 + 100;
pauseMenuContainer.addChild(exitText);
// Store reference to volume text for updates
pauseMenuContainer.volumeText = volumeText;
}
function createCustomKeyboard() {
if (keyboardContainer) return; // Already exists
keyboardContainer = new Container();
game.addChild(keyboardContainer);
// Create keyboard background
var keyboardBg = keyboardContainer.attachAsset('keyboardBg', {
anchorX: 0.5,
anchorY: 1.0,
x: 2048 / 2,
y: 2732
});
// Clear previous keys
keyboardKeys = [];
var startY = 2732 - 750; // Start position for keys
var keySpacing = 150;
var rowSpacing = 110;
// Create letter keys
for (var row = 0; row < keyboardLayout.length; row++) {
var rowKeys = keyboardLayout[row];
var rowWidth = rowKeys.length * keySpacing;
var startX = (2048 - rowWidth) / 2 + keySpacing / 2;
for (var col = 0; col < rowKeys.length; col++) {
var letter = rowKeys[col];
var keyX = startX + col * keySpacing;
var keyY = startY + row * rowSpacing;
var key = keyboardContainer.attachAsset('keyboardKey', {
anchorX: 0.5,
anchorY: 0.5,
x: keyX,
y: keyY
});
var keyText = new Text2(letter, {
size: 45,
fill: 0xFFFFFF
});
keyText.anchor.set(0.5, 0.5);
keyText.x = keyX;
keyText.y = keyY;
keyboardContainer.addChild(keyText);
keyboardKeys.push({
key: key,
text: keyText,
letter: letter,
x: keyX,
y: keyY,
width: 140,
height: 100
});
}
}
// Create space key
var spaceKey = keyboardContainer.attachAsset('keyboardSpaceKey', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: startY + 3 * rowSpacing
});
var spaceText = new Text2('SPACE', {
size: 40,
fill: 0xFFFFFF
});
spaceText.anchor.set(0.5, 0.5);
spaceText.x = 2048 / 2;
spaceText.y = startY + 3 * rowSpacing;
keyboardContainer.addChild(spaceText);
keyboardKeys.push({
key: spaceKey,
text: spaceText,
letter: ' ',
x: 2048 / 2,
y: startY + 3 * rowSpacing,
width: 400,
height: 100
});
// Create backspace key
var backspaceKey = keyboardContainer.attachAsset('keyboardBackspaceKey', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 300,
y: startY + 3 * rowSpacing
});
var backspaceText = new Text2('←', {
size: 50,
fill: 0xFFFFFF
});
backspaceText.anchor.set(0.5, 0.5);
backspaceText.x = 2048 / 2 - 300;
backspaceText.y = startY + 3 * rowSpacing;
keyboardContainer.addChild(backspaceText);
keyboardKeys.push({
key: backspaceKey,
text: backspaceText,
letter: 'BACKSPACE',
x: 2048 / 2 - 300,
y: startY + 3 * rowSpacing,
width: 200,
height: 100
});
// Create done key
var doneKey = keyboardContainer.attachAsset('keyboardDoneKey', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 300,
y: startY + 3 * rowSpacing
});
var doneText = new Text2('DONE', {
size: 40,
fill: 0xFFFFFF
});
doneText.anchor.set(0.5, 0.5);
doneText.x = 2048 / 2 + 300;
doneText.y = startY + 3 * rowSpacing;
keyboardContainer.addChild(doneText);
keyboardKeys.push({
key: doneKey,
text: doneText,
letter: 'DONE',
x: 2048 / 2 + 300,
y: startY + 3 * rowSpacing,
width: 200,
height: 100
});
// Animate keyboard sliding up
keyboardContainer.y = 800;
tween(keyboardContainer, {
y: 0
}, {
duration: 300,
easing: tween.easeOut
});
keyboardVisible = true;
}
function hideCustomKeyboard() {
if (!keyboardContainer) return;
tween(keyboardContainer, {
y: 800
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
if (keyboardContainer) {
keyboardContainer.destroy();
keyboardContainer = null;
keyboardKeys = [];
keyboardVisible = false;
}
}
});
}
function handleKeyboardInput(letter) {
if (letter === 'BACKSPACE') {
if (activeInputField === 'name') {
if (inputText.length > 0) {
inputText = inputText.slice(0, -1);
}
} else if (activeInputField === 'password') {
if (passwordText.length > 0) {
passwordText = passwordText.slice(0, -1);
}
}
} else if (letter === 'DONE') {
hideCustomKeyboard();
return;
} else if (letter === ' ') {
if (activeInputField === 'name') {
if (inputText.length < 20) {
inputText += ' ';
}
} else if (activeInputField === 'password') {
if (passwordText.length < 20) {
passwordText += ' ';
}
}
} else {
if (activeInputField === 'name') {
if (inputText.length < 20) {
inputText += letter;
}
} else if (activeInputField === 'password') {
if (passwordText.length < 20) {
passwordText += letter;
}
}
}
// Update text display based on active field
if (activeInputField === 'name' && textInputText) {
if (inputText.length === 0) {
textInputText.setText('Enter your name...');
textInputText.fill = 0x888888;
} else {
textInputText.setText(inputText);
textInputText.fill = 0x000000;
}
} else if (activeInputField === 'password' && passwordInputText) {
if (passwordText.length === 0) {
passwordInputText.setText('Enter password...');
passwordInputText.fill = 0x888888;
} else {
// Show asterisks for password
var maskedPassword = '*'.repeat(passwordText.length);
passwordInputText.setText(maskedPassword);
passwordInputText.fill = 0x000000;
}
}
}
function createHomeScreen() {
homeContainer = new Container();
game.addChild(homeContainer);
// Create title using gemMatchTitle asset
titleText = homeContainer.attachAsset('gemMatchTitle', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 800
});
// Create play button using playButton asset
playButton = homeContainer.attachAsset('playButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1400
});
// Play button text removed per request
// Create text input field under play button
textInputBorder = homeContainer.attachAsset('textInputBorder', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1600
});
textInputField = homeContainer.attachAsset('textInputField', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1600
});
// Create placeholder text for input field
textInputText = new Text2('Enter your name...', {
size: 50,
fill: 0x888888
});
textInputText.anchor.set(0.5, 0.5);
textInputText.x = 2048 / 2;
textInputText.y = 1600;
homeContainer.addChild(textInputText);
// Create password input field under name field
passwordInputBorder = homeContainer.attachAsset('textInputBorder', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1750
});
passwordInputField = homeContainer.attachAsset('textInputField', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1750
});
// Create placeholder text for password field
passwordInputText = new Text2('Enter password...', {
size: 50,
fill: 0x888888
});
passwordInputText.anchor.set(0.5, 0.5);
passwordInputText.x = 2048 / 2;
passwordInputText.y = 1750;
homeContainer.addChild(passwordInputText);
// Create account button under password field
createAccountButton = homeContainer.attachAsset('createAccountButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1900
});
// Add bouncy animation to play button
tween(playButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(playButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Restart the bounce animation
if (currentGameState === GAME_STATE_HOME && playButton) {
tween(playButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 1000,
easing: tween.easeInOut
});
}
}
});
}
});
// Add super vibrant rainbow color animation with bounce effect
var rainbowColors = [0xFF0080, 0x00FF80, 0x8000FF, 0xFF8000, 0x0080FF, 0xFF4080, 0x80FF00, 0xFF0040];
var colorIndex = 0;
function animateTitle() {
if (currentGameState === GAME_STATE_HOME && titleText && titleText.fill !== undefined) {
// Color transition
tween(titleText, {
fill: rainbowColors[colorIndex]
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
colorIndex = (colorIndex + 1) % rainbowColors.length;
LK.setTimeout(animateTitle, 100);
}
});
// Add bouncy scale animation
if (titleText.scaleX !== undefined && titleText.scaleY !== undefined) {
tween(titleText, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (titleText && titleText.scaleX !== undefined && titleText.scaleY !== undefined) {
tween(titleText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeIn
});
}
}
});
}
}
}
animateTitle();
}
function startGame() {
currentGameState = GAME_STATE_PLAYING;
// Reset moves for new game
movesRemaining = maxMoves;
// Reset hint system
lastMoveTime = LK.ticks;
clearHintAnimations();
// Remove home screen
if (homeContainer) {
homeContainer.destroy();
homeContainer = null;
playButton = null;
titleText = null;
passwordInputField = null;
passwordInputBorder = null;
passwordInputText = null;
createAccountButton = null;
}
// Create game elements
createGameElements();
initializeBoard();
}
function createGameElements() {
// Create board background
var boardBackground = game.addChild(LK.getAsset('boardBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: boardStartY + BOARD_TOTAL_SIZE / 2,
scaleX: BOARD_TOTAL_SIZE / 960,
scaleY: BOARD_TOTAL_SIZE / 960
}));
// Initialize score display with bright colors
scoreTxt = new Text2('Score: 0', {
size: 90,
fill: 0xFF1493 // Bright pink text
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 80;
// Add target score display
targetTxt = new Text2('Target: ' + targetScore, {
size: 70,
fill: 0x32CD32 // Bright green text
});
targetTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(targetTxt);
targetTxt.y = 180;
// Add encouraging message display
messageTxt = new Text2('Match the colorful gems!', {
size: 60,
fill: 0xFFD700 // Golden yellow text
});
messageTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(messageTxt);
messageTxt.y = 250;
// Add moves display next to target
movesTxt = new Text2('Moves: ' + movesRemaining, {
size: 70,
fill: 0xFF4500 // Orange red text
});
movesTxt.anchor.set(0, 0);
LK.gui.top.addChild(movesTxt);
movesTxt.x = targetTxt.x + targetTxt.width / 2 + 50;
movesTxt.y = 180;
// Create pause button below the game board
pauseButton = game.addChild(LK.getAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: boardStartY + BOARD_TOTAL_SIZE + 150
}));
// Pause button text removed per request
}
// UI elements - declare globally but create in game
var scoreTxt = null;
var targetTxt = null;
var messageTxt = null;
var movesTxt = null;
var pauseButton = null;
var targetScore = 500; // Kid-friendly target
var maxMoves = 20; // Limited moves for the game
var movesRemaining = maxMoves;
// Hint system variables
var lastMoveTime = 0;
var hintTimeout = null;
var hintAnimations = [];
function initializeBoard() {
// Create 2D array for board
for (var y = 0; y < BOARD_SIZE; y++) {
board[y] = [];
gems[y] = [];
for (var x = 0; x < BOARD_SIZE; x++) {
var gemType = Math.floor(Math.random() * 8);
var gem = new Gem(gemType);
gem.setGridPosition(x, y);
board[y][x] = gemType;
gems[y][x] = gem;
game.addChild(gem);
}
}
// Remove initial matches
removeInitialMatches();
}
function clearHintAnimations() {
// Stop all hint animations
for (var i = 0; i < hintAnimations.length; i++) {
var hintData = hintAnimations[i];
if (hintData.gem && hintData.gem.scaleX !== undefined) {
tween.stop(hintData.gem, {
scaleX: true,
scaleY: true
});
// Reset scale to normal
var originalScale = CELL_SIZE / 256;
hintData.gem.scaleX = originalScale;
hintData.gem.scaleY = originalScale;
}
}
hintAnimations = [];
// Clear hint timeout
if (hintTimeout) {
LK.clearTimeout(hintTimeout);
hintTimeout = null;
}
}
function removeInitialMatches() {
var foundMatches = true;
var iterations = 0;
while (foundMatches && iterations < 10) {
foundMatches = false;
iterations++;
for (var y = 0; y < BOARD_SIZE; y++) {
for (var x = 0; x < BOARD_SIZE; x++) {
if (hasMatchAt(x, y)) {
var newType = Math.floor(Math.random() * 8);
board[y][x] = newType;
gems[y][x].gemType = newType;
// Update gem graphics by recreating
gems[y][x].destroy();
var newGem = new Gem(newType);
newGem.setGridPosition(x, y);
gems[y][x] = newGem;
game.addChild(newGem);
foundMatches = true;
}
}
}
}
}
function findPossibleMoves() {
var possibleMoves = [];
for (var y = 0; y < BOARD_SIZE; y++) {
for (var x = 0; x < BOARD_SIZE; x++) {
if (board[y][x] === -1) continue;
// Check adjacent positions for potential swaps
var directions = [{
dx: 1,
dy: 0
}, {
dx: -1,
dy: 0
}, {
dx: 0,
dy: 1
}, {
dx: 0,
dy: -1
}];
for (var d = 0; d < directions.length; d++) {
var newX = x + directions[d].dx;
var newY = y + directions[d].dy;
if (newX >= 0 && newX < BOARD_SIZE && newY >= 0 && newY < BOARD_SIZE && board[newY][newX] !== -1) {
// Simulate swap
var originalType1 = board[y][x];
var originalType2 = board[newY][newX];
board[y][x] = originalType2;
board[newY][newX] = originalType1;
// Check if this creates matches
if (hasMatchAt(x, y) || hasMatchAt(newX, newY)) {
possibleMoves.push({
gem1: {
x: x,
y: y
},
gem2: {
x: newX,
y: newY
}
});
}
// Revert swap
board[y][x] = originalType1;
board[newY][newX] = originalType2;
}
}
}
}
return possibleMoves;
}
function hasMatchAt(x, y) {
if (board[y][x] === undefined || board[y][x] === -1) return false;
var gemType = board[y][x];
// Check horizontal match
var horizontalCount = 1;
// Check left
for (var i = x - 1; i >= 0 && board[y] && board[y][i] === gemType; i--) {
horizontalCount++;
}
// Check right
for (var i = x + 1; i < BOARD_SIZE && board[y] && board[y][i] === gemType; i++) {
horizontalCount++;
}
// Check vertical match
var verticalCount = 1;
// Check up
for (var i = y - 1; i >= 0 && board[i] && board[i][x] === gemType; i--) {
verticalCount++;
}
// Check down
for (var i = y + 1; i < BOARD_SIZE && board[i] && board[i][x] === gemType; i++) {
verticalCount++;
}
return horizontalCount >= 3 || verticalCount >= 3;
}
function showHint() {
// Clear any existing hint animations
clearHintAnimations();
// Find possible moves
var possibleMoves = findPossibleMoves();
if (possibleMoves.length === 0) return;
// Pick a random possible move
var randomMove = possibleMoves[Math.floor(Math.random() * possibleMoves.length)];
var gem1 = gems[randomMove.gem1.y][randomMove.gem1.x];
var gem2 = gems[randomMove.gem2.y][randomMove.gem2.x];
if (!gem1 || !gem2) return;
// Create bouncing animation for both gems
var originalScale = CELL_SIZE / 256;
var hintGems = [gem1, gem2];
var hintColors = [0xFFFF00, 0x00FFFF]; // Yellow and cyan for visibility
var _loop = function _loop() {
gem = hintGems[i];
color = hintColors[i]; // Flash the gem with hint color
LK.effects.flashObject(gem, color, 800);
// Add bouncing animation
function createBounceAnimation(targetGem) {
function bounce() {
if (hintAnimations.length === 0) return; // Stop if hints were cleared
tween(targetGem, {
scaleX: originalScale * 1.3,
scaleY: originalScale * 1.3
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
if (hintAnimations.length === 0) return; // Stop if hints were cleared
tween(targetGem, {
scaleX: originalScale,
scaleY: originalScale
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
// Continue bouncing
LK.setTimeout(bounce, 200);
}
});
}
});
}
bounce();
}
createBounceAnimation(gem);
hintAnimations.push({
gem: gem
});
},
gem,
color;
for (var i = 0; i < hintGems.length; i++) {
_loop();
}
}
function getGemAt(gameX, gameY) {
var gridX = Math.floor((gameX - boardStartX) / CELL_SIZE);
var gridY = Math.floor((gameY - boardStartY) / CELL_SIZE);
if (gridX >= 0 && gridX < BOARD_SIZE && gridY >= 0 && gridY < BOARD_SIZE) {
return gems[gridY][gridX];
}
return null;
}
function isAdjacent(gem1, gem2) {
var dx = Math.abs(gem1.gridX - gem2.gridX);
var dy = Math.abs(gem1.gridY - gem2.gridY);
return dx === 1 && dy === 0 || dx === 0 && dy === 1;
}
function swapGems(gem1, gem2) {
if (!gem1 || !gem2 || gem1.isAnimating || gem2.isAnimating) return;
// Store original positions and types
var originalGem1X = gem1.gridX;
var originalGem1Y = gem1.gridY;
var originalGem2X = gem2.gridX;
var originalGem2Y = gem2.gridY;
var originalGem1Type = gem1.gemType;
var originalGem2Type = gem2.gemType;
// Calculate original visual positions
var originalGem1PosX = boardStartX + originalGem1X * CELL_SIZE + CELL_SIZE / 2;
var originalGem1PosY = boardStartY + originalGem1Y * CELL_SIZE + CELL_SIZE / 2;
var originalGem2PosX = boardStartX + originalGem2X * CELL_SIZE + CELL_SIZE / 2;
var originalGem2PosY = boardStartY + originalGem2Y * CELL_SIZE + CELL_SIZE / 2;
// Temporarily update board and gem properties to test for matches
board[originalGem1Y][originalGem1X] = originalGem2Type;
board[originalGem2Y][originalGem2X] = originalGem1Type;
gem1.gemType = originalGem2Type;
gem2.gemType = originalGem1Type;
// Check if this swap creates any matches
var hasMatch = hasMatchAt(originalGem1X, originalGem1Y) || hasMatchAt(originalGem2X, originalGem2Y);
if (hasMatch) {
// Valid swap - complete the swap
gem1.setGridPosition(originalGem2X, originalGem2Y);
gem2.setGridPosition(originalGem1X, originalGem1Y);
// Update gems array
gems[originalGem1Y][originalGem1X] = gem2;
gems[originalGem2Y][originalGem2X] = gem1;
// Animate to swapped positions
gem1.animateToPosition(originalGem2PosX, originalGem2PosY, 200);
gem2.animateToPosition(originalGem1PosX, originalGem1PosY, 200, function () {
if (volumeEnabled) {
var swapSound = LK.getSound('swap');
if (swapSound) swapSound.play();
}
// Decrement moves on successful swap
movesRemaining--;
if (movesTxt) {
movesTxt.setText('Moves: ' + movesRemaining);
// Color code the moves display
if (movesRemaining <= 3) {
movesTxt.fill = 0xFF0000; // Red - critical
} else if (movesRemaining <= 5) {
movesTxt.fill = 0xFF8C00; // Orange - warning
} else {
movesTxt.fill = 0xFF4500; // Orange red - normal
}
}
// Update hint system - player made a move
lastMoveTime = LK.ticks;
clearHintAnimations();
checkForMatches();
});
} else {
// Invalid swap - revert changes
board[originalGem1Y][originalGem1X] = originalGem1Type;
board[originalGem2Y][originalGem2X] = originalGem2Type;
gem1.gemType = originalGem1Type;
gem2.gemType = originalGem2Type;
// Animate gems briefly toward each other then back
var swapDistance = 30;
var gem1SwipePosX = originalGem1PosX + (originalGem2PosX - originalGem1PosX) * 0.3;
var gem1SwipePosY = originalGem1PosY + (originalGem2PosY - originalGem1PosY) * 0.3;
var gem2SwipePosX = originalGem2PosX + (originalGem1PosX - originalGem2PosX) * 0.3;
var gem2SwipePosY = originalGem2PosY + (originalGem1PosY - originalGem2PosY) * 0.3;
// First animate toward each other
gem1.animateToPosition(gem1SwipePosX, gem1SwipePosY, 150, function () {
// Then animate back to original positions
gem1.animateToPosition(originalGem1PosX, originalGem1PosY, 150);
});
gem2.animateToPosition(gem2SwipePosX, gem2SwipePosY, 150, function () {
// Then animate back to original positions
gem2.animateToPosition(originalGem2PosX, originalGem2PosY, 150);
if (volumeEnabled) {
var invalidSound = LK.getSound('invalid_move');
if (invalidSound) invalidSound.play();
}
});
}
}
function checkForMatches() {
if (isProcessingMatches) return;
var matchesFound = [];
var processedPositions = {}; // Track which positions we've already processed
// Find all matches by checking every position on the board
for (var y = 0; y < BOARD_SIZE; y++) {
for (var x = 0; x < BOARD_SIZE; x++) {
if (board[y][x] === -1) continue; // Skip empty cells
var positionKey = x + ',' + y;
if (processedPositions[positionKey]) continue; // Skip already processed positions
var gemType = board[y][x];
var foundMatches = [];
// Check horizontal matches starting from this position
var horizontalCount = 1;
var horizontalPositions = [{
x: x,
y: y
}];
// Check right
for (var i = x + 1; i < BOARD_SIZE && board[y][i] === gemType; i++) {
horizontalCount++;
horizontalPositions.push({
x: i,
y: y
});
}
// Check left - this was missing in original logic
for (var i = x - 1; i >= 0 && board[y][i] === gemType; i--) {
horizontalCount++;
horizontalPositions.unshift({
x: i,
y: y
}); // Add to beginning
}
if (horizontalCount >= 3) {
foundMatches = foundMatches.concat(horizontalPositions);
}
// Check vertical matches starting from this position
var verticalCount = 1;
var verticalPositions = [{
x: x,
y: y
}];
// Check down
for (var i = y + 1; i < BOARD_SIZE && board[i][x] === gemType; i++) {
verticalCount++;
verticalPositions.push({
x: x,
y: i
});
}
// Check up - this was missing in original logic
for (var i = y - 1; i >= 0 && board[i][x] === gemType; i--) {
verticalCount++;
verticalPositions.unshift({
x: x,
y: i
}); // Add to beginning
}
if (verticalCount >= 3) {
// Merge with horizontal matches if they overlap, otherwise add separately
if (foundMatches.length > 0) {
// Check if vertical matches overlap with horizontal
var hasOverlap = false;
for (var v = 0; v < verticalPositions.length; v++) {
for (var h = 0; h < foundMatches.length; h++) {
if (verticalPositions[v].x === foundMatches[h].x && verticalPositions[v].y === foundMatches[h].y) {
hasOverlap = true;
break;
}
}
if (hasOverlap) break;
}
if (hasOverlap) {
// Merge unique vertical positions
for (var v = 0; v < verticalPositions.length; v++) {
var vPos = verticalPositions[v];
var alreadyExists = false;
for (var h = 0; h < foundMatches.length; h++) {
if (foundMatches[h].x === vPos.x && foundMatches[h].y === vPos.y) {
alreadyExists = true;
break;
}
}
if (!alreadyExists) {
foundMatches.push(vPos);
}
}
} else {
foundMatches = foundMatches.concat(verticalPositions);
}
} else {
foundMatches = verticalPositions;
}
}
// Add all found matches to the main list and mark positions as processed
for (var i = 0; i < foundMatches.length; i++) {
var match = foundMatches[i];
var alreadyFound = false;
for (var j = 0; j < matchesFound.length; j++) {
if (matchesFound[j].x === match.x && matchesFound[j].y === match.y) {
alreadyFound = true;
break;
}
}
if (!alreadyFound) {
matchesFound.push(match);
}
// Mark this position as processed
processedPositions[match.x + ',' + match.y] = true;
}
}
}
// Check for 2x2 square matches and add rows if found
for (var y = 0; y < BOARD_SIZE - 1; y++) {
for (var x = 0; x < BOARD_SIZE - 1; x++) {
var squareMatches = checkSquareMatch(x, y);
if (squareMatches.length === 4) {
// Check if any of these squares are already in our matches
var hasSquareMatch = false;
for (var i = 0; i < squareMatches.length; i++) {
for (var j = 0; j < matchesFound.length; j++) {
if (squareMatches[i].x === matchesFound[j].x && squareMatches[i].y === matchesFound[j].y) {
hasSquareMatch = true;
break;
}
}
if (hasSquareMatch) break;
}
if (hasSquareMatch) {
// Add entire rows for square matches
for (var rowY = y; rowY <= y + 1; rowY++) {
for (var rowX = 0; rowX < BOARD_SIZE; rowX++) {
var alreadyFound = false;
for (var j = 0; j < matchesFound.length; j++) {
if (matchesFound[j].x === rowX && matchesFound[j].y === rowY) {
alreadyFound = true;
break;
}
}
if (!alreadyFound) {
matchesFound.push({
x: rowX,
y: rowY
});
}
}
}
}
}
}
}
if (matchesFound.length > 0) {
isProcessingMatches = true;
removeMatches(matchesFound);
} else {
// No matches found, check if moves are depleted
if (movesRemaining <= 0) {
messageTxt.setText('NO MORE MOVES!');
LK.effects.flashScreen(0xFF0000, 1000); // Red flash for game over
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
}
}
function checkSquareMatch(x, y) {
if (x >= BOARD_SIZE - 1 || y >= BOARD_SIZE - 1) return [];
var gemType = board[y][x];
// Check if all 4 positions in 2x2 square have same gem type
if (board[y][x] === gemType && board[y][x + 1] === gemType && board[y + 1][x] === gemType && board[y + 1][x + 1] === gemType) {
return [{
x: x,
y: y
}, {
x: x + 1,
y: y
}, {
x: x,
y: y + 1
}, {
x: x + 1,
y: y + 1
}];
}
return [];
}
function getRowsToRemove(matches) {
var rowsToRemove = [];
// Check if any 2x2 square matches exist
for (var y = 0; y < BOARD_SIZE - 1; y++) {
for (var x = 0; x < BOARD_SIZE - 1; x++) {
var squareMatches = checkSquareMatch(x, y);
if (squareMatches.length === 4) {
// Check if this square is part of our current matches
var isPartOfMatches = false;
for (var i = 0; i < squareMatches.length; i++) {
for (var j = 0; j < matches.length; j++) {
if (squareMatches[i].x === matches[j].x && squareMatches[i].y === matches[j].y) {
isPartOfMatches = true;
break;
}
}
if (isPartOfMatches) break;
}
if (isPartOfMatches) {
// Add both rows to removal list
if (rowsToRemove.indexOf(y) === -1) rowsToRemove.push(y);
if (rowsToRemove.indexOf(y + 1) === -1) rowsToRemove.push(y + 1);
}
}
}
}
return rowsToRemove;
}
function getMatchesAt(x, y) {
if (board[y][x] === -1) return []; // Empty cell
var gemType = board[y][x];
var allMatches = [];
// Check horizontal matches
var horizontalMatches = [{
x: x,
y: y
}];
// Check left
for (var i = x - 1; i >= 0 && board[y][i] === gemType; i--) {
horizontalMatches.push({
x: i,
y: y
});
}
// Check right
for (var i = x + 1; i < BOARD_SIZE && board[y][i] === gemType; i++) {
horizontalMatches.push({
x: i,
y: y
});
}
if (horizontalMatches.length >= 3) {
for (var i = 0; i < horizontalMatches.length; i++) {
allMatches.push(horizontalMatches[i]);
}
}
// Check vertical matches
var verticalMatches = [{
x: x,
y: y
}];
// Check up
for (var i = y - 1; i >= 0 && board[i][x] === gemType; i--) {
verticalMatches.push({
x: x,
y: i
});
}
// Check down
for (var i = y + 1; i < BOARD_SIZE && board[i][x] === gemType; i++) {
verticalMatches.push({
x: x,
y: i
});
}
if (verticalMatches.length >= 3) {
// Add vertical matches, avoiding duplicates from horizontal
for (var i = 0; i < verticalMatches.length; i++) {
var vMatch = verticalMatches[i];
var alreadyExists = false;
for (var j = 0; j < allMatches.length; j++) {
if (allMatches[j].x === vMatch.x && allMatches[j].y === vMatch.y) {
alreadyExists = true;
break;
}
}
if (!alreadyExists) {
allMatches.push(vMatch);
}
}
}
return allMatches;
}
function removeMatches(matches) {
// Check for 2x2 square matches and get rows to clear
var rowsToRemove = getRowsToRemove(matches);
var totalGemsToRemove = matches.length;
// If we have a square match, add entire rows to removal
if (rowsToRemove.length > 0) {
var rowMatches = [];
for (var i = 0; i < rowsToRemove.length; i++) {
var rowY = rowsToRemove[i];
for (var x = 0; x < BOARD_SIZE; x++) {
rowMatches.push({
x: x,
y: rowY
});
}
}
// Combine with original matches, avoiding duplicates
for (var i = 0; i < rowMatches.length; i++) {
var rowMatch = rowMatches[i];
var alreadyExists = false;
for (var j = 0; j < matches.length; j++) {
if (matches[j].x === rowMatch.x && matches[j].y === rowMatch.y) {
alreadyExists = true;
break;
}
}
if (!alreadyExists) {
matches.push(rowMatch);
}
}
totalGemsToRemove = matches.length;
}
// Add score with celebration for big matches
score += matches.length * 10;
scoreTxt.setText('Score: ' + score);
// Kid-friendly encouraging messages based on match size and square detection
var encouragingMessages = ['Great job!', 'Awesome!', 'Fantastic!', 'Amazing!', 'Super cool!', 'You\'re doing great!', 'Keep going!', 'Brilliant!', 'Wonderful!'];
if (rowsToRemove.length > 0) {
messageTxt.setText('SQUARE POWER! ROW CLEARED!');
LK.effects.flashScreen(0x00FF00, 1000); // Bright green flash for square matches
if (volumeEnabled) {
var squareSound = LK.getSound('square_match');
if (squareSound) squareSound.play();
}
} else if (matches.length >= 6) {
messageTxt.setText('WOW! INCREDIBLE!');
LK.effects.flashScreen(0xFFD700, 800); // Extra long gold flash
if (volumeEnabled) {
var bigSound = LK.getSound('big_match');
if (bigSound) bigSound.play();
}
} else if (matches.length >= 5) {
messageTxt.setText('SUPER COMBO!');
LK.effects.flashScreen(0xFFD700, 500); // Gold flash for 5+ matches
if (volumeEnabled) {
var bigSound = LK.getSound('big_match');
if (bigSound) bigSound.play();
}
} else if (matches.length >= 4) {
messageTxt.setText('GREAT MATCH!');
LK.effects.flashScreen(0xFF69B4, 300); // Pink flash for 4+ matches
if (volumeEnabled) {
var bigSound = LK.getSound('big_match');
if (bigSound) bigSound.play();
}
} else {
var randomMessage = encouragingMessages[Math.floor(Math.random() * encouragingMessages.length)];
messageTxt.setText(randomMessage);
if (volumeEnabled) {
var matchSound = LK.getSound('match');
if (matchSound) matchSound.play();
}
}
// Update target display with progress
var progress = Math.min(score / targetScore, 1.0);
var progressPercent = Math.floor(progress * 100);
targetTxt.setText('Target: ' + targetScore + ' (' + progressPercent + '%)');
// Encouraging messages based on progress
if (progress >= 0.9) {
targetTxt.fill = 0xFF6347; // Orange - almost there!
} else if (progress >= 0.5) {
targetTxt.fill = 0xFFD700; // Gold - halfway there!
} else {
targetTxt.fill = 0x32CD32; // Green - keep going!
}
// Check if target is reached
if (score >= targetScore) {
messageTxt.setText('🎉 YOU DID IT! 🎉');
LK.effects.flashScreen(0x00FF00, 1000); // Bright green celebration
LK.showYouWin();
}
// Flash and remove matched gems with rainbow colors
var rainbowColors = [0xFF69B4, 0x00BFFF, 0x32CD32, 0xFFD700, 0xFF6347, 0x9370DB];
for (var i = 0; i < matches.length; i++) {
var match = matches[i];
var gem = gems[match.y][match.x];
if (gem) {
var flashColor = rainbowColors[i % rainbowColors.length];
LK.effects.flashObject(gem, flashColor, 300);
tween(gem, {
alpha: 0,
scaleX: 1.5,
// Make gems grow bigger before disappearing
scaleY: 1.5
}, {
duration: 300,
easing: tween.easeOut,
// Bouncy effect
onFinish: function onFinish() {
// Properly destroy the gem after animation
if (gem && gem.destroy) {
gem.destroy();
}
}
});
}
board[match.y][match.x] = -1; // Mark as empty
gems[match.y][match.x] = null; // Clear gem reference
}
// Wait for animation then drop gems
LK.setTimeout(function () {
dropGems();
}, 350);
}
function dropGems() {
var moved = false;
// Drop existing gems
for (var x = 0; x < BOARD_SIZE; x++) {
var writePos = BOARD_SIZE - 1;
for (var y = BOARD_SIZE - 1; y >= 0; y--) {
if (board[y][x] !== -1) {
if (y !== writePos) {
// Move gem down
board[writePos][x] = board[y][x];
gems[writePos][x] = gems[y][x];
gems[writePos][x].setGridPosition(x, writePos);
gems[writePos][x].animateToPosition(boardStartX + x * CELL_SIZE + CELL_SIZE / 2, boardStartY + writePos * CELL_SIZE + CELL_SIZE / 2, 200);
board[y][x] = -1;
gems[y][x] = null;
moved = true;
}
writePos--;
}
}
}
// Fill empty spaces with new gems - ensure we fill from top to bottom
for (var x = 0; x < BOARD_SIZE; x++) {
for (var y = 0; y < BOARD_SIZE; y++) {
if (board[y][x] === -1) {
var newType = Math.floor(Math.random() * 8);
var newGem = new Gem(newType);
newGem.setGridPosition(x, y);
newGem.y = boardStartY - (BOARD_SIZE - y) * CELL_SIZE + CELL_SIZE / 2; // Start above board
newGem.animateToPosition(boardStartX + x * CELL_SIZE + CELL_SIZE / 2, boardStartY + y * CELL_SIZE + CELL_SIZE / 2, 400);
board[y][x] = newType;
gems[y][x] = newGem;
game.addChild(newGem);
moved = true;
}
}
}
// Double check - ensure no empty spaces remain by creating additional gems if needed
for (var x = 0; x < BOARD_SIZE; x++) {
for (var y = 0; y < BOARD_SIZE; y++) {
if (!gems[y][x] || board[y][x] === -1) {
var newType = Math.floor(Math.random() * 8);
var newGem = new Gem(newType);
newGem.setGridPosition(x, y);
board[y][x] = newType;
gems[y][x] = newGem;
game.addChild(newGem);
moved = true;
}
}
}
if (moved) {
LK.setTimeout(function () {
isProcessingMatches = false;
checkForMatches(); // Check for cascade matches
}, 450);
} else {
isProcessingMatches = false;
}
}
game.down = function (x, y, obj) {
if (currentGameState === GAME_STATE_HOME) {
// Check if play button was clicked using coordinate bounds
if (playButton) {
var buttonLeft = playButton.x - playButton.width * playButton.scaleX / 2;
var buttonRight = playButton.x + playButton.width * playButton.scaleX / 2;
var buttonTop = playButton.y - playButton.height * playButton.scaleY / 2;
var buttonBottom = playButton.y + playButton.height * playButton.scaleY / 2;
if (x >= buttonLeft && x <= buttonRight && y >= buttonTop && y <= buttonBottom) {
// Add click effect to play button
tween(playButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(playButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
if (volumeEnabled) LK.getSound('button_click').play();
startGame();
}
});
}
});
}
// Check if text input field was clicked
if (textInputField) {
var fieldLeft = textInputField.x - textInputField.width / 2;
var fieldRight = textInputField.x + textInputField.width / 2;
var fieldTop = textInputField.y - textInputField.height / 2;
var fieldBottom = textInputField.y + textInputField.height / 2;
if (x >= fieldLeft && x <= fieldRight && y >= fieldTop && y <= fieldBottom) {
// Set active field to name
activeInputField = 'name';
// Show custom keyboard
if (volumeEnabled) LK.getSound('button_click').play();
// Add visual feedback
tween(textInputField, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(textInputField, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
createCustomKeyboard();
}
});
}
});
return;
}
// Check if password input field was clicked
if (passwordInputField) {
var fieldLeft = passwordInputField.x - passwordInputField.width / 2;
var fieldRight = passwordInputField.x + passwordInputField.width / 2;
var fieldTop = passwordInputField.y - passwordInputField.height / 2;
var fieldBottom = passwordInputField.y + passwordInputField.height / 2;
if (x >= fieldLeft && x <= fieldRight && y >= fieldTop && y <= fieldBottom) {
// Set active field to password
activeInputField = 'password';
// Show custom keyboard
if (volumeEnabled) LK.getSound('button_click').play();
// Add visual feedback
tween(passwordInputField, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(passwordInputField, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
createCustomKeyboard();
}
});
}
});
return;
}
}
// Check if create account button was clicked
if (createAccountButton) {
var buttonLeft = createAccountButton.x - createAccountButton.width / 2;
var buttonRight = createAccountButton.x + createAccountButton.width / 2;
var buttonTop = createAccountButton.y - createAccountButton.height / 2;
var buttonBottom = createAccountButton.y + createAccountButton.height / 2;
if (x >= buttonLeft && x <= buttonRight && y >= buttonTop && y <= buttonBottom) {
// Add click effect to create account button
tween(createAccountButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(createAccountButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
if (volumeEnabled) LK.getSound('button_click').play();
// Handle account creation logic
if (inputText.trim().length === 0 || passwordText.trim().length === 0) {
// Show error message for empty fields
console.log('Please enter both name and password');
return;
}
// Save account data to storage
var accountData = {
username: inputText.trim(),
password: passwordText.trim(),
dateCreated: new Date().toISOString(),
highScore: 0
};
// Save to storage with username as key
storage['account_' + inputText.trim()] = accountData;
storage.currentUser = inputText.trim();
console.log('Account created successfully for:', inputText);
// Clear input fields after successful creation
inputText = '';
passwordText = '';
// Update display
if (textInputText) {
textInputText.setText('Enter your name...');
textInputText.fill = 0x888888;
}
if (passwordInputText) {
passwordInputText.setText('Enter password...');
passwordInputText.fill = 0x888888;
}
// Start the game automatically after account creation
startGame();
}
});
}
});
}
}
// Handle keyboard clicks
if (keyboardVisible && keyboardContainer) {
for (var i = 0; i < keyboardKeys.length; i++) {
var keyData = keyboardKeys[i];
var keyLeft = keyData.x - keyData.width / 2;
var keyRight = keyData.x + keyData.width / 2;
var keyTop = keyData.y - keyData.height / 2;
var keyBottom = keyData.y + keyData.height / 2;
if (x >= keyLeft && x <= keyRight && y >= keyTop && y <= keyBottom) {
// Key pressed - add visual feedback
if (volumeEnabled) LK.getSound('button_click').play();
var originalKey = keyData.key;
tween(originalKey, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(originalKey, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
}
});
handleKeyboardInput(keyData.letter);
return;
}
}
}
}
}
return;
}
if (currentGameState === GAME_STATE_PAUSED) {
// Handle pause menu clicks
if (resumeButton) {
var buttonLeft = resumeButton.x - resumeButton.width / 2;
var buttonRight = resumeButton.x + resumeButton.width / 2;
var buttonTop = resumeButton.y - resumeButton.height / 2;
var buttonBottom = resumeButton.y + resumeButton.height / 2;
if (x >= buttonLeft && x <= buttonRight && y >= buttonTop && y <= buttonBottom) {
// Resume game
if (volumeEnabled) LK.getSound('button_click').play();
currentGameState = GAME_STATE_PLAYING;
pauseMenuContainer.destroy();
pauseMenuContainer = null;
return;
}
}
if (volumeButton) {
var buttonLeft = volumeButton.x - volumeButton.width / 2;
var buttonRight = volumeButton.x + volumeButton.width / 2;
var buttonTop = volumeButton.y - volumeButton.height / 2;
var buttonBottom = volumeButton.y + volumeButton.height / 2;
if (x >= buttonLeft && x <= buttonRight && y >= buttonTop && y <= buttonBottom) {
// Toggle volume
if (volumeEnabled) LK.getSound('button_click').play();
volumeEnabled = !volumeEnabled;
storage.volumeEnabled = volumeEnabled;
pauseMenuContainer.volumeText.setText(volumeEnabled ? 'VOLUME: ON' : 'VOLUME: OFF');
return;
}
}
if (exitButton) {
var buttonLeft = exitButton.x - exitButton.width / 2;
var buttonRight = exitButton.x + exitButton.width / 2;
var buttonTop = exitButton.y - exitButton.height / 2;
var buttonBottom = exitButton.y + exitButton.height / 2;
if (x >= buttonLeft && x <= buttonRight && y >= buttonTop && y <= buttonBottom) {
// Exit to home screen
if (volumeEnabled) LK.getSound('button_click').play();
currentGameState = GAME_STATE_HOME;
// Clear all game elements
game.removeChildren();
// Reset UI elements
LK.gui.top.removeChildren();
scoreTxt = null;
targetTxt = null;
messageTxt = null;
movesTxt = null;
pauseButton = null;
pauseMenuContainer = null;
// Reset game variables
board = [];
gems = [];
selectedGem = null;
isProcessingMatches = false;
isDragging = false;
score = 0;
// Reset input fields
inputText = '';
passwordText = '';
// Show home screen
createHomeScreen();
return;
}
}
return;
}
if (currentGameState !== GAME_STATE_PLAYING || isProcessingMatches) return;
// Check if pause button was clicked
if (pauseButton) {
var buttonLeft = pauseButton.x - pauseButton.width / 2;
var buttonRight = pauseButton.x + pauseButton.width / 2;
var buttonTop = pauseButton.y - pauseButton.height / 2;
var buttonBottom = pauseButton.y + pauseButton.height / 2;
if (x >= buttonLeft && x <= buttonRight && y >= buttonTop && y <= buttonBottom) {
// Add click effect to pause button
tween(pauseButton, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(pauseButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
// Show pause menu
if (volumeEnabled) LK.getSound('button_click').play();
currentGameState = GAME_STATE_PAUSED;
createPauseMenu();
}
});
}
});
return;
}
}
selectedGem = getGemAt(x, y);
if (selectedGem) {
if (volumeEnabled) {
var selectSound = LK.getSound('select');
if (selectSound) selectSound.play();
}
isDragging = true;
dragStartX = x;
dragStartY = y;
// Fun rainbow flash and bigger bounce effect for kids
var rainbowColors = [0xFF69B4, 0x00BFFF, 0x32CD32, 0xFFD700, 0xFF6347, 0x9370DB];
var randomColor = rainbowColors[Math.floor(Math.random() * rainbowColors.length)];
LK.effects.flashObject(selectedGem, randomColor, 300);
// Store reference to selected gem for use in callbacks
var gemToAnimate = selectedGem;
// Check if gem exists and has valid properties before starting tween, and prevent multiple scale animations
if (gemToAnimate && gemToAnimate.scaleX !== undefined && gemToAnimate.scaleY !== undefined && !gemToAnimate.isScaling) {
// Stop any existing scale tweens on this gem
tween.stop(gemToAnimate, {
scaleX: true,
scaleY: true
});
// Mark gem as scaling to prevent multiple simultaneous animations
gemToAnimate.isScaling = true;
// Store original scale values
var originalScaleX = CELL_SIZE / 256;
var originalScaleY = CELL_SIZE / 256;
tween(gemToAnimate, {
scaleX: originalScaleX * 1.4,
// Bigger bounce for kids
scaleY: originalScaleY * 1.4
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Check if gem still exists and has valid properties before animating back
if (gemToAnimate && gemToAnimate.scaleX !== undefined && gemToAnimate.scaleY !== undefined) {
tween(gemToAnimate, {
scaleX: originalScaleX,
scaleY: originalScaleY
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
// Reset scaling flag when animation is complete
if (gemToAnimate) {
gemToAnimate.isScaling = false;
}
}
});
} else {
// Reset scaling flag even if gem no longer exists
if (gemToAnimate) {
gemToAnimate.isScaling = false;
}
}
}
});
}
}
};
game.move = function (x, y, obj) {
if (currentGameState !== GAME_STATE_PLAYING || !isDragging || !selectedGem || isProcessingMatches) return;
var deltaX = x - dragStartX;
var deltaY = y - dragStartY;
var threshold = CELL_SIZE / 2;
if (Math.abs(deltaX) > threshold || Math.abs(deltaY) > threshold) {
var targetGem = null;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// Horizontal swipe
if (deltaX > 0 && selectedGem.gridX < BOARD_SIZE - 1) {
targetGem = gems[selectedGem.gridY][selectedGem.gridX + 1];
} else if (deltaX < 0 && selectedGem.gridX > 0) {
targetGem = gems[selectedGem.gridY][selectedGem.gridX - 1];
}
} else {
// Vertical swipe
if (deltaY > 0 && selectedGem.gridY < BOARD_SIZE - 1) {
targetGem = gems[selectedGem.gridY + 1][selectedGem.gridX];
} else if (deltaY < 0 && selectedGem.gridY > 0) {
targetGem = gems[selectedGem.gridY - 1][selectedGem.gridX];
}
}
if (targetGem) {
swapGems(selectedGem, targetGem);
}
isDragging = false;
selectedGem = null;
}
};
game.up = function (x, y, obj) {
if (currentGameState !== GAME_STATE_PLAYING) return;
isDragging = false;
selectedGem = null;
};
// Game update loop for hint system
game.update = function () {
if (currentGameState === GAME_STATE_PLAYING && !isProcessingMatches) {
// Check if 5 seconds (300 ticks at 60fps) have passed since last move
var timeSinceLastMove = LK.ticks - lastMoveTime;
if (timeSinceLastMove >= 300 && hintAnimations.length === 0) {
// Show hint after 5 seconds of inactivity
showHint();
}
}
};
// Initialize home screen
createHomeScreen(); ===================================================================
--- original.js
+++ change.js
@@ -1471,10 +1471,39 @@
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
if (volumeEnabled) LK.getSound('button_click').play();
- // Here you would handle account creation logic
- console.log('Create account clicked with name:', inputText, 'and password:', passwordText);
+ // Handle account creation logic
+ if (inputText.trim().length === 0 || passwordText.trim().length === 0) {
+ // Show error message for empty fields
+ console.log('Please enter both name and password');
+ return;
+ }
+ // Save account data to storage
+ var accountData = {
+ username: inputText.trim(),
+ password: passwordText.trim(),
+ dateCreated: new Date().toISOString(),
+ highScore: 0
+ };
+ // Save to storage with username as key
+ storage['account_' + inputText.trim()] = accountData;
+ storage.currentUser = inputText.trim();
+ console.log('Account created successfully for:', inputText);
+ // Clear input fields after successful creation
+ inputText = '';
+ passwordText = '';
+ // Update display
+ if (textInputText) {
+ textInputText.setText('Enter your name...');
+ textInputText.fill = 0x888888;
+ }
+ if (passwordInputText) {
+ passwordInputText.setText('Enter password...');
+ passwordInputText.fill = 0x888888;
+ }
+ // Start the game automatically after account creation
+ startGame();
}
});
}
});
make a orange gem realistic. In-Game asset. 2d. High contrast. No shadows
a purple gem not a diamond realistic. In-Game asset. 2d. High contrast. No shadows
a red gem realistic. In-Game asset. 2d. High contrast. No shadows
a yellow gem found from the caves of colorado make it realistic. In-Game asset. 2d. High contrast. No shadows
a cyan realistic gem. In-Game asset. 2d. High contrast. No shadows
a pink gem realistic. In-Game asset. 2d. High contrast. No shadows
a very modern pause button. In-Game asset. 2d. High contrast. No shadows
a fun play button that says play on it super modern and kid friendly. In-Game asset. 2d. High contrast. No shadows
a create account button for signing up in a game supa kid friendly and modern. In-Game asset. 2d. High contrast. No shadows