/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var GridCell = Container.expand(function (letter, row, col) { var self = Container.call(this); self.row = row; self.col = col; self.letter = letter; self.isFound = false; self.isSelected = false; var background = self.attachAsset('gridCell', { anchorX: 0.5, anchorY: 0.5 }); var selectedBg = self.attachAsset('selectedCell', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); var foundBg = self.attachAsset('foundCell', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); var letterText = new Text2(letter, { size: 85, fill: 0x000000, letterSpacing: 3 }); letterText.anchor.set(0.5, 0.5); self.addChild(letterText); self.setSelected = function (selected) { self.isSelected = selected; selectedBg.alpha = selected ? 1 : 0; }; self.setFound = function () { self.isFound = true; foundBg.alpha = 1; selectedBg.alpha = 0; letterText.tint = 0xffffff; }; return self; }); var HighScorePopup = Container.expand(function () { var self = Container.call(this); // Background overlay var overlay = LK.getAsset('gridCell', { width: 2048, height: 2732, anchorX: 0, anchorY: 0, alpha: 0.8 }); overlay.tint = 0x000000; self.addChild(overlay); // Popup background var popup = LK.getAsset('gridCell', { width: 1200, height: 1500, anchorX: 0.5, anchorY: 0.5 }); popup.x = 2048 / 2; popup.y = 2732 / 2; popup.tint = 0xffffff; self.addChild(popup); // Title var titleText = new Text2('HIGH SCORES', { size: 100, fill: 0x2196F3, letterSpacing: 5 }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 2732 / 2 - 600; self.addChild(titleText); // Get high scores from storage var highScores = storage.highScores || []; // Display scores for (var i = 0; i < Math.min(10, highScores.length); i++) { var scoreText = new Text2(i + 1 + '. ' + highScores[i], { size: 60, fill: 0x333333, letterSpacing: 2 }); scoreText.anchor.set(0.5, 0.5); scoreText.x = 2048 / 2; scoreText.y = 2732 / 2 - 400 + i * 80; self.addChild(scoreText); } // Close button var closeButton = LK.getAsset('selectedCell', { width: 200, height: 80, anchorX: 0.5, anchorY: 0.5 }); closeButton.x = 2048 / 2; closeButton.y = 2732 / 2 + 500; self.addChild(closeButton); var closeText = new Text2('CLOSE', { size: 50, fill: 0xffffff, letterSpacing: 2 }); closeText.anchor.set(0.5, 0.5); closeText.x = 2048 / 2; closeText.y = 2732 / 2 + 500; self.addChild(closeText); // Close functionality closeButton.down = function () { self.destroy(); }; overlay.down = function () { self.destroy(); }; return self; }); var NicknameScreen = Container.expand(function () { var self = Container.call(this); // Background overlay var overlay = LK.getAsset('gridCell', { width: 2048, height: 2732, anchorX: 0, anchorY: 0, alpha: 0.9 }); overlay.tint = 0x2196F3; self.addChild(overlay); // Title var titleText = new Text2('WORD QUEST', { size: 150, fill: 0xffffff, letterSpacing: 8 }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 600; self.addChild(titleText); // Subtitle var subtitleText = new Text2('Enter Your Nickname', { size: 80, fill: 0xffffff, letterSpacing: 3 }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 2048 / 2; subtitleText.y = 800; self.addChild(subtitleText); // Input background var inputBg = LK.getAsset('gridCell', { width: 800, height: 120, anchorX: 0.5, anchorY: 0.5 }); inputBg.x = 2048 / 2; inputBg.y = 1000; inputBg.tint = 0xffffff; self.addChild(inputBg); // Current nickname display var currentNickname = storage.nickname || ''; var nicknameText = new Text2(currentNickname, { size: 70, fill: 0x333333, letterSpacing: 2 }); nicknameText.anchor.set(0.5, 0.5); nicknameText.x = 2048 / 2; nicknameText.y = 1000; self.addChild(nicknameText); // Virtual keyboard letters var keyboard = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var keysPerRow = 7; var keyWidth = 100; var keyHeight = 100; var keySpacing = 20; var totalRows = Math.ceil(keyboard.length / keysPerRow); var startY = 1200; var keyButtons = []; for (var i = 0; i < keyboard.length; i++) { var row = Math.floor(i / keysPerRow); var col = i % keysPerRow; var keysInThisRow = Math.min(keysPerRow, keyboard.length - row * keysPerRow); var totalRowWidth = keysInThisRow * keyWidth + (keysInThisRow - 1) * keySpacing; var startX = 2048 / 2 - totalRowWidth / 2; var keyButton = LK.getAsset('selectedCell', { width: keyWidth, height: keyHeight, anchorX: 0.5, anchorY: 0.5 }); keyButton.x = startX + col * (keyWidth + keySpacing) + keyWidth / 2; keyButton.y = startY + row * (keyHeight + keySpacing); keyButton.letter = keyboard[i]; self.addChild(keyButton); var keyText = new Text2(keyboard[i], { size: 50, fill: 0xffffff, letterSpacing: 1 }); keyText.anchor.set(0.5, 0.5); keyText.x = keyButton.x; keyText.y = keyButton.y; self.addChild(keyText); keyButton.down = function () { if (currentNickname.length < 12) { currentNickname += this.letter; nicknameText.setText(currentNickname); } }; keyButtons.push(keyButton); } // Backspace button var backspaceButton = LK.getAsset('foundCell', { width: 200, height: 80, anchorX: 0.5, anchorY: 0.5 }); backspaceButton.x = 2048 / 2 - 150; backspaceButton.y = startY + totalRows * (keyHeight + keySpacing) + 100; self.addChild(backspaceButton); var backspaceText = new Text2('DELETE', { size: 40, fill: 0xffffff, letterSpacing: 1 }); backspaceText.anchor.set(0.5, 0.5); backspaceText.x = backspaceButton.x; backspaceText.y = backspaceButton.y; self.addChild(backspaceText); backspaceButton.down = function () { if (currentNickname.length > 0) { currentNickname = currentNickname.slice(0, -1); nicknameText.setText(currentNickname); } }; // Start game button var startButton = LK.getAsset('selectedCell', { width: 200, height: 80, anchorX: 0.5, anchorY: 0.5 }); startButton.x = 2048 / 2 + 150; startButton.y = startY + totalRows * (keyHeight + keySpacing) + 100; self.addChild(startButton); var startText = new Text2('START', { size: 40, fill: 0xffffff, letterSpacing: 1 }); startText.anchor.set(0.5, 0.5); startText.x = startButton.x; startText.y = startButton.y; self.addChild(startText); startButton.down = function () { if (currentNickname.length > 0) { storage.nickname = currentNickname; self.destroy(); startGame(); } }; return self; }); var WordListItem = Container.expand(function (word, index) { var self = Container.call(this); self.word = word; self.found = false; var wordText = new Text2(word.toUpperCase(), { size: 87, fill: 0x333333, letterSpacing: 3 }); wordText.anchor.set(0, 0.5); self.addChild(wordText); var strikethrough = LK.getAsset('foundCell', { width: wordText.width + 20, height: 4, anchorX: 0, anchorY: 0.5, alpha: 0 }); strikethrough.x = -10; self.addChild(strikethrough); self.markFound = function () { self.found = true; wordText.tint = 0x888888; strikethrough.alpha = 1; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf5f5f5 }); /**** * Game Code ****/ var GRID_SIZE = 9; var CELL_SIZE = 80; var CELL_SPACING = 25; var TOTAL_GRID_WIDTH = GRID_SIZE * CELL_SIZE + (GRID_SIZE - 1) * CELL_SPACING; var GRID_START_X = 2048 / 2 - TOTAL_GRID_WIDTH / 2; var GRID_START_Y = 2732 / 2 - (GRID_SIZE * CELL_SIZE + (GRID_SIZE - 1) * CELL_SPACING) / 2; var words = [{ word: 'CAT', level: 'A1' }, { word: 'DOG', level: 'A2' }, { word: 'BIRD', level: 'B1' }, { word: 'FISH', level: 'B1+' }, { word: 'TREE', level: 'B2' }, { word: 'BOOK', level: 'C1' }]; var grid = []; var gridCells = []; var wordList = []; var selectedCells = []; var isDragging = false; var foundWords = []; var scoreText = null; // Generate random letter function getRandomLetter() { return String.fromCharCode(65 + Math.floor(Math.random() * 26)); } // Create empty grid function createGrid() { for (var i = 0; i < GRID_SIZE; i++) { grid[i] = []; gridCells[i] = []; for (var j = 0; j < GRID_SIZE; j++) { grid[i][j] = null; // Start with empty cells } } } // Place word in grid function placeWord(word, row, col, direction) { var directions = { horizontal: [0, 1], vertical: [1, 0], diagonal1: [1, 1], diagonal2: [1, -1], horizontal_r: [0, -1], vertical_r: [-1, 0], diagonal1_r: [-1, -1], diagonal2_r: [-1, 1] }; var dir = directions[direction]; for (var i = 0; i < word.length; i++) { var newRow = row + dir[0] * i; var newCol = col + dir[1] * i; if (newRow >= 0 && newRow < GRID_SIZE && newCol >= 0 && newCol < GRID_SIZE) { grid[newRow][newCol] = word[i]; } } } // Check if word can be placed function canPlaceWord(word, row, col, direction) { var directions = { horizontal: [0, 1], vertical: [1, 0], diagonal1: [1, 1], diagonal2: [1, -1], horizontal_r: [0, -1], vertical_r: [-1, 0], diagonal1_r: [-1, -1], diagonal2_r: [-1, 1] }; var dir = directions[direction]; for (var i = 0; i < word.length; i++) { var newRow = row + dir[0] * i; var newCol = col + dir[1] * i; if (newRow < 0 || newRow >= GRID_SIZE || newCol < 0 || newCol >= GRID_SIZE) { return false; } // Check if the position is already occupied by a different letter var existingLetter = grid[newRow][newCol]; if (existingLetter && existingLetter !== word[i]) { return false; } } return true; } // Place all words in grid function placeWords() { var directions = ['horizontal', 'vertical', 'diagonal1', 'diagonal2', 'horizontal_r', 'vertical_r', 'diagonal1_r', 'diagonal2_r']; for (var w = 0; w < words.length; w++) { var wordObj = words[w]; var word = wordObj.word; var placed = false; var attempts = 0; while (!placed && attempts < 1000) { var row = Math.floor(Math.random() * GRID_SIZE); var col = Math.floor(Math.random() * GRID_SIZE); var direction = directions[Math.floor(Math.random() * directions.length)]; if (canPlaceWord(word, row, col, direction)) { placeWord(word, row, col, direction); placed = true; } attempts++; } if (!placed) { console.log("Failed to place word: " + word); } } } // Create visual grid function createVisualGrid() { for (var i = 0; i < GRID_SIZE; i++) { for (var j = 0; j < GRID_SIZE; j++) { var cell = new GridCell(grid[i][j], i, j); cell.x = GRID_START_X + j * (CELL_SIZE + CELL_SPACING); cell.y = GRID_START_Y + i * (CELL_SIZE + CELL_SPACING); gridCells[i][j] = cell; game.addChild(cell); } } } // Create word list function createWordList() { var wordsPerRow = 2; var wordWidth = 450; var wordHeight = 120; var horizontalSpacing = 120; var verticalSpacing = 80; var totalRows = Math.ceil(words.length / wordsPerRow); var totalWidth = wordsPerRow * wordWidth + (wordsPerRow - 1) * horizontalSpacing; var totalHeight = totalRows * wordHeight + (totalRows - 1) * verticalSpacing; var startX = 2048 / 2 - totalWidth / 2; var startY = 2732 - totalHeight - 200; for (var i = 0; i < words.length; i++) { var wordObj = words[i]; var displayText = wordObj.level + ': ' + wordObj.word; var wordItem = new WordListItem(displayText, i); wordItem.actualWord = wordObj.word; var row = Math.floor(i / wordsPerRow); var col = i % wordsPerRow; wordItem.x = startX + col * (wordWidth + horizontalSpacing); wordItem.y = startY + row * (wordHeight + verticalSpacing); wordList.push(wordItem); game.addChild(wordItem); } } // Get cell at position function getCellAtPosition(x, y) { // Check if gridCells is properly initialized if (!gridCells || gridCells.length === 0) { return null; } for (var i = 0; i < GRID_SIZE; i++) { if (!gridCells[i]) { continue; } for (var j = 0; j < GRID_SIZE; j++) { var cell = gridCells[i][j]; var bounds = { left: cell.x - CELL_SIZE / 2, right: cell.x + CELL_SIZE / 2, top: cell.y - CELL_SIZE / 2, bottom: cell.y + CELL_SIZE / 2 }; if (x >= bounds.left && x <= bounds.right && y >= bounds.top && y <= bounds.bottom) { return cell; } } } return null; } // Clear selection function clearSelection() { for (var i = 0; i < selectedCells.length; i++) { if (!selectedCells[i].isFound) { selectedCells[i].setSelected(false); } } selectedCells = []; } // Get selected word function getSelectedWord() { var word = ""; for (var i = 0; i < selectedCells.length; i++) { word += selectedCells[i].letter; } return word; } // Check if word is valid function isValidWord(word) { for (var i = 0; i < words.length; i++) { if (words[i].word === word && foundWords.indexOf(word) === -1) { return true; } } return false; } // Mark word as found function markWordFound(word) { foundWords.push(word); // Mark cells as found for (var i = 0; i < selectedCells.length; i++) { selectedCells[i].setFound(); } // Mark word in list as found for (var i = 0; i < wordList.length; i++) { if (wordList[i].actualWord === word) { wordList[i].markFound(); break; } } LK.getSound('wordFound').play(); LK.setScore(LK.getScore() + word.length * 10); // Check win condition if (foundWords.length === words.length) { // Save high score var currentScore = LK.getScore(); var highScores = storage.highScores || []; // Add current score and sort highScores.push(currentScore); highScores.sort(function (a, b) { return b - a; }); // Keep only top 10 scores if (highScores.length > 10) { highScores = highScores.slice(0, 10); } // Save back to storage storage.highScores = highScores; LK.setTimeout(function () { LK.showYouWin(); }, 1000); } } // Check if cells form a line function isValidSelection(cells) { if (cells.length < 2) return true; var deltaRow = cells[1].row - cells[0].row; var deltaCol = cells[1].col - cells[0].col; // Normalize direction if (deltaRow !== 0) deltaRow = deltaRow > 0 ? 1 : -1; if (deltaCol !== 0) deltaCol = deltaCol > 0 ? 1 : -1; for (var i = 2; i < cells.length; i++) { var currentDeltaRow = cells[i].row - cells[i - 1].row; var currentDeltaCol = cells[i].col - cells[i - 1].col; if (currentDeltaRow !== 0) currentDeltaRow = currentDeltaRow > 0 ? 1 : -1; if (currentDeltaCol !== 0) currentDeltaCol = currentDeltaCol > 0 ? 1 : -1; if (currentDeltaRow !== deltaRow || currentDeltaCol !== deltaCol) { return false; } } return true; } // Fill empty cells with random letters function fillEmptyCells() { for (var i = 0; i < GRID_SIZE; i++) { for (var j = 0; j < GRID_SIZE; j++) { if (grid[i][j] === null) { grid[i][j] = getRandomLetter(); } } } } // Start game function function startGame() { // Initialize game createGrid(); placeWords(); fillEmptyCells(); createVisualGrid(); createWordList(); // Create title var titleText = new Text2('WORD QUEST', { size: 142, fill: 0x2196F3, letterSpacing: 8 }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 150; game.addChild(titleText); // Create score display scoreText = new Text2('Score: 0', { size: 87, fill: 0x333333, letterSpacing: 2 }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); scoreText.y = 200; // Create high score button var highScoreButton = LK.getAsset('selectedCell', { width: 300, height: 80, anchorX: 0.5, anchorY: 0.5 }); highScoreButton.x = 2048 - 200; highScoreButton.y = 150; game.addChild(highScoreButton); var highScoreButtonText = new Text2('HIGH SCORES', { size: 40, fill: 0xffffff, letterSpacing: 2 }); highScoreButtonText.anchor.set(0.5, 0.5); highScoreButtonText.x = 2048 - 200; highScoreButtonText.y = 150; game.addChild(highScoreButtonText); // High score button functionality highScoreButton.down = function () { var popup = new HighScorePopup(); game.addChild(popup); // Animate popup appearance popup.alpha = 0; popup.scaleX = 0.5; popup.scaleY = 0.5; tween(popup, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); }; } // Show nickname screen on game start var nicknameScreen = new NicknameScreen(); game.addChild(nicknameScreen); game.down = function (x, y, obj) { // Create 4 sliding boxes from the selected point for (var i = 0; i < 4; i++) { var box = LK.getAsset('selectedCell', { anchorX: 0.5, anchorY: 0.5, x: x, y: y, scaleX: 0.5, scaleY: 0.5 }); game.addChild(box); // Define slide directions (up, down, left, right) var directions = [{ x: 0, y: -200 }, // up { x: 0, y: 200 }, // down { x: -200, y: 0 }, // left { x: 200, y: 0 } // right ]; var targetX = x + directions[i].x; var targetY = y + directions[i].y; // Animate box sliding out and fading tween(box, { x: targetX, y: targetY, alpha: 0 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { box.destroy(); } }); } var cell = getCellAtPosition(x, y); if (cell && !cell.isFound) { isDragging = true; clearSelection(); selectedCells.push(cell); cell.setSelected(true); LK.getSound('selectLetter').play(); } }; game.move = function (x, y, obj) { if (isDragging) { var cell = getCellAtPosition(x, y); if (cell && !cell.isFound && selectedCells.indexOf(cell) === -1) { var tempSelection = selectedCells.slice(); tempSelection.push(cell); if (isValidSelection(tempSelection)) { selectedCells.push(cell); cell.setSelected(true); LK.getSound('selectLetter').play(); } } } }; game.up = function (x, y, obj) { if (isDragging) { isDragging = false; if (selectedCells.length > 1) { var selectedWord = getSelectedWord(); var reverseWord = selectedWord.split('').reverse().join(''); if (isValidWord(selectedWord)) { markWordFound(selectedWord); } else if (isValidWord(reverseWord)) { markWordFound(reverseWord); } else { clearSelection(); } } else { clearSelection(); } } }; game.update = function () { if (scoreText) { scoreText.setText('Score: ' + LK.getScore()); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var GridCell = Container.expand(function (letter, row, col) {
var self = Container.call(this);
self.row = row;
self.col = col;
self.letter = letter;
self.isFound = false;
self.isSelected = false;
var background = self.attachAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5
});
var selectedBg = self.attachAsset('selectedCell', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
var foundBg = self.attachAsset('foundCell', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
var letterText = new Text2(letter, {
size: 85,
fill: 0x000000,
letterSpacing: 3
});
letterText.anchor.set(0.5, 0.5);
self.addChild(letterText);
self.setSelected = function (selected) {
self.isSelected = selected;
selectedBg.alpha = selected ? 1 : 0;
};
self.setFound = function () {
self.isFound = true;
foundBg.alpha = 1;
selectedBg.alpha = 0;
letterText.tint = 0xffffff;
};
return self;
});
var HighScorePopup = Container.expand(function () {
var self = Container.call(this);
// Background overlay
var overlay = LK.getAsset('gridCell', {
width: 2048,
height: 2732,
anchorX: 0,
anchorY: 0,
alpha: 0.8
});
overlay.tint = 0x000000;
self.addChild(overlay);
// Popup background
var popup = LK.getAsset('gridCell', {
width: 1200,
height: 1500,
anchorX: 0.5,
anchorY: 0.5
});
popup.x = 2048 / 2;
popup.y = 2732 / 2;
popup.tint = 0xffffff;
self.addChild(popup);
// Title
var titleText = new Text2('HIGH SCORES', {
size: 100,
fill: 0x2196F3,
letterSpacing: 5
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 2732 / 2 - 600;
self.addChild(titleText);
// Get high scores from storage
var highScores = storage.highScores || [];
// Display scores
for (var i = 0; i < Math.min(10, highScores.length); i++) {
var scoreText = new Text2(i + 1 + '. ' + highScores[i], {
size: 60,
fill: 0x333333,
letterSpacing: 2
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 2048 / 2;
scoreText.y = 2732 / 2 - 400 + i * 80;
self.addChild(scoreText);
}
// Close button
var closeButton = LK.getAsset('selectedCell', {
width: 200,
height: 80,
anchorX: 0.5,
anchorY: 0.5
});
closeButton.x = 2048 / 2;
closeButton.y = 2732 / 2 + 500;
self.addChild(closeButton);
var closeText = new Text2('CLOSE', {
size: 50,
fill: 0xffffff,
letterSpacing: 2
});
closeText.anchor.set(0.5, 0.5);
closeText.x = 2048 / 2;
closeText.y = 2732 / 2 + 500;
self.addChild(closeText);
// Close functionality
closeButton.down = function () {
self.destroy();
};
overlay.down = function () {
self.destroy();
};
return self;
});
var NicknameScreen = Container.expand(function () {
var self = Container.call(this);
// Background overlay
var overlay = LK.getAsset('gridCell', {
width: 2048,
height: 2732,
anchorX: 0,
anchorY: 0,
alpha: 0.9
});
overlay.tint = 0x2196F3;
self.addChild(overlay);
// Title
var titleText = new Text2('WORD QUEST', {
size: 150,
fill: 0xffffff,
letterSpacing: 8
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 600;
self.addChild(titleText);
// Subtitle
var subtitleText = new Text2('Enter Your Nickname', {
size: 80,
fill: 0xffffff,
letterSpacing: 3
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 2048 / 2;
subtitleText.y = 800;
self.addChild(subtitleText);
// Input background
var inputBg = LK.getAsset('gridCell', {
width: 800,
height: 120,
anchorX: 0.5,
anchorY: 0.5
});
inputBg.x = 2048 / 2;
inputBg.y = 1000;
inputBg.tint = 0xffffff;
self.addChild(inputBg);
// Current nickname display
var currentNickname = storage.nickname || '';
var nicknameText = new Text2(currentNickname, {
size: 70,
fill: 0x333333,
letterSpacing: 2
});
nicknameText.anchor.set(0.5, 0.5);
nicknameText.x = 2048 / 2;
nicknameText.y = 1000;
self.addChild(nicknameText);
// Virtual keyboard letters
var keyboard = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var keysPerRow = 7;
var keyWidth = 100;
var keyHeight = 100;
var keySpacing = 20;
var totalRows = Math.ceil(keyboard.length / keysPerRow);
var startY = 1200;
var keyButtons = [];
for (var i = 0; i < keyboard.length; i++) {
var row = Math.floor(i / keysPerRow);
var col = i % keysPerRow;
var keysInThisRow = Math.min(keysPerRow, keyboard.length - row * keysPerRow);
var totalRowWidth = keysInThisRow * keyWidth + (keysInThisRow - 1) * keySpacing;
var startX = 2048 / 2 - totalRowWidth / 2;
var keyButton = LK.getAsset('selectedCell', {
width: keyWidth,
height: keyHeight,
anchorX: 0.5,
anchorY: 0.5
});
keyButton.x = startX + col * (keyWidth + keySpacing) + keyWidth / 2;
keyButton.y = startY + row * (keyHeight + keySpacing);
keyButton.letter = keyboard[i];
self.addChild(keyButton);
var keyText = new Text2(keyboard[i], {
size: 50,
fill: 0xffffff,
letterSpacing: 1
});
keyText.anchor.set(0.5, 0.5);
keyText.x = keyButton.x;
keyText.y = keyButton.y;
self.addChild(keyText);
keyButton.down = function () {
if (currentNickname.length < 12) {
currentNickname += this.letter;
nicknameText.setText(currentNickname);
}
};
keyButtons.push(keyButton);
}
// Backspace button
var backspaceButton = LK.getAsset('foundCell', {
width: 200,
height: 80,
anchorX: 0.5,
anchorY: 0.5
});
backspaceButton.x = 2048 / 2 - 150;
backspaceButton.y = startY + totalRows * (keyHeight + keySpacing) + 100;
self.addChild(backspaceButton);
var backspaceText = new Text2('DELETE', {
size: 40,
fill: 0xffffff,
letterSpacing: 1
});
backspaceText.anchor.set(0.5, 0.5);
backspaceText.x = backspaceButton.x;
backspaceText.y = backspaceButton.y;
self.addChild(backspaceText);
backspaceButton.down = function () {
if (currentNickname.length > 0) {
currentNickname = currentNickname.slice(0, -1);
nicknameText.setText(currentNickname);
}
};
// Start game button
var startButton = LK.getAsset('selectedCell', {
width: 200,
height: 80,
anchorX: 0.5,
anchorY: 0.5
});
startButton.x = 2048 / 2 + 150;
startButton.y = startY + totalRows * (keyHeight + keySpacing) + 100;
self.addChild(startButton);
var startText = new Text2('START', {
size: 40,
fill: 0xffffff,
letterSpacing: 1
});
startText.anchor.set(0.5, 0.5);
startText.x = startButton.x;
startText.y = startButton.y;
self.addChild(startText);
startButton.down = function () {
if (currentNickname.length > 0) {
storage.nickname = currentNickname;
self.destroy();
startGame();
}
};
return self;
});
var WordListItem = Container.expand(function (word, index) {
var self = Container.call(this);
self.word = word;
self.found = false;
var wordText = new Text2(word.toUpperCase(), {
size: 87,
fill: 0x333333,
letterSpacing: 3
});
wordText.anchor.set(0, 0.5);
self.addChild(wordText);
var strikethrough = LK.getAsset('foundCell', {
width: wordText.width + 20,
height: 4,
anchorX: 0,
anchorY: 0.5,
alpha: 0
});
strikethrough.x = -10;
self.addChild(strikethrough);
self.markFound = function () {
self.found = true;
wordText.tint = 0x888888;
strikethrough.alpha = 1;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf5f5f5
});
/****
* Game Code
****/
var GRID_SIZE = 9;
var CELL_SIZE = 80;
var CELL_SPACING = 25;
var TOTAL_GRID_WIDTH = GRID_SIZE * CELL_SIZE + (GRID_SIZE - 1) * CELL_SPACING;
var GRID_START_X = 2048 / 2 - TOTAL_GRID_WIDTH / 2;
var GRID_START_Y = 2732 / 2 - (GRID_SIZE * CELL_SIZE + (GRID_SIZE - 1) * CELL_SPACING) / 2;
var words = [{
word: 'CAT',
level: 'A1'
}, {
word: 'DOG',
level: 'A2'
}, {
word: 'BIRD',
level: 'B1'
}, {
word: 'FISH',
level: 'B1+'
}, {
word: 'TREE',
level: 'B2'
}, {
word: 'BOOK',
level: 'C1'
}];
var grid = [];
var gridCells = [];
var wordList = [];
var selectedCells = [];
var isDragging = false;
var foundWords = [];
var scoreText = null;
// Generate random letter
function getRandomLetter() {
return String.fromCharCode(65 + Math.floor(Math.random() * 26));
}
// Create empty grid
function createGrid() {
for (var i = 0; i < GRID_SIZE; i++) {
grid[i] = [];
gridCells[i] = [];
for (var j = 0; j < GRID_SIZE; j++) {
grid[i][j] = null; // Start with empty cells
}
}
}
// Place word in grid
function placeWord(word, row, col, direction) {
var directions = {
horizontal: [0, 1],
vertical: [1, 0],
diagonal1: [1, 1],
diagonal2: [1, -1],
horizontal_r: [0, -1],
vertical_r: [-1, 0],
diagonal1_r: [-1, -1],
diagonal2_r: [-1, 1]
};
var dir = directions[direction];
for (var i = 0; i < word.length; i++) {
var newRow = row + dir[0] * i;
var newCol = col + dir[1] * i;
if (newRow >= 0 && newRow < GRID_SIZE && newCol >= 0 && newCol < GRID_SIZE) {
grid[newRow][newCol] = word[i];
}
}
}
// Check if word can be placed
function canPlaceWord(word, row, col, direction) {
var directions = {
horizontal: [0, 1],
vertical: [1, 0],
diagonal1: [1, 1],
diagonal2: [1, -1],
horizontal_r: [0, -1],
vertical_r: [-1, 0],
diagonal1_r: [-1, -1],
diagonal2_r: [-1, 1]
};
var dir = directions[direction];
for (var i = 0; i < word.length; i++) {
var newRow = row + dir[0] * i;
var newCol = col + dir[1] * i;
if (newRow < 0 || newRow >= GRID_SIZE || newCol < 0 || newCol >= GRID_SIZE) {
return false;
}
// Check if the position is already occupied by a different letter
var existingLetter = grid[newRow][newCol];
if (existingLetter && existingLetter !== word[i]) {
return false;
}
}
return true;
}
// Place all words in grid
function placeWords() {
var directions = ['horizontal', 'vertical', 'diagonal1', 'diagonal2', 'horizontal_r', 'vertical_r', 'diagonal1_r', 'diagonal2_r'];
for (var w = 0; w < words.length; w++) {
var wordObj = words[w];
var word = wordObj.word;
var placed = false;
var attempts = 0;
while (!placed && attempts < 1000) {
var row = Math.floor(Math.random() * GRID_SIZE);
var col = Math.floor(Math.random() * GRID_SIZE);
var direction = directions[Math.floor(Math.random() * directions.length)];
if (canPlaceWord(word, row, col, direction)) {
placeWord(word, row, col, direction);
placed = true;
}
attempts++;
}
if (!placed) {
console.log("Failed to place word: " + word);
}
}
}
// Create visual grid
function createVisualGrid() {
for (var i = 0; i < GRID_SIZE; i++) {
for (var j = 0; j < GRID_SIZE; j++) {
var cell = new GridCell(grid[i][j], i, j);
cell.x = GRID_START_X + j * (CELL_SIZE + CELL_SPACING);
cell.y = GRID_START_Y + i * (CELL_SIZE + CELL_SPACING);
gridCells[i][j] = cell;
game.addChild(cell);
}
}
}
// Create word list
function createWordList() {
var wordsPerRow = 2;
var wordWidth = 450;
var wordHeight = 120;
var horizontalSpacing = 120;
var verticalSpacing = 80;
var totalRows = Math.ceil(words.length / wordsPerRow);
var totalWidth = wordsPerRow * wordWidth + (wordsPerRow - 1) * horizontalSpacing;
var totalHeight = totalRows * wordHeight + (totalRows - 1) * verticalSpacing;
var startX = 2048 / 2 - totalWidth / 2;
var startY = 2732 - totalHeight - 200;
for (var i = 0; i < words.length; i++) {
var wordObj = words[i];
var displayText = wordObj.level + ': ' + wordObj.word;
var wordItem = new WordListItem(displayText, i);
wordItem.actualWord = wordObj.word;
var row = Math.floor(i / wordsPerRow);
var col = i % wordsPerRow;
wordItem.x = startX + col * (wordWidth + horizontalSpacing);
wordItem.y = startY + row * (wordHeight + verticalSpacing);
wordList.push(wordItem);
game.addChild(wordItem);
}
}
// Get cell at position
function getCellAtPosition(x, y) {
// Check if gridCells is properly initialized
if (!gridCells || gridCells.length === 0) {
return null;
}
for (var i = 0; i < GRID_SIZE; i++) {
if (!gridCells[i]) {
continue;
}
for (var j = 0; j < GRID_SIZE; j++) {
var cell = gridCells[i][j];
var bounds = {
left: cell.x - CELL_SIZE / 2,
right: cell.x + CELL_SIZE / 2,
top: cell.y - CELL_SIZE / 2,
bottom: cell.y + CELL_SIZE / 2
};
if (x >= bounds.left && x <= bounds.right && y >= bounds.top && y <= bounds.bottom) {
return cell;
}
}
}
return null;
}
// Clear selection
function clearSelection() {
for (var i = 0; i < selectedCells.length; i++) {
if (!selectedCells[i].isFound) {
selectedCells[i].setSelected(false);
}
}
selectedCells = [];
}
// Get selected word
function getSelectedWord() {
var word = "";
for (var i = 0; i < selectedCells.length; i++) {
word += selectedCells[i].letter;
}
return word;
}
// Check if word is valid
function isValidWord(word) {
for (var i = 0; i < words.length; i++) {
if (words[i].word === word && foundWords.indexOf(word) === -1) {
return true;
}
}
return false;
}
// Mark word as found
function markWordFound(word) {
foundWords.push(word);
// Mark cells as found
for (var i = 0; i < selectedCells.length; i++) {
selectedCells[i].setFound();
}
// Mark word in list as found
for (var i = 0; i < wordList.length; i++) {
if (wordList[i].actualWord === word) {
wordList[i].markFound();
break;
}
}
LK.getSound('wordFound').play();
LK.setScore(LK.getScore() + word.length * 10);
// Check win condition
if (foundWords.length === words.length) {
// Save high score
var currentScore = LK.getScore();
var highScores = storage.highScores || [];
// Add current score and sort
highScores.push(currentScore);
highScores.sort(function (a, b) {
return b - a;
});
// Keep only top 10 scores
if (highScores.length > 10) {
highScores = highScores.slice(0, 10);
}
// Save back to storage
storage.highScores = highScores;
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
}
}
// Check if cells form a line
function isValidSelection(cells) {
if (cells.length < 2) return true;
var deltaRow = cells[1].row - cells[0].row;
var deltaCol = cells[1].col - cells[0].col;
// Normalize direction
if (deltaRow !== 0) deltaRow = deltaRow > 0 ? 1 : -1;
if (deltaCol !== 0) deltaCol = deltaCol > 0 ? 1 : -1;
for (var i = 2; i < cells.length; i++) {
var currentDeltaRow = cells[i].row - cells[i - 1].row;
var currentDeltaCol = cells[i].col - cells[i - 1].col;
if (currentDeltaRow !== 0) currentDeltaRow = currentDeltaRow > 0 ? 1 : -1;
if (currentDeltaCol !== 0) currentDeltaCol = currentDeltaCol > 0 ? 1 : -1;
if (currentDeltaRow !== deltaRow || currentDeltaCol !== deltaCol) {
return false;
}
}
return true;
}
// Fill empty cells with random letters
function fillEmptyCells() {
for (var i = 0; i < GRID_SIZE; i++) {
for (var j = 0; j < GRID_SIZE; j++) {
if (grid[i][j] === null) {
grid[i][j] = getRandomLetter();
}
}
}
}
// Start game function
function startGame() {
// Initialize game
createGrid();
placeWords();
fillEmptyCells();
createVisualGrid();
createWordList();
// Create title
var titleText = new Text2('WORD QUEST', {
size: 142,
fill: 0x2196F3,
letterSpacing: 8
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 150;
game.addChild(titleText);
// Create score display
scoreText = new Text2('Score: 0', {
size: 87,
fill: 0x333333,
letterSpacing: 2
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
scoreText.y = 200;
// Create high score button
var highScoreButton = LK.getAsset('selectedCell', {
width: 300,
height: 80,
anchorX: 0.5,
anchorY: 0.5
});
highScoreButton.x = 2048 - 200;
highScoreButton.y = 150;
game.addChild(highScoreButton);
var highScoreButtonText = new Text2('HIGH SCORES', {
size: 40,
fill: 0xffffff,
letterSpacing: 2
});
highScoreButtonText.anchor.set(0.5, 0.5);
highScoreButtonText.x = 2048 - 200;
highScoreButtonText.y = 150;
game.addChild(highScoreButtonText);
// High score button functionality
highScoreButton.down = function () {
var popup = new HighScorePopup();
game.addChild(popup);
// Animate popup appearance
popup.alpha = 0;
popup.scaleX = 0.5;
popup.scaleY = 0.5;
tween(popup, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
};
}
// Show nickname screen on game start
var nicknameScreen = new NicknameScreen();
game.addChild(nicknameScreen);
game.down = function (x, y, obj) {
// Create 4 sliding boxes from the selected point
for (var i = 0; i < 4; i++) {
var box = LK.getAsset('selectedCell', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
scaleX: 0.5,
scaleY: 0.5
});
game.addChild(box);
// Define slide directions (up, down, left, right)
var directions = [{
x: 0,
y: -200
},
// up
{
x: 0,
y: 200
},
// down
{
x: -200,
y: 0
},
// left
{
x: 200,
y: 0
} // right
];
var targetX = x + directions[i].x;
var targetY = y + directions[i].y;
// Animate box sliding out and fading
tween(box, {
x: targetX,
y: targetY,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
box.destroy();
}
});
}
var cell = getCellAtPosition(x, y);
if (cell && !cell.isFound) {
isDragging = true;
clearSelection();
selectedCells.push(cell);
cell.setSelected(true);
LK.getSound('selectLetter').play();
}
};
game.move = function (x, y, obj) {
if (isDragging) {
var cell = getCellAtPosition(x, y);
if (cell && !cell.isFound && selectedCells.indexOf(cell) === -1) {
var tempSelection = selectedCells.slice();
tempSelection.push(cell);
if (isValidSelection(tempSelection)) {
selectedCells.push(cell);
cell.setSelected(true);
LK.getSound('selectLetter').play();
}
}
}
};
game.up = function (x, y, obj) {
if (isDragging) {
isDragging = false;
if (selectedCells.length > 1) {
var selectedWord = getSelectedWord();
var reverseWord = selectedWord.split('').reverse().join('');
if (isValidWord(selectedWord)) {
markWordFound(selectedWord);
} else if (isValidWord(reverseWord)) {
markWordFound(reverseWord);
} else {
clearSelection();
}
} else {
clearSelection();
}
}
};
game.update = function () {
if (scoreText) {
scoreText.setText('Score: ' + LK.getScore());
}
};