User prompt
the buttons in the main menu are not correctly clicable
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toLowerCase')' in or related to this line: 'if (guess.toLowerCase() === self.words[self.currentWordIndex]) {' Line Number: 22
Initial prompt
Word Guesser
/****
* Classes
****/
var Confetti = Container.expand(function () {
var self = Container.call(this);
var confettiGraphics = self.attachAsset('confetti', {
anchorX: 0.5,
anchorY: 0.5
});
// Random color
confettiGraphics.tint = Math.random() * 0xffffff;
self.vx = (Math.random() - 0.5) * 20;
self.vy = -Math.random() * 15 - 5;
self.gravity = 0.5;
self.rotation = Math.random() * Math.PI * 2;
self.rotSpeed = (Math.random() - 0.5) * 0.2;
self.lifetime = 60 + Math.random() * 60;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
self.vy += self.gravity;
self.rotation += self.rotSpeed;
self.lifetime--;
self.alpha = Math.min(1, self.lifetime / 30);
if (self.lifetime <= 0) {
self.destroy();
return true;
}
return false;
};
});
var Letter = Container.expand(function (_char, index) {
var self = Container.call(this);
var letterGraphics = self.attachAsset('letter', {
anchorX: 0.5,
anchorY: 0.5
});
var letterText = new Text2(_char.toUpperCase(), {
size: 70,
fill: 0x000000
});
letterText.anchor.set(0.5);
self.addChild(letterText);
self["char"] = _char;
self.slotIndex = null;
self.originalIndex = index;
self.isDragging = false;
self.startX = 0;
self.startY = 0;
self.targetX = 0;
self.targetY = 0;
self.isMoving = false;
self.setHighlight = function (isCorrect) {
if (isCorrect) {
letterGraphics.tint = 0x33ff33;
} else if (isCorrect === false) {
// explicitly check for false to differentiate from undefined
letterGraphics.tint = 0xff3333;
} else {
letterGraphics.tint = 0xffffff;
}
};
self.update = function () {
if (self.isMoving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 5) {
self.x = self.targetX;
self.y = self.targetY;
self.isMoving = false;
} else {
self.x += dx * 0.2;
self.y += dy * 0.2;
}
}
};
self.moveTo = function (x, y) {
self.targetX = x;
self.targetY = y;
self.isMoving = true;
};
self.returnToField = function () {
self.slotIndex = null;
self.moveTo(self.startX, self.startY);
};
});
var Slot = Container.expand(function (index) {
var self = Container.call(this);
var slotGraphics = self.attachAsset('slot', {
anchorX: 0.5,
anchorY: 0.5
});
self.index = index;
self.letter = null;
self.setLetter = function (letter) {
self.letter = letter;
if (letter) {
letter.slotIndex = self.index;
}
};
self.clearLetter = function () {
if (self.letter) {
self.letter.slotIndex = null;
self.letter = null;
}
};
});
var TimeBar = Container.expand(function () {
var self = Container.call(this);
var barBg = self.attachAsset('timeBarBg', {
anchorX: 0,
anchorY: 0.5
});
var barFill = new Container();
var barFillGraphics = barFill.attachAsset('timeBar', {
anchorX: 0,
anchorY: 0.5
});
self.addChild(barFill);
self.maxTime = 15 * 60; // 15 seconds at 60fps
self.timeLeft = self.maxTime;
self.reset = function () {
self.timeLeft = self.maxTime;
barFill.scale.x = 1;
};
self.update = function () {
if (self.timeLeft > 0) {
self.timeLeft--;
barFill.scale.x = self.timeLeft / self.maxTime;
}
return self.timeLeft <= 0;
};
});
/****
* Initialize Game
****/
/****
* Game Setup
****/
var game = new LK.Game({
backgroundColor: 0x000055
});
/****
* Game Code
****/
// Play background music in a loop
var WordList = function WordList() {
// A selection of 500 English words (5-9 letters)
var words = ["about", "above", "actor", "adult", "after", "again", "agree", "ahead", "album", "allow", "alone", "along", "already", "always", "amount", "angry", "animal", "answer", "anyone", "anything", "appear", "apple", "argue", "around", "arrive", "artist", "assume", "attack", "attend", "author", "autumn", "awake", "award", "badge", "baggage", "bake", "balance", "balloon", "banana", "banner", "barely", "barrel", "basket", "battle", "beach", "beauty", "because", "become", "before", "begin", "behind", "belief", "belong", "beneath", "beside", "better", "between", "beyond", "bicycle", "black", "blame", "blank", "blanket", "blind", "block", "blood", "board", "boast", "bonus", "border", "borrow", "bottle", "bottom", "bounce", "brain", "branch", "brave", "bread", "break", "breath", "brick", "bridge", "brief", "bright", "broad", "broken", "brother", "brown", "brush", "budget", "build", "bumpy", "bunch", "burden", "butter", "button", "cable", "camel", "camera", "cancel", "candy", "cannon", "canoe", "canvas", "canyon", "capable", "capital", "captain", "carbon", "career", "careful", "carpet", "carrot", "carry", "carton", "castle", "cattle", "caught", "cause", "caution", "cease", "ceiling", "celery", "cellar", "century", "certain", "chain", "chair", "chalk", "channel", "chapter", "charge", "charm", "chart", "chase", "cheap", "check", "cheer", "cheese", "cherry", "chicken", "chief", "child", "chill", "choice", "choose", "church", "circle", "claim", "class", "clean", "clear", "clerk", "clever", "cliff", "climb", "clock", "close", "cloth", "cloud", "clown", "coach", "coast", "coffee", "collar", "colony", "color", "column", "combat", "combine", "comedy", "coming", "common", "compass", "complex", "compute", "conceal", "concept", "concern", "concert", "conduct", "confirm", "connect", "consent", "contain", "content", "contest", "control", "convert", "cookie", "copper", "corner", "correct", "cotton", "couch", "cough", "council", "count", "country", "county", "couple", "course", "cousin", "cover", "crack", "craft", "crash", "crawl", "crazy", "cream", "create", "credit", "creek", "crime", "crisp", "critic", "cross", "crowd", "crown", "cruel", "crush", "crystal", "culture", "cunning", "curious", "current", "curtain", "curve", "cushion", "custom", "cutting", "cycle", "daily", "damage", "dance", "danger", "daring", "darken", "dazzle", "dealer", "debate", "debris", "decade", "decay", "decent", "decide", "declare", "decorate", "decrease", "dedicate", "defeat", "defend", "define", "degree", "delay", "delete", "delight", "deliver", "demand", "demise", "denial", "dense", "dental", "depart", "depend", "depict", "deposit", "depth", "deputy", "derive", "describe", "desert", "design", "desire", "despair", "destroy", "detail", "detect", "develop", "device", "devote", "diagnose", "diamond", "diary", "dictate", "differ", "digest", "digital", "dignity", "dilemma", "diminish", "dinner", "direct", "disable", "disagree", "disclose", "discover", "discuss", "disease", "disgust", "dismiss", "display", "dispose", "distance", "distort", "disturb", "divide", "divine", "dizzy", "doctor", "document", "domain", "domestic", "dominate", "donate", "donor", "double", "doubt", "dozen", "draft", "dragon", "drama", "dream", "dress", "drift", "drink", "drive", "drone", "drown", "drunk", "dryer", "duckling", "dumb", "dusk", "dust", "duty", "dwarf", "dwell", "eager", "eagle", "early", "earth", "easily", "easter", "eastern", "eating", "eclipse", "ecology", "economy", "edition", "editor", "educate", "effect", "effort", "eight", "either", "elbow", "elder", "elect", "eleven", "elite", "email", "embark", "embody", "embrace", "emerge", "emotion", "employ", "empower", "empty", "enable", "enact", "endless", "endorse", "endure", "enemy", "energy", "enforce", "engage", "engine", "enhance", "enjoy", "enlist", "enough", "enrich", "ensign", "ensure", "enter", "entitle", "entity", "entrance", "envelope", "envision", "envy", "equal", "equip", "equity", "eraser", "erode", "erosion", "error", "erupt", "escape", "escort", "essay", "essence", "estate", "esteem", "eternal", "ethics", "evidence", "evoke", "evolve", "exact", "examine", "example", "exceed", "excel", "except", "excess", "exchange", "excite", "exclude", "excuse", "execute", "exempt", "exhaust", "exhibit", "exist", "expand", "expect", "expert", "explain", "explode", "explore", "export", "expose", "express", "extend", "extra", "eyebrow", "fabric", "facade", "factor", "factory", "faculty", "fading", "falcon", "falling", "fallout", "famous", "fantasy", "farmer", "fashion", "father", "fatigue", "fault", "favor", "feature", "federal", "feeling", "fellow", "female", "fence", "ferry", "fever", "fiber", "fiction", "field", "fierce", "fight", "figure", "filter", "final", "find", "finger", "finish", "fire", "firm", "first"];
return {
getRandomWord: function getRandomWord() {
return words[Math.floor(Math.random() * words.length)];
}
};
};
LK.playMusic('background', {
loop: true
});
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var LETTER_SIZE = 100;
var LETTER_MARGIN = 20;
var PLAYING_FIELD_TOP = 400;
var PLAYING_FIELD_HEIGHT = 1300;
var SLOT_AREA_TOP = PLAYING_FIELD_TOP + PLAYING_FIELD_HEIGHT + 100;
/****
* Game Variables
****/
var wordList = new WordList();
var currentWord = "";
var letters = [];
var slots = [];
var confetti = [];
var score = 0;
var wordsCompleted = 0;
var timeBar = null;
var isGameActive = false;
var isProMode = false;
var menuContainer = null;
var gameContainer = null;
/****
* UI Elements
****/
var background = game.attachAsset('background', {});
game.addChildAt(background, 0);
var scoreText = new Text2('SCORE: 0', {
size: 70,
fill: 0xffffff
});
scoreText.anchor.set(0, 0);
scoreText.x = 50;
scoreText.y = 50;
var wordText = new Text2('WORD: 0', {
size: 70,
fill: 0xffffff
});
wordText.anchor.set(0, 0);
wordText.x = 50;
wordText.y = 130;
var statusText = new Text2('', {
size: 70,
fill: 0xffffff
});
statusText.anchor.set(0.5);
statusText.x = GAME_WIDTH / 2;
statusText.y = 200;
/****
* Main Menu
****/
function createMainMenu() {
menuContainer = new Container();
game.addChild(menuContainer);
var menuBg = menuContainer.attachAsset('menuBackground', {});
var titleText = new Text2('WORD PUZZLE', {
size: 120,
fill: 0xffffff
});
titleText.anchor.set(0.5);
titleText.x = GAME_WIDTH / 2;
titleText.y = GAME_HEIGHT * 0.25;
menuContainer.addChild(titleText);
var casualButton = new Container();
var casualBtnGraphics = casualButton.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5
});
var casualBtnText = new Text2('CASUAL MODE', {
size: 70,
fill: 0xffffff
});
casualBtnText.anchor.set(0.5);
casualButton.addChild(casualBtnText);
casualButton.x = GAME_WIDTH / 2;
casualButton.y = GAME_HEIGHT * 0.45;
menuContainer.addChild(casualButton);
casualButton.interactive = true;
casualButton.buttonMode = true;
casualButton.on('pointerdown', function () {
startGame(false);
});
var proButton = new Container();
var proBtnGraphics = proButton.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5
});
proBtnGraphics.tint = 0xff3366;
var proBtnText = new Text2('PRO MODE', {
size: 70,
fill: 0xffffff
});
proBtnText.anchor.set(0.5);
proButton.addChild(proBtnText);
proButton.x = GAME_WIDTH / 2;
proButton.y = GAME_HEIGHT * 0.6;
menuContainer.addChild(proButton);
proButton.interactive = true;
proButton.buttonMode = true;
proButton.on('pointerdown', function () {
startGame(true);
});
var instructionsText = new Text2('Arrange the letters to form the correct word', {
size: 50,
fill: 0xaaaaff
});
instructionsText.anchor.set(0.5);
instructionsText.x = GAME_WIDTH / 2;
instructionsText.y = GAME_HEIGHT * 0.75;
menuContainer.addChild(instructionsText);
}
/****
* Game Functions
****/
function startGame(proMode) {
// Remove menu if it exists
if (menuContainer) {
menuContainer.destroy();
menuContainer = null;
}
// Create game container
gameContainer = new Container();
game.addChild(gameContainer);
// Add UI elements
gameContainer.addChild(scoreText);
gameContainer.addChild(wordText);
gameContainer.addChild(statusText);
// Set game mode
isProMode = proMode;
// Create time bar for pro mode
if (isProMode) {
timeBar = new TimeBar();
timeBar.x = GAME_WIDTH / 2 - 900;
timeBar.y = 300;
gameContainer.addChild(timeBar);
}
// Reset game state
score = 0;
wordsCompleted = 0;
updateScoreDisplay();
// Start the game
isGameActive = true;
loadNextWord();
}
function loadNextWord() {
// Clear current word
clearCurrentWord();
// Get a new random word
currentWord = wordList.getRandomWord();
// Create slots for the word
createSlots(currentWord.length);
// Create jumbled letters
createLetters(currentWord);
// Reset time bar for pro mode
if (isProMode && timeBar) {
timeBar.reset();
}
// Update status
statusText.setText('Arrange the letters!');
statusText.style.fill = 0xffffff;
}
function createSlots(count) {
slots = [];
var totalWidth = count * (LETTER_SIZE + LETTER_MARGIN);
var startX = (GAME_WIDTH - totalWidth) / 2 + LETTER_SIZE / 2;
for (var i = 0; i < count; i++) {
var slot = new Slot(i);
slot.x = startX + i * (LETTER_SIZE + LETTER_MARGIN);
slot.y = SLOT_AREA_TOP;
slots.push(slot);
gameContainer.addChild(slot);
}
}
function createLetters(word) {
letters = [];
// Create array of characters
var chars = word.split('');
// Shuffle the characters
for (var i = chars.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
// Calculate grid dimensions
var cols = Math.ceil(Math.sqrt(chars.length));
var rows = Math.ceil(chars.length / cols);
// Calculate starting position for grid
var gridWidth = cols * (LETTER_SIZE + LETTER_MARGIN);
var gridHeight = rows * (LETTER_SIZE + LETTER_MARGIN);
var startX = (GAME_WIDTH - gridWidth) / 2 + LETTER_SIZE / 2;
var startY = PLAYING_FIELD_TOP + (PLAYING_FIELD_HEIGHT - gridHeight) / 2 + LETTER_SIZE / 2;
// Create letter objects
for (var k = 0; k < chars.length; k++) {
var row = Math.floor(k / cols);
var col = k % cols;
var letter = new Letter(chars[k], k);
letter.x = startX + col * (LETTER_SIZE + LETTER_MARGIN);
letter.y = startY + row * (LETTER_SIZE + LETTER_MARGIN);
letter.startX = letter.x;
letter.startY = letter.y;
letters.push(letter);
gameContainer.addChild(letter);
// Make letter interactive
letter.interactive = true;
letter.buttonMode = true;
// Set up drag events
letter.on('pointerdown', onLetterDragStart);
letter.on('pointermove', onLetterDragMove);
letter.on('pointerup', onLetterDragEnd);
letter.on('pointerupoutside', onLetterDragEnd);
}
}
function clearCurrentWord() {
// Remove all letters and slots
for (var i = 0; i < letters.length; i++) {
letters[i].destroy();
}
letters = [];
for (var j = 0; j < slots.length; j++) {
slots[j].destroy();
}
slots = [];
}
function checkWord() {
// Check if all slots have letters
var allSlotsFilled = true;
for (var i = 0; i < slots.length; i++) {
if (!slots[i].letter) {
allSlotsFilled = false;
break;
}
}
if (!allSlotsFilled) {
return;
}
// Get the word formed by the letters in slots
var formedWord = "";
for (var j = 0; j < slots.length; j++) {
formedWord += slots[j].letter["char"];
}
// Check if the word is correct
if (formedWord === currentWord) {
wordCorrect();
} else {
wordIncorrect();
}
}
function wordCorrect() {
// Play sound
LK.getSound('correct').play();
// Update status
statusText.setText('CORRECT!');
statusText.style.fill = 0x33ff33;
// Highlight letters
for (var i = 0; i < letters.length; i++) {
letters[i].setHighlight(true);
}
// Create confetti effect
for (var j = 0; j < 100; j++) {
var conf = new Confetti();
conf.x = GAME_WIDTH / 2;
conf.y = SLOT_AREA_TOP;
confetti.push(conf);
gameContainer.addChild(conf);
}
// Calculate score based on word length and time (for pro mode)
var wordScore = currentWord.length * 10;
if (isProMode && timeBar) {
var timeBonus = Math.floor(timeBar.timeLeft / 10);
wordScore += timeBonus;
}
score += wordScore;
wordsCompleted++;
updateScoreDisplay();
// Load next word after delay
setTimeout(function () {
if (isGameActive) {
loadNextWord();
}
}, 1500);
}
function wordIncorrect() {
// Play sound
LK.getSound('wrong').play();
// Update status
statusText.setText('TRY AGAIN!');
statusText.style.fill = 0xff3333;
// Highlight letters
for (var i = 0; i < letters.length; i++) {
letters[i].setHighlight(false);
}
// Return letters to their original positions after delay
setTimeout(function () {
if (isGameActive) {
for (var i = 0; i < letters.length; i++) {
if (letters[i].slotIndex !== null) {
var slot = slots[letters[i].slotIndex];
slot.clearLetter();
}
letters[i].returnToField();
letters[i].setHighlight(undefined);
}
statusText.setText('Arrange the letters!');
statusText.style.fill = 0xffffff;
}
}, 1000);
}
function updateScoreDisplay() {
scoreText.setText('SCORE: ' + score);
wordText.setText('WORDS: ' + wordsCompleted);
}
function gameOver() {
// Play sound
LK.getSound('gameOver').play();
// Update status
statusText.setText('GAME OVER!');
statusText.style.fill = 0xff3333;
// Disable game
isGameActive = false;
// Submit score
LK.setScore(score);
// Show game over screen after delay
setTimeout(function () {
LK.showGameOver();
}, 2000);
}
function returnToMenu() {
if (gameContainer) {
gameContainer.destroy();
gameContainer = null;
}
createMainMenu();
}
/****
* Event Handlers
****/
function onLetterDragStart(event) {
if (!isGameActive) {
return;
}
var letter = this;
letter.isDragging = true;
letter.dragData = event.data;
letter.alpha = 0.8;
// If letter is in a slot, remove it
if (letter.slotIndex !== null) {
var oldSlot = slots[letter.slotIndex];
oldSlot.clearLetter();
}
}
function onLetterDragMove(event) {
if (!isGameActive) {
return;
}
var letter = this;
if (letter.isDragging) {
var newPosition = letter.dragData.getLocalPosition(letter.parent);
letter.x = newPosition.x;
letter.y = newPosition.y;
}
}
function onLetterDragEnd() {
if (!isGameActive) {
return;
}
var letter = this;
letter.isDragging = false;
letter.alpha = 1;
// Check if letter is dropped on a slot
var nearestSlot = null;
var minDistance = LETTER_SIZE * 1.5;
for (var i = 0; i < slots.length; i++) {
var slot = slots[i];
var dx = letter.x - slot.x;
var dy = letter.y - slot.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance && !slot.letter) {
nearestSlot = slot;
minDistance = distance;
}
}
// Place letter in slot or return to field
if (nearestSlot) {
nearestSlot.setLetter(letter);
letter.moveTo(nearestSlot.x, nearestSlot.y);
LK.getSound('letterPlace').play();
// Check if word is complete
setTimeout(checkWord, 200);
} else {
letter.returnToField();
}
}
/****
* Game Loop
****/
LK.on('tick', function () {
// Update letters
for (var i = 0; i < letters.length; i++) {
letters[i].update();
}
// Update confetti
for (var j = confetti.length - 1; j >= 0; j--) {
if (confetti[j].update()) {
confetti.splice(j, 1);
}
}
// Update timer in pro mode
if (isGameActive && isProMode && timeBar) {
if (timeBar.update()) {
gameOver();
}
}
});
// Start with the main menu
createMainMenu(); ===================================================================
--- original.js
+++ change.js
@@ -237,8 +237,9 @@
casualButton.x = GAME_WIDTH / 2;
casualButton.y = GAME_HEIGHT * 0.45;
menuContainer.addChild(casualButton);
casualButton.interactive = true;
+ casualButton.buttonMode = true;
casualButton.on('pointerdown', function () {
startGame(false);
});
var proButton = new Container();
@@ -256,8 +257,9 @@
proButton.x = GAME_WIDTH / 2;
proButton.y = GAME_HEIGHT * 0.6;
menuContainer.addChild(proButton);
proButton.interactive = true;
+ proButton.buttonMode = true;
proButton.on('pointerdown', function () {
startGame(true);
});
var instructionsText = new Text2('Arrange the letters to form the correct word', {