/****
* 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());
}
};