/**** * 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); // Create explosion animation tween(self, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 500, easing: tween.easeOut, 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; } }; self.down = function (x, y, obj) { if (!self.isCollected) { gameState.collectLetter(self); } }; 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: 100, fill: 0x800080, // Bright red color fontWeight: 'bold' // Set font weight to bold }); self.wordDisplay.anchor.set(0.5, 0.5); self.addChild(self.wordDisplay); self.healthDisplay = new Text2('', { 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); self.speak = function (message) { console.log("Owl says: " + message); }; 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 with color change tween(buttonGraphic, { scaleX: 0.95, scaleY: 0.95, tint: 0xFFFF00 // Change color to yellow }, { duration: 100 }); } }; self.up = function (x, y, obj) { if (self.isEnabled) { // Button release effect with color reset tween(buttonGraphic, { scaleX: 1, scaleY: 1, tint: 0xFFFFFF // Reset color to white }, { duration: 100, onFinish: function onFinish() { gameState.castSpell(); } }); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Add background to the game var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 }); background.x = 2048 / 2; background.y = 2732 / 2; game.addChild(background); // Create owl helper function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) { return _arrayLikeToArray(r, a); } var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) { return Array.from(r); } } function _arrayWithoutHoles(r) { if (Array.isArray(r)) { return _arrayLikeToArray(r); } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; } 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', 'BAT', 'JAR', 'PEN', 'RAT', 'BOX'], 2: ['MAGIC', 'SPELL', 'POWER', 'WITCH', 'WAND', 'FAIRY', 'POTION', 'CHARM', 'BOOK', 'MYSTIC', 'GHOST', 'CURSE', 'BROOM', 'ELIXIR', 'WIZARD'], 3: ['WIZARD', 'SORCERER', 'ENCHANTED', 'MAGICAL', 'LEVITATE', 'TRANSFORM', 'VANISHING', 'CONJURE', 'TELEPORT', 'MYSTICAL', 'ILLUSION', 'PHANTOM', 'APPARITION', 'METAMORPHOSIS', 'INCANTATION'] }, // 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.gameActive = true; // Store original word lists for resetting if (!storage.originalWordLists) { storage.originalWordLists = JSON.parse(JSON.stringify(this.wordLists)); } // 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 // Initialize owl this.owl = new Owl(); 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 based on the current monster's word length var currentWordLength = this.monsters[0] ? this.monsters[0].word.length : 8; var slotWidth = 120; var totalWidth = slotWidth * currentWordLength; var startX = (2048 - totalWidth) / 2 + slotWidth / 2; for (var i = 0; i < currentWordLength; 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(); } }, 500); }, 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); }, spawnMonster: function spawnMonster() { var monster = new Monster(); monster.x = 2048 / 2; monster.y = 500; // Choose a word based on difficulty // Reset word list if all words have been used if (this.wordLists[this.difficultyLevel].length === 0) { this.wordLists[this.difficultyLevel] = _toConsumableArray(storage.originalWordLists[this.difficultyLevel]); } var wordList = this.wordLists[this.difficultyLevel]; // Select a random word that hasn't been used yet var randomIndex = Math.floor(Math.random() * wordList.length); var randomWord = wordList.splice(randomIndex, 1)[0]; monster.setWord(randomWord); game.addChild(monster); this.monsters.push(monster); }, 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 // Removed reference to undefined wizard object 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 // Create and display success message in the center of the game var successMessage = new Text2("Great job! You defeated the monster with your spell!", { size: 80, fill: 0xFFFFFF }); successMessage.anchor.set(0.5, 0.5); successMessage.x = 2048 / 2; successMessage.y = 2732 / 2; game.addChild(successMessage); // Hide the message after 3 seconds LK.setTimeout(function () { game.removeChild(successMessage); }, 3000); // 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); // Show 'oops' message var oopsMessage = new Text2("Oops! That's not the right spell.", { size: 80, fill: 0xFF0000 }); oopsMessage.anchor.set(0.5, 0.5); oopsMessage.x = 2048 / 2; oopsMessage.y = 2732 / 2; game.addChild(oopsMessage); // Hide the message after 2 seconds LK.setTimeout(function () { game.removeChild(oopsMessage); }, 2000); // Clear collected letters and slots this.collectedLetters = []; for (var i = 0; i < this.wordSlots.length; i++) { this.wordSlots[i].clear(); } this.spellButton.setEnabled(false); } } }, 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() { // Remove letters that fall off screen for (var i = this.availableLetters.length - 1; i >= 0; i--) { var letter = this.availableLetters[i]; if (letter.y > 2732 + 50) { letter.destroy(); this.availableLetters.splice(i, 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 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); // Main game loop game.update = function () { if (!gameState.gameActive) { return; } // Update all entities // 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(); } // Check for collisions gameState.checkCollisions(); // Check for game over conditions gameState.checkGameOver(); }; // Initialize the game state gameState.initialize();
/****
* 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);
// Create explosion animation
tween(self, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
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;
}
};
self.down = function (x, y, obj) {
if (!self.isCollected) {
gameState.collectLetter(self);
}
};
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: 100,
fill: 0x800080,
// Bright red color
fontWeight: 'bold' // Set font weight to bold
});
self.wordDisplay.anchor.set(0.5, 0.5);
self.addChild(self.wordDisplay);
self.healthDisplay = new Text2('', {
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);
self.speak = function (message) {
console.log("Owl says: " + message);
};
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 with color change
tween(buttonGraphic, {
scaleX: 0.95,
scaleY: 0.95,
tint: 0xFFFF00 // Change color to yellow
}, {
duration: 100
});
}
};
self.up = function (x, y, obj) {
if (self.isEnabled) {
// Button release effect with color reset
tween(buttonGraphic, {
scaleX: 1,
scaleY: 1,
tint: 0xFFFFFF // Reset color to white
}, {
duration: 100,
onFinish: function onFinish() {
gameState.castSpell();
}
});
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Add background to the game
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5
});
background.x = 2048 / 2;
background.y = 2732 / 2;
game.addChild(background);
// Create owl helper
function _toConsumableArray(r) {
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function _iterableToArray(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) {
return Array.from(r);
}
}
function _arrayWithoutHoles(r) {
if (Array.isArray(r)) {
return _arrayLikeToArray(r);
}
}
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
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', 'BAT', 'JAR', 'PEN', 'RAT', 'BOX'],
2: ['MAGIC', 'SPELL', 'POWER', 'WITCH', 'WAND', 'FAIRY', 'POTION', 'CHARM', 'BOOK', 'MYSTIC', 'GHOST', 'CURSE', 'BROOM', 'ELIXIR', 'WIZARD'],
3: ['WIZARD', 'SORCERER', 'ENCHANTED', 'MAGICAL', 'LEVITATE', 'TRANSFORM', 'VANISHING', 'CONJURE', 'TELEPORT', 'MYSTICAL', 'ILLUSION', 'PHANTOM', 'APPARITION', 'METAMORPHOSIS', 'INCANTATION']
},
// 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.gameActive = true;
// Store original word lists for resetting
if (!storage.originalWordLists) {
storage.originalWordLists = JSON.parse(JSON.stringify(this.wordLists));
}
// 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
// Initialize owl
this.owl = new Owl();
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 based on the current monster's word length
var currentWordLength = this.monsters[0] ? this.monsters[0].word.length : 8;
var slotWidth = 120;
var totalWidth = slotWidth * currentWordLength;
var startX = (2048 - totalWidth) / 2 + slotWidth / 2;
for (var i = 0; i < currentWordLength; 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();
}
}, 500);
},
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);
},
spawnMonster: function spawnMonster() {
var monster = new Monster();
monster.x = 2048 / 2;
monster.y = 500;
// Choose a word based on difficulty
// Reset word list if all words have been used
if (this.wordLists[this.difficultyLevel].length === 0) {
this.wordLists[this.difficultyLevel] = _toConsumableArray(storage.originalWordLists[this.difficultyLevel]);
}
var wordList = this.wordLists[this.difficultyLevel];
// Select a random word that hasn't been used yet
var randomIndex = Math.floor(Math.random() * wordList.length);
var randomWord = wordList.splice(randomIndex, 1)[0];
monster.setWord(randomWord);
game.addChild(monster);
this.monsters.push(monster);
},
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
// Removed reference to undefined wizard object
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
// Create and display success message in the center of the game
var successMessage = new Text2("Great job! You defeated the monster with your spell!", {
size: 80,
fill: 0xFFFFFF
});
successMessage.anchor.set(0.5, 0.5);
successMessage.x = 2048 / 2;
successMessage.y = 2732 / 2;
game.addChild(successMessage);
// Hide the message after 3 seconds
LK.setTimeout(function () {
game.removeChild(successMessage);
}, 3000);
// 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);
// Show 'oops' message
var oopsMessage = new Text2("Oops! That's not the right spell.", {
size: 80,
fill: 0xFF0000
});
oopsMessage.anchor.set(0.5, 0.5);
oopsMessage.x = 2048 / 2;
oopsMessage.y = 2732 / 2;
game.addChild(oopsMessage);
// Hide the message after 2 seconds
LK.setTimeout(function () {
game.removeChild(oopsMessage);
}, 2000);
// Clear collected letters and slots
this.collectedLetters = [];
for (var i = 0; i < this.wordSlots.length; i++) {
this.wordSlots[i].clear();
}
this.spellButton.setEnabled(false);
}
}
},
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() {
// Remove letters that fall off screen
for (var i = this.availableLetters.length - 1; i >= 0; i--) {
var letter = this.availableLetters[i];
if (letter.y > 2732 + 50) {
letter.destroy();
this.availableLetters.splice(i, 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
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);
// Main game loop
game.update = function () {
if (!gameState.gameActive) {
return;
}
// Update all entities
// 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();
}
// Check for collisions
gameState.checkCollisions();
// Check for game over conditions
gameState.checkGameOver();
};
// Initialize the game state
gameState.initialize();