User prompt
increase the letter falling spawn
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'parse')' in or related to this line: 'storage.originalWordLists = JSON.parse(JSON.stringify(this.wordLists));' Line Number: 397
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'parse')' in or related to this line: 'storage.originalWordLists = JSON.parse(JSON.stringify(this.wordLists));' Line Number: 396
User prompt
i dont want repeated words when i am playing the game
User prompt
can you please add more words in wordlist
User prompt
increase the letter falling spawn
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'castSpell')' in or related to this line: 'this.wizard.castSpell();' Line Number: 517
User prompt
add mouse interaction to select the letter when i click the falling leters
User prompt
remove the wizard asset and related code
Code edit (1 edits merged)
Please save this source code
User prompt
can you please add some gap in between cast spell and wizard and letterslot
Code edit (1 edits merged)
Please save this source code
User prompt
Word Wizard: Spell Masters
Initial prompt
Create a 2D educational adventure game called 'Word Wizard,' where players help a young wizard learn magical spells by solving word puzzles and spelling challenges. The game should have a fantasy-themed world with different enchanted lands to explore. Players collect letters to form words and defeat vocabulary monsters. The game should include three difficulty levels (easy, medium, hard) and power-ups like hints or extra time. A friendly guide, such as a wise owl or a talking spellbook, helps the player along the journey. The goal is to recover lost magical words stolen by an evil sorcerer and restore the wizard's powers. The game should be fully playable using a mouse or touchscreen.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { difficultyLevel: 1, highScore: 0 }); /**** * Classes ****/ var Letter = Container.expand(function () { var self = Container.call(this); self.value = ''; self.isCollected = false; self.fallSpeed = 3 + Math.random() * 2; var letterGraphic = self.attachAsset('letter', { anchorX: 0.5, anchorY: 0.5 }); self.textDisplay = new Text2('A', { size: 60, fill: 0x000000 }); self.textDisplay.anchor.set(0.5, 0.5); self.addChild(self.textDisplay); self.setValue = function (letter) { self.value = letter; self.textDisplay.setText(letter); }; self.collect = function () { self.isCollected = true; LK.getSound('collectLetter').play(); LK.effects.flashObject(self, 0xFFFFFF, 300); tween(self, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { self.visible = false; } }); }; self.update = function () { if (!self.isCollected) { self.y += self.fallSpeed; // Slight side-to-side movement self.x += Math.sin(LK.ticks / 20) * 0.8; } }; return self; }); var LetterSlot = Container.expand(function () { var self = Container.call(this); self.letter = ''; self.isFilled = false; var slotGraphic = self.attachAsset('letterSlot', { anchorX: 0.5, anchorY: 0.5 }); self.textDisplay = new Text2('', { size: 50, fill: 0x000000 }); self.textDisplay.anchor.set(0.5, 0.5); self.addChild(self.textDisplay); self.setLetter = function (letter) { self.letter = letter; self.isFilled = true; self.textDisplay.setText(letter); tween(slotGraphic, { tint: 0xAAFFAA }, { duration: 300 }); }; self.clear = function () { self.letter = ''; self.isFilled = false; self.textDisplay.setText(''); tween(slotGraphic, { tint: 0xFFFFFF }, { duration: 300 }); }; self.down = function (x, y, obj) { if (self.isFilled) { self.clear(); gameState.removeLetter(self.index); } }; return self; }); var Monster = Container.expand(function () { var self = Container.call(this); self.word = ''; self.health = 100; self.isDefeated = false; var monsterGraphic = self.attachAsset('monster', { anchorX: 0.5, anchorY: 0.5 }); self.wordDisplay = new Text2('', { size: 50, fill: 0xFFFFFF }); self.wordDisplay.anchor.set(0.5, 0.5); self.addChild(self.wordDisplay); self.healthDisplay = new Text2('100%', { size: 30, fill: 0xFFFFFF }); self.healthDisplay.anchor.set(0.5, 0.5); self.healthDisplay.y = -80; self.addChild(self.healthDisplay); self.setWord = function (word) { self.word = word.toUpperCase(); self.wordDisplay.setText(self.word); }; self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0) { self.health = 0; self.defeat(); } self.healthDisplay.setText(self.health + '%'); // Flash red when taking damage LK.effects.flashObject(monsterGraphic, 0xFF0000, 300); }; self.defeat = function () { if (!self.isDefeated) { self.isDefeated = true; LK.getSound('defeatMonster').play(); LK.effects.flashObject(self, 0xFFFFFF, 500); tween(self, { alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { self.visible = false; } }); } }; self.update = function () { if (!self.isDefeated) { // Breathing animation monsterGraphic.scaleX = 1 + Math.sin(LK.ticks / 30) * 0.05; monsterGraphic.scaleY = 1 + Math.sin(LK.ticks / 30) * 0.05; } }; return self; }); var Owl = Container.expand(function () { var self = Container.call(this); var owlGraphic = self.attachAsset('owl', { anchorX: 0.5, anchorY: 0.5 }); self.speechBubble = new Text2('', { size: 30, fill: 0x000000 }); self.speechBubble.anchor.set(0, 0.5); self.speechBubble.x = 70; self.addChild(self.speechBubble); self.speak = function (text) { self.speechBubble.setText(text); self.speechBubble.alpha = 1; // Clear previous timeout if exists if (self.timeoutId) { LK.clearTimeout(self.timeoutId); } // Hide message after 5 seconds self.timeoutId = LK.setTimeout(function () { tween(self.speechBubble, { alpha: 0 }, { duration: 1000 }); }, 5000); }; self.update = function () { // Slight bobbing animation owlGraphic.y = Math.sin(LK.ticks / 40) * 5; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); self.type = ''; self.isCollected = false; self.fallSpeed = 2; var powerupGraphic = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.textDisplay = new Text2('?', { size: 40, fill: 0xFFFFFF }); self.textDisplay.anchor.set(0.5, 0.5); self.addChild(self.textDisplay); self.setType = function (type) { self.type = type; if (type === 'hint') { self.textDisplay.setText('H'); powerupGraphic.tint = 0x00AAFF; } else if (type === 'time') { self.textDisplay.setText('T'); powerupGraphic.tint = 0xFFAA00; } else if (type === 'score') { self.textDisplay.setText('S'); powerupGraphic.tint = 0xAA00FF; } }; self.collect = function () { if (!self.isCollected) { self.isCollected = true; LK.getSound('powerup').play(); LK.effects.flashObject(self, 0xFFFFFF, 300); tween(self, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 500, onFinish: function onFinish() { self.visible = false; } }); } }; self.update = function () { if (!self.isCollected) { self.y += self.fallSpeed; // Rotate slowly self.rotation += 0.01; // Pulsing effect var scale = 1 + Math.sin(LK.ticks / 15) * 0.1; powerupGraphic.scaleX = scale; powerupGraphic.scaleY = scale; } }; return self; }); var SpellButton = Container.expand(function () { var self = Container.call(this); var buttonGraphic = self.attachAsset('spellButton', { anchorX: 0.5, anchorY: 0.5 }); self.textDisplay = new Text2('CAST SPELL', { size: 50, fill: 0xFFFFFF }); self.textDisplay.anchor.set(0.5, 0.5); self.addChild(self.textDisplay); self.isEnabled = true; self.setEnabled = function (enabled) { self.isEnabled = enabled; buttonGraphic.alpha = enabled ? 1 : 0.5; self.textDisplay.alpha = enabled ? 1 : 0.5; }; self.down = function (x, y, obj) { if (self.isEnabled) { // Button press effect tween(buttonGraphic, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); } }; self.up = function (x, y, obj) { if (self.isEnabled) { // Button release effect tween(buttonGraphic, { scaleX: 1, scaleY: 1 }, { duration: 100, onFinish: function onFinish() { gameState.castSpell(); } }); } }; return self; }); var Wizard = Container.expand(function () { var self = Container.call(this); var wizardGraphic = self.attachAsset('wizard', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.isMoving = false; self.targetX = 0; self.speed = 10; self.moveTo = function (x) { self.isMoving = true; self.targetX = x; }; self.update = function () { if (self.isMoving) { if (Math.abs(self.x - self.targetX) < self.speed) { self.x = self.targetX; self.isMoving = false; } else if (self.x < self.targetX) { self.x += self.speed; } else { self.x -= self.speed; } } }; self.castSpell = function () { LK.effects.flashObject(self, 0x00FFFF, 500); LK.getSound('castSpell').play(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game state variables var gameState = { level: 1, score: 0, highScore: storage.highScore || 0, difficultyLevel: storage.difficultyLevel || 1, collectedLetters: [], currentWord: '', wordSlots: [], availableLetters: [], monsters: [], powerups: [], spawnLetterTimer: null, spawnPowerupTimer: null, gameActive: false, // Word lists for different difficulty levels wordLists: { 1: ['CAT', 'DOG', 'HAT', 'RUN', 'SUN', 'FUN', 'MAP', 'BIG', 'PET', 'RED'], 2: ['MAGIC', 'SPELL', 'POWER', 'WITCH', 'WAND', 'FAIRY', 'POTION', 'CHARM', 'BOOK', 'MYSTIC'], 3: ['WIZARD', 'SORCERER', 'ENCHANTED', 'MAGICAL', 'LEVITATE', 'TRANSFORM', 'VANISHING', 'CONJURE', 'TELEPORT', 'MYSTICAL'] }, // Available letters by difficulty letterSets: { 1: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 2: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 3: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' }, initialize: function initialize() { // Reset game state this.score = 0; this.collectedLetters = []; this.availableLetters = []; this.monsters = []; this.powerups = []; this.gameActive = true; // Create wizard character this.wizard = new Wizard(); this.wizard.x = 2048 / 2; this.wizard.y = 2732 - 200; game.addChild(this.wizard); // Create owl helper this.owl = new Owl(); this.owl.x = 150; this.owl.y = 200; game.addChild(this.owl); // Create spell button this.spellButton = new SpellButton(); this.spellButton.x = 2048 / 2; this.spellButton.y = 2732 - 100; game.addChild(this.spellButton); this.spellButton.setEnabled(false); // Set up word slots this.setupWordSlots(); // Spawn first monster this.spawnMonster(); // Start letter spawning this.startLetterSpawning(); // Start powerup spawning this.startPowerupSpawning(); // Show welcome message this.owl.speak("Welcome, young wizard! Collect falling letters to spell words and defeat monsters!"); // Update score display this.updateScoreDisplay(); // Play background music LK.playMusic('gameMusic'); }, setupWordSlots: function setupWordSlots() { this.wordSlots = []; // Create slots for letters (max 8 slots) var maxSlots = 8; var slotWidth = 90; var totalWidth = slotWidth * maxSlots; var startX = (2048 - totalWidth) / 2 + slotWidth / 2; for (var i = 0; i < maxSlots; i++) { var slot = new LetterSlot(); slot.x = startX + i * slotWidth; slot.y = 2732 - 300; slot.index = i; this.wordSlots.push(slot); game.addChild(slot); } }, startLetterSpawning: function startLetterSpawning() { if (this.spawnLetterTimer) { LK.clearInterval(this.spawnLetterTimer); } this.spawnLetterTimer = LK.setInterval(function () { if (gameState.gameActive && gameState.availableLetters.length < 10) { gameState.spawnLetter(); } }, 2000); }, startPowerupSpawning: function startPowerupSpawning() { if (this.spawnPowerupTimer) { LK.clearInterval(this.spawnPowerupTimer); } this.spawnPowerupTimer = LK.setInterval(function () { if (gameState.gameActive && Math.random() < 0.3) { gameState.spawnPowerup(); } }, 10000); }, spawnLetter: function spawnLetter() { var letter = new Letter(); // Position randomly along top of screen letter.x = Math.random() * (2048 - 200) + 100; letter.y = -50; // Choose a letter that's in the current monster's word var currentWord = this.monsters[0] ? this.monsters[0].word : ''; var letterSet = this.letterSets[this.difficultyLevel]; if (currentWord && Math.random() < 0.7) { // 70% chance to spawn a letter from the current word var letterIndex = Math.floor(Math.random() * currentWord.length); letter.setValue(currentWord[letterIndex]); } else { // 30% chance to spawn a random letter var randomIndex = Math.floor(Math.random() * letterSet.length); letter.setValue(letterSet[randomIndex]); } game.addChild(letter); this.availableLetters.push(letter); }, spawnPowerup: function spawnPowerup() { var powerup = new PowerUp(); // Position randomly along top of screen powerup.x = Math.random() * (2048 - 200) + 100; powerup.y = -50; // Choose powerup type var types = ['hint', 'time', 'score']; var randomType = types[Math.floor(Math.random() * types.length)]; powerup.setType(randomType); game.addChild(powerup); this.powerups.push(powerup); }, spawnMonster: function spawnMonster() { var monster = new Monster(); monster.x = 2048 / 2; monster.y = 500; // Choose a word based on difficulty var wordList = this.wordLists[this.difficultyLevel]; var randomWord = wordList[Math.floor(Math.random() * wordList.length)]; monster.setWord(randomWord); game.addChild(monster); this.monsters.push(monster); this.owl.speak("A monster appeared! Spell \"" + randomWord + "\" to defeat it!"); }, collectLetter: function collectLetter(letter) { if (this.collectedLetters.length < 8) { // Add letter to collection this.collectedLetters.push(letter.value); // Find next empty slot for (var i = 0; i < this.wordSlots.length; i++) { if (!this.wordSlots[i].isFilled) { this.wordSlots[i].setLetter(letter.value); break; } } // Enable spell button if we have at least one letter this.spellButton.setEnabled(true); // Mark letter as collected letter.collect(); // Remove from available letters var index = this.availableLetters.indexOf(letter); if (index !== -1) { this.availableLetters.splice(index, 1); } } }, removeLetter: function removeLetter(index) { // Remove letter from collection if (index < this.collectedLetters.length) { this.collectedLetters.splice(index, 1); // Shift all letters in slots after the removed one for (var i = index; i < this.wordSlots.length - 1; i++) { if (i + 1 < this.collectedLetters.length) { this.wordSlots[i].setLetter(this.collectedLetters[i]); } else { this.wordSlots[i].clear(); } } // Disable spell button if no letters remaining if (this.collectedLetters.length === 0) { this.spellButton.setEnabled(false); } } }, castSpell: function castSpell() { // Form word from collected letters var word = this.collectedLetters.join(''); // Check if word matches current monster's word if (this.monsters.length > 0) { var monster = this.monsters[0]; if (word === monster.word) { // Correct word! Defeat monster this.wizard.castSpell(); monster.defeat(); // Calculate score based on word length and difficulty var scoreIncrease = word.length * 10 * this.difficultyLevel; this.score += scoreIncrease; this.updateScoreDisplay(); // Show success message this.owl.speak("Great job! You defeated the monster with your spell!"); // Clear collected letters and slots this.collectedLetters = []; for (var i = 0; i < this.wordSlots.length; i++) { this.wordSlots[i].clear(); } this.spellButton.setEnabled(false); // Remove monster from array LK.setTimeout(function () { var index = gameState.monsters.indexOf(monster); if (index !== -1) { gameState.monsters.splice(index, 1); } // Spawn next monster after a delay LK.setTimeout(function () { gameState.spawnMonster(); }, 2000); }, 1500); } else { // Wrong word LK.effects.flashScreen(0xFF0000, 300); this.owl.speak("Oops! That's not the right spell. Try again!"); // Clear collected letters and slots this.collectedLetters = []; for (var i = 0; i < this.wordSlots.length; i++) { this.wordSlots[i].clear(); } this.spellButton.setEnabled(false); } } }, usePowerup: function usePowerup(powerup) { powerup.collect(); if (powerup.type === 'hint') { // Hint powerup - reveal first letter of monster's word if (this.monsters.length > 0) { var monster = this.monsters[0]; this.owl.speak("Hint: The first letter is '" + monster.word[0] + "'"); } } else if (powerup.type === 'time') { // Time powerup - slow down letters for (var i = 0; i < this.availableLetters.length; i++) { this.availableLetters[i].fallSpeed *= 0.5; } this.owl.speak("Time slowed down!"); // Return to normal speed after 10 seconds LK.setTimeout(function () { for (var i = 0; i < gameState.availableLetters.length; i++) { gameState.availableLetters[i].fallSpeed *= 2; } }, 10000); } else if (powerup.type === 'score') { // Score powerup - bonus points this.score += 50; this.updateScoreDisplay(); this.owl.speak("Bonus 50 points!"); } // Remove from powerups array var index = this.powerups.indexOf(powerup); if (index !== -1) { this.powerups.splice(index, 1); } }, updateScoreDisplay: function updateScoreDisplay() { // Update score display scoreTxt.setText("SCORE: " + this.score); // Update high score if needed if (this.score > this.highScore) { this.highScore = this.score; storage.highScore = this.highScore; } }, checkCollisions: function checkCollisions() { // Check for letter collisions with wizard for (var i = this.availableLetters.length - 1; i >= 0; i--) { var letter = this.availableLetters[i]; if (!letter.isCollected && letter.intersects(this.wizard)) { this.collectLetter(letter); } // Remove letters that fall off screen if (letter.y > 2732 + 50) { letter.destroy(); this.availableLetters.splice(i, 1); } } // Check for powerup collisions with wizard for (var j = this.powerups.length - 1; j >= 0; j--) { var powerup = this.powerups[j]; if (!powerup.isCollected && powerup.intersects(this.wizard)) { this.usePowerup(powerup); } // Remove powerups that fall off screen if (powerup.y > 2732 + 50) { powerup.destroy(); this.powerups.splice(j, 1); } } }, checkGameOver: function checkGameOver() { // Game over logic // For example, if all monsters are defeated or time runs out if (this.score >= 500) { this.gameActive = false; // Show you win message this.owl.speak("Congratulations! You've mastered the spell words!"); LK.setTimeout(function () { LK.showYouWin(); }, 2000); } } }; // Initialize GUI elements var scoreTxt = new Text2("SCORE: 0", { size: 70, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Set up level selector UI (for difficulty) var levelText = new Text2("LEVEL: " + gameState.difficultyLevel, { size: 40, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); levelText.x = 120; levelText.y = 20; LK.gui.topLeft.addChild(levelText); // Level buttons var levelDecrease = new Text2("β", { size: 50, fill: 0xFFFFFF }); levelDecrease.anchor.set(0.5, 0.5); levelDecrease.x = 350; levelDecrease.y = 40; levelDecrease.interactive = true; levelDecrease.down = function () { if (gameState.difficultyLevel > 1) { gameState.difficultyLevel--; storage.difficultyLevel = gameState.difficultyLevel; levelText.setText("LEVEL: " + gameState.difficultyLevel); } }; LK.gui.topLeft.addChild(levelDecrease); var levelIncrease = new Text2("βΆ", { size: 50, fill: 0xFFFFFF }); levelIncrease.anchor.set(0.5, 0.5); levelIncrease.x = 400; levelIncrease.y = 40; levelIncrease.interactive = true; levelIncrease.down = function () { if (gameState.difficultyLevel < 3) { gameState.difficultyLevel++; storage.difficultyLevel = gameState.difficultyLevel; levelText.setText("LEVEL: " + gameState.difficultyLevel); } }; LK.gui.topLeft.addChild(levelIncrease); // Game event handlers game.down = function (x, y, obj) { // Move wizard when clicking/tapping on the game gameState.wizard.moveTo(x); }; game.move = function (x, y, obj) { // If on mobile/touch device, allow dragging the wizard if (obj.isActive) { gameState.wizard.moveTo(x); } }; // Main game loop game.update = function () { if (!gameState.gameActive) { return; } // Update all entities if (gameState.wizard) { gameState.wizard.update(); } if (gameState.owl) { gameState.owl.update(); } // Update available letters for (var i = 0; i < gameState.availableLetters.length; i++) { gameState.availableLetters[i].update(); } // Update monsters for (var j = 0; j < gameState.monsters.length; j++) { gameState.monsters[j].update(); } // Update powerups for (var k = 0; k < gameState.powerups.length; k++) { gameState.powerups[k].update(); } // Check for collisions gameState.checkCollisions(); // Check for game over conditions gameState.checkGameOver(); }; // Initialize the game state gameState.initialize();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,743 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ difficultyLevel: 1,
+ highScore: 0
+});
+
+/****
+* Classes
+****/
+var Letter = Container.expand(function () {
+ var self = Container.call(this);
+ self.value = '';
+ self.isCollected = false;
+ self.fallSpeed = 3 + Math.random() * 2;
+ var letterGraphic = self.attachAsset('letter', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.textDisplay = new Text2('A', {
+ size: 60,
+ fill: 0x000000
+ });
+ self.textDisplay.anchor.set(0.5, 0.5);
+ self.addChild(self.textDisplay);
+ self.setValue = function (letter) {
+ self.value = letter;
+ self.textDisplay.setText(letter);
+ };
+ self.collect = function () {
+ self.isCollected = true;
+ LK.getSound('collectLetter').play();
+ LK.effects.flashObject(self, 0xFFFFFF, 300);
+ tween(self, {
+ alpha: 0
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ self.visible = false;
+ }
+ });
+ };
+ self.update = function () {
+ if (!self.isCollected) {
+ self.y += self.fallSpeed;
+ // Slight side-to-side movement
+ self.x += Math.sin(LK.ticks / 20) * 0.8;
+ }
+ };
+ return self;
+});
+var LetterSlot = Container.expand(function () {
+ var self = Container.call(this);
+ self.letter = '';
+ self.isFilled = false;
+ var slotGraphic = self.attachAsset('letterSlot', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.textDisplay = new Text2('', {
+ size: 50,
+ fill: 0x000000
+ });
+ self.textDisplay.anchor.set(0.5, 0.5);
+ self.addChild(self.textDisplay);
+ self.setLetter = function (letter) {
+ self.letter = letter;
+ self.isFilled = true;
+ self.textDisplay.setText(letter);
+ tween(slotGraphic, {
+ tint: 0xAAFFAA
+ }, {
+ duration: 300
+ });
+ };
+ self.clear = function () {
+ self.letter = '';
+ self.isFilled = false;
+ self.textDisplay.setText('');
+ tween(slotGraphic, {
+ tint: 0xFFFFFF
+ }, {
+ duration: 300
+ });
+ };
+ self.down = function (x, y, obj) {
+ if (self.isFilled) {
+ self.clear();
+ gameState.removeLetter(self.index);
+ }
+ };
+ return self;
+});
+var Monster = Container.expand(function () {
+ var self = Container.call(this);
+ self.word = '';
+ self.health = 100;
+ self.isDefeated = false;
+ var monsterGraphic = self.attachAsset('monster', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.wordDisplay = new Text2('', {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ self.wordDisplay.anchor.set(0.5, 0.5);
+ self.addChild(self.wordDisplay);
+ self.healthDisplay = new Text2('100%', {
+ size: 30,
+ fill: 0xFFFFFF
+ });
+ self.healthDisplay.anchor.set(0.5, 0.5);
+ self.healthDisplay.y = -80;
+ self.addChild(self.healthDisplay);
+ self.setWord = function (word) {
+ self.word = word.toUpperCase();
+ self.wordDisplay.setText(self.word);
+ };
+ self.takeDamage = function (amount) {
+ self.health -= amount;
+ if (self.health <= 0) {
+ self.health = 0;
+ self.defeat();
+ }
+ self.healthDisplay.setText(self.health + '%');
+ // Flash red when taking damage
+ LK.effects.flashObject(monsterGraphic, 0xFF0000, 300);
+ };
+ self.defeat = function () {
+ if (!self.isDefeated) {
+ self.isDefeated = true;
+ LK.getSound('defeatMonster').play();
+ LK.effects.flashObject(self, 0xFFFFFF, 500);
+ tween(self, {
+ alpha: 0,
+ scaleX: 0,
+ scaleY: 0
+ }, {
+ duration: 1000,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ self.visible = false;
+ }
+ });
+ }
+ };
+ self.update = function () {
+ if (!self.isDefeated) {
+ // Breathing animation
+ monsterGraphic.scaleX = 1 + Math.sin(LK.ticks / 30) * 0.05;
+ monsterGraphic.scaleY = 1 + Math.sin(LK.ticks / 30) * 0.05;
+ }
+ };
+ return self;
+});
+var Owl = Container.expand(function () {
+ var self = Container.call(this);
+ var owlGraphic = self.attachAsset('owl', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speechBubble = new Text2('', {
+ size: 30,
+ fill: 0x000000
+ });
+ self.speechBubble.anchor.set(0, 0.5);
+ self.speechBubble.x = 70;
+ self.addChild(self.speechBubble);
+ self.speak = function (text) {
+ self.speechBubble.setText(text);
+ self.speechBubble.alpha = 1;
+ // Clear previous timeout if exists
+ if (self.timeoutId) {
+ LK.clearTimeout(self.timeoutId);
+ }
+ // Hide message after 5 seconds
+ self.timeoutId = LK.setTimeout(function () {
+ tween(self.speechBubble, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ }, 5000);
+ };
+ self.update = function () {
+ // Slight bobbing animation
+ owlGraphic.y = Math.sin(LK.ticks / 40) * 5;
+ };
+ return self;
+});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ self.type = '';
+ self.isCollected = false;
+ self.fallSpeed = 2;
+ var powerupGraphic = self.attachAsset('powerup', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.textDisplay = new Text2('?', {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ self.textDisplay.anchor.set(0.5, 0.5);
+ self.addChild(self.textDisplay);
+ self.setType = function (type) {
+ self.type = type;
+ if (type === 'hint') {
+ self.textDisplay.setText('H');
+ powerupGraphic.tint = 0x00AAFF;
+ } else if (type === 'time') {
+ self.textDisplay.setText('T');
+ powerupGraphic.tint = 0xFFAA00;
+ } else if (type === 'score') {
+ self.textDisplay.setText('S');
+ powerupGraphic.tint = 0xAA00FF;
+ }
+ };
+ self.collect = function () {
+ if (!self.isCollected) {
+ self.isCollected = true;
+ LK.getSound('powerup').play();
+ LK.effects.flashObject(self, 0xFFFFFF, 300);
+ tween(self, {
+ alpha: 0,
+ scaleX: 1.5,
+ scaleY: 1.5
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ self.visible = false;
+ }
+ });
+ }
+ };
+ self.update = function () {
+ if (!self.isCollected) {
+ self.y += self.fallSpeed;
+ // Rotate slowly
+ self.rotation += 0.01;
+ // Pulsing effect
+ var scale = 1 + Math.sin(LK.ticks / 15) * 0.1;
+ powerupGraphic.scaleX = scale;
+ powerupGraphic.scaleY = scale;
+ }
+ };
+ return self;
+});
+var SpellButton = Container.expand(function () {
+ var self = Container.call(this);
+ var buttonGraphic = self.attachAsset('spellButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.textDisplay = new Text2('CAST SPELL', {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ self.textDisplay.anchor.set(0.5, 0.5);
+ self.addChild(self.textDisplay);
+ self.isEnabled = true;
+ self.setEnabled = function (enabled) {
+ self.isEnabled = enabled;
+ buttonGraphic.alpha = enabled ? 1 : 0.5;
+ self.textDisplay.alpha = enabled ? 1 : 0.5;
+ };
+ self.down = function (x, y, obj) {
+ if (self.isEnabled) {
+ // Button press effect
+ tween(buttonGraphic, {
+ scaleX: 0.95,
+ scaleY: 0.95
+ }, {
+ duration: 100
+ });
+ }
+ };
+ self.up = function (x, y, obj) {
+ if (self.isEnabled) {
+ // Button release effect
+ tween(buttonGraphic, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 100,
+ onFinish: function onFinish() {
+ gameState.castSpell();
+ }
+ });
+ }
+ };
+ return self;
+});
+var Wizard = Container.expand(function () {
+ var self = Container.call(this);
+ var wizardGraphic = self.attachAsset('wizard', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1,
+ scaleY: 1
+ });
+ self.isMoving = false;
+ self.targetX = 0;
+ self.speed = 10;
+ self.moveTo = function (x) {
+ self.isMoving = true;
+ self.targetX = x;
+ };
+ self.update = function () {
+ if (self.isMoving) {
+ if (Math.abs(self.x - self.targetX) < self.speed) {
+ self.x = self.targetX;
+ self.isMoving = false;
+ } else if (self.x < self.targetX) {
+ self.x += self.speed;
+ } else {
+ self.x -= self.speed;
+ }
+ }
+ };
+ self.castSpell = function () {
+ LK.effects.flashObject(self, 0x00FFFF, 500);
+ LK.getSound('castSpell').play();
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x87CEEB
+});
+
+/****
+* Game Code
+****/
+// Game state variables
+var gameState = {
+ level: 1,
+ score: 0,
+ highScore: storage.highScore || 0,
+ difficultyLevel: storage.difficultyLevel || 1,
+ collectedLetters: [],
+ currentWord: '',
+ wordSlots: [],
+ availableLetters: [],
+ monsters: [],
+ powerups: [],
+ spawnLetterTimer: null,
+ spawnPowerupTimer: null,
+ gameActive: false,
+ // Word lists for different difficulty levels
+ wordLists: {
+ 1: ['CAT', 'DOG', 'HAT', 'RUN', 'SUN', 'FUN', 'MAP', 'BIG', 'PET', 'RED'],
+ 2: ['MAGIC', 'SPELL', 'POWER', 'WITCH', 'WAND', 'FAIRY', 'POTION', 'CHARM', 'BOOK', 'MYSTIC'],
+ 3: ['WIZARD', 'SORCERER', 'ENCHANTED', 'MAGICAL', 'LEVITATE', 'TRANSFORM', 'VANISHING', 'CONJURE', 'TELEPORT', 'MYSTICAL']
+ },
+ // Available letters by difficulty
+ letterSets: {
+ 1: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 2: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 3: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ },
+ initialize: function initialize() {
+ // Reset game state
+ this.score = 0;
+ this.collectedLetters = [];
+ this.availableLetters = [];
+ this.monsters = [];
+ this.powerups = [];
+ this.gameActive = true;
+ // Create wizard character
+ this.wizard = new Wizard();
+ this.wizard.x = 2048 / 2;
+ this.wizard.y = 2732 - 200;
+ game.addChild(this.wizard);
+ // Create owl helper
+ this.owl = new Owl();
+ this.owl.x = 150;
+ this.owl.y = 200;
+ game.addChild(this.owl);
+ // Create spell button
+ this.spellButton = new SpellButton();
+ this.spellButton.x = 2048 / 2;
+ this.spellButton.y = 2732 - 100;
+ game.addChild(this.spellButton);
+ this.spellButton.setEnabled(false);
+ // Set up word slots
+ this.setupWordSlots();
+ // Spawn first monster
+ this.spawnMonster();
+ // Start letter spawning
+ this.startLetterSpawning();
+ // Start powerup spawning
+ this.startPowerupSpawning();
+ // Show welcome message
+ this.owl.speak("Welcome, young wizard! Collect falling letters to spell words and defeat monsters!");
+ // Update score display
+ this.updateScoreDisplay();
+ // Play background music
+ LK.playMusic('gameMusic');
+ },
+ setupWordSlots: function setupWordSlots() {
+ this.wordSlots = [];
+ // Create slots for letters (max 8 slots)
+ var maxSlots = 8;
+ var slotWidth = 90;
+ var totalWidth = slotWidth * maxSlots;
+ var startX = (2048 - totalWidth) / 2 + slotWidth / 2;
+ for (var i = 0; i < maxSlots; i++) {
+ var slot = new LetterSlot();
+ slot.x = startX + i * slotWidth;
+ slot.y = 2732 - 300;
+ slot.index = i;
+ this.wordSlots.push(slot);
+ game.addChild(slot);
+ }
+ },
+ startLetterSpawning: function startLetterSpawning() {
+ if (this.spawnLetterTimer) {
+ LK.clearInterval(this.spawnLetterTimer);
+ }
+ this.spawnLetterTimer = LK.setInterval(function () {
+ if (gameState.gameActive && gameState.availableLetters.length < 10) {
+ gameState.spawnLetter();
+ }
+ }, 2000);
+ },
+ startPowerupSpawning: function startPowerupSpawning() {
+ if (this.spawnPowerupTimer) {
+ LK.clearInterval(this.spawnPowerupTimer);
+ }
+ this.spawnPowerupTimer = LK.setInterval(function () {
+ if (gameState.gameActive && Math.random() < 0.3) {
+ gameState.spawnPowerup();
+ }
+ }, 10000);
+ },
+ spawnLetter: function spawnLetter() {
+ var letter = new Letter();
+ // Position randomly along top of screen
+ letter.x = Math.random() * (2048 - 200) + 100;
+ letter.y = -50;
+ // Choose a letter that's in the current monster's word
+ var currentWord = this.monsters[0] ? this.monsters[0].word : '';
+ var letterSet = this.letterSets[this.difficultyLevel];
+ if (currentWord && Math.random() < 0.7) {
+ // 70% chance to spawn a letter from the current word
+ var letterIndex = Math.floor(Math.random() * currentWord.length);
+ letter.setValue(currentWord[letterIndex]);
+ } else {
+ // 30% chance to spawn a random letter
+ var randomIndex = Math.floor(Math.random() * letterSet.length);
+ letter.setValue(letterSet[randomIndex]);
+ }
+ game.addChild(letter);
+ this.availableLetters.push(letter);
+ },
+ spawnPowerup: function spawnPowerup() {
+ var powerup = new PowerUp();
+ // Position randomly along top of screen
+ powerup.x = Math.random() * (2048 - 200) + 100;
+ powerup.y = -50;
+ // Choose powerup type
+ var types = ['hint', 'time', 'score'];
+ var randomType = types[Math.floor(Math.random() * types.length)];
+ powerup.setType(randomType);
+ game.addChild(powerup);
+ this.powerups.push(powerup);
+ },
+ spawnMonster: function spawnMonster() {
+ var monster = new Monster();
+ monster.x = 2048 / 2;
+ monster.y = 500;
+ // Choose a word based on difficulty
+ var wordList = this.wordLists[this.difficultyLevel];
+ var randomWord = wordList[Math.floor(Math.random() * wordList.length)];
+ monster.setWord(randomWord);
+ game.addChild(monster);
+ this.monsters.push(monster);
+ this.owl.speak("A monster appeared! Spell \"" + randomWord + "\" to defeat it!");
+ },
+ collectLetter: function collectLetter(letter) {
+ if (this.collectedLetters.length < 8) {
+ // Add letter to collection
+ this.collectedLetters.push(letter.value);
+ // Find next empty slot
+ for (var i = 0; i < this.wordSlots.length; i++) {
+ if (!this.wordSlots[i].isFilled) {
+ this.wordSlots[i].setLetter(letter.value);
+ break;
+ }
+ }
+ // Enable spell button if we have at least one letter
+ this.spellButton.setEnabled(true);
+ // Mark letter as collected
+ letter.collect();
+ // Remove from available letters
+ var index = this.availableLetters.indexOf(letter);
+ if (index !== -1) {
+ this.availableLetters.splice(index, 1);
+ }
+ }
+ },
+ removeLetter: function removeLetter(index) {
+ // Remove letter from collection
+ if (index < this.collectedLetters.length) {
+ this.collectedLetters.splice(index, 1);
+ // Shift all letters in slots after the removed one
+ for (var i = index; i < this.wordSlots.length - 1; i++) {
+ if (i + 1 < this.collectedLetters.length) {
+ this.wordSlots[i].setLetter(this.collectedLetters[i]);
+ } else {
+ this.wordSlots[i].clear();
+ }
+ }
+ // Disable spell button if no letters remaining
+ if (this.collectedLetters.length === 0) {
+ this.spellButton.setEnabled(false);
+ }
+ }
+ },
+ castSpell: function castSpell() {
+ // Form word from collected letters
+ var word = this.collectedLetters.join('');
+ // Check if word matches current monster's word
+ if (this.monsters.length > 0) {
+ var monster = this.monsters[0];
+ if (word === monster.word) {
+ // Correct word! Defeat monster
+ this.wizard.castSpell();
+ monster.defeat();
+ // Calculate score based on word length and difficulty
+ var scoreIncrease = word.length * 10 * this.difficultyLevel;
+ this.score += scoreIncrease;
+ this.updateScoreDisplay();
+ // Show success message
+ this.owl.speak("Great job! You defeated the monster with your spell!");
+ // Clear collected letters and slots
+ this.collectedLetters = [];
+ for (var i = 0; i < this.wordSlots.length; i++) {
+ this.wordSlots[i].clear();
+ }
+ this.spellButton.setEnabled(false);
+ // Remove monster from array
+ LK.setTimeout(function () {
+ var index = gameState.monsters.indexOf(monster);
+ if (index !== -1) {
+ gameState.monsters.splice(index, 1);
+ }
+ // Spawn next monster after a delay
+ LK.setTimeout(function () {
+ gameState.spawnMonster();
+ }, 2000);
+ }, 1500);
+ } else {
+ // Wrong word
+ LK.effects.flashScreen(0xFF0000, 300);
+ this.owl.speak("Oops! That's not the right spell. Try again!");
+ // Clear collected letters and slots
+ this.collectedLetters = [];
+ for (var i = 0; i < this.wordSlots.length; i++) {
+ this.wordSlots[i].clear();
+ }
+ this.spellButton.setEnabled(false);
+ }
+ }
+ },
+ usePowerup: function usePowerup(powerup) {
+ powerup.collect();
+ if (powerup.type === 'hint') {
+ // Hint powerup - reveal first letter of monster's word
+ if (this.monsters.length > 0) {
+ var monster = this.monsters[0];
+ this.owl.speak("Hint: The first letter is '" + monster.word[0] + "'");
+ }
+ } else if (powerup.type === 'time') {
+ // Time powerup - slow down letters
+ for (var i = 0; i < this.availableLetters.length; i++) {
+ this.availableLetters[i].fallSpeed *= 0.5;
+ }
+ this.owl.speak("Time slowed down!");
+ // Return to normal speed after 10 seconds
+ LK.setTimeout(function () {
+ for (var i = 0; i < gameState.availableLetters.length; i++) {
+ gameState.availableLetters[i].fallSpeed *= 2;
+ }
+ }, 10000);
+ } else if (powerup.type === 'score') {
+ // Score powerup - bonus points
+ this.score += 50;
+ this.updateScoreDisplay();
+ this.owl.speak("Bonus 50 points!");
+ }
+ // Remove from powerups array
+ var index = this.powerups.indexOf(powerup);
+ if (index !== -1) {
+ this.powerups.splice(index, 1);
+ }
+ },
+ updateScoreDisplay: function updateScoreDisplay() {
+ // Update score display
+ scoreTxt.setText("SCORE: " + this.score);
+ // Update high score if needed
+ if (this.score > this.highScore) {
+ this.highScore = this.score;
+ storage.highScore = this.highScore;
+ }
+ },
+ checkCollisions: function checkCollisions() {
+ // Check for letter collisions with wizard
+ for (var i = this.availableLetters.length - 1; i >= 0; i--) {
+ var letter = this.availableLetters[i];
+ if (!letter.isCollected && letter.intersects(this.wizard)) {
+ this.collectLetter(letter);
+ }
+ // Remove letters that fall off screen
+ if (letter.y > 2732 + 50) {
+ letter.destroy();
+ this.availableLetters.splice(i, 1);
+ }
+ }
+ // Check for powerup collisions with wizard
+ for (var j = this.powerups.length - 1; j >= 0; j--) {
+ var powerup = this.powerups[j];
+ if (!powerup.isCollected && powerup.intersects(this.wizard)) {
+ this.usePowerup(powerup);
+ }
+ // Remove powerups that fall off screen
+ if (powerup.y > 2732 + 50) {
+ powerup.destroy();
+ this.powerups.splice(j, 1);
+ }
+ }
+ },
+ checkGameOver: function checkGameOver() {
+ // Game over logic
+ // For example, if all monsters are defeated or time runs out
+ if (this.score >= 500) {
+ this.gameActive = false;
+ // Show you win message
+ this.owl.speak("Congratulations! You've mastered the spell words!");
+ LK.setTimeout(function () {
+ LK.showYouWin();
+ }, 2000);
+ }
+ }
+};
+// Initialize GUI elements
+var scoreTxt = new Text2("SCORE: 0", {
+ size: 70,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Set up level selector UI (for difficulty)
+var levelText = new Text2("LEVEL: " + gameState.difficultyLevel, {
+ size: 40,
+ fill: 0xFFFFFF
+});
+levelText.anchor.set(0, 0);
+levelText.x = 120;
+levelText.y = 20;
+LK.gui.topLeft.addChild(levelText);
+// Level buttons
+var levelDecrease = new Text2("β", {
+ size: 50,
+ fill: 0xFFFFFF
+});
+levelDecrease.anchor.set(0.5, 0.5);
+levelDecrease.x = 350;
+levelDecrease.y = 40;
+levelDecrease.interactive = true;
+levelDecrease.down = function () {
+ if (gameState.difficultyLevel > 1) {
+ gameState.difficultyLevel--;
+ storage.difficultyLevel = gameState.difficultyLevel;
+ levelText.setText("LEVEL: " + gameState.difficultyLevel);
+ }
+};
+LK.gui.topLeft.addChild(levelDecrease);
+var levelIncrease = new Text2("βΆ", {
+ size: 50,
+ fill: 0xFFFFFF
+});
+levelIncrease.anchor.set(0.5, 0.5);
+levelIncrease.x = 400;
+levelIncrease.y = 40;
+levelIncrease.interactive = true;
+levelIncrease.down = function () {
+ if (gameState.difficultyLevel < 3) {
+ gameState.difficultyLevel++;
+ storage.difficultyLevel = gameState.difficultyLevel;
+ levelText.setText("LEVEL: " + gameState.difficultyLevel);
+ }
+};
+LK.gui.topLeft.addChild(levelIncrease);
+// Game event handlers
+game.down = function (x, y, obj) {
+ // Move wizard when clicking/tapping on the game
+ gameState.wizard.moveTo(x);
+};
+game.move = function (x, y, obj) {
+ // If on mobile/touch device, allow dragging the wizard
+ if (obj.isActive) {
+ gameState.wizard.moveTo(x);
+ }
+};
+// Main game loop
+game.update = function () {
+ if (!gameState.gameActive) {
+ return;
+ }
+ // Update all entities
+ if (gameState.wizard) {
+ gameState.wizard.update();
+ }
+ if (gameState.owl) {
+ gameState.owl.update();
+ }
+ // Update available letters
+ for (var i = 0; i < gameState.availableLetters.length; i++) {
+ gameState.availableLetters[i].update();
+ }
+ // Update monsters
+ for (var j = 0; j < gameState.monsters.length; j++) {
+ gameState.monsters[j].update();
+ }
+ // Update powerups
+ for (var k = 0; k < gameState.powerups.length; k++) {
+ gameState.powerups[k].update();
+ }
+ // Check for collisions
+ gameState.checkCollisions();
+ // Check for game over conditions
+ gameState.checkGameOver();
+};
+// Initialize the game state
+gameState.initialize();
\ No newline at end of file