User prompt
None of the music is playing fix this
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'happinessBarFill.width = 400 * percentage;' Line Number: 550
User prompt
Please fix the bug: 'TypeError: null is not an object (evaluating 'menuSummer.rotation')' in or related to this line: 'tween(menuSummer, {' Line Number: 366
User prompt
in the menu the dog just floats everywhere in the screen and no boundaries, except for the screen format of the game she cannot go off āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Mega start menu when the game starts with a play button and menu music and the game name raise a summer and the dog summer will be floating around the background doing little flips and just floating around until players press then this main screen war here and also the menu music fades out in the real music, plays āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make food Appear next to the dog and make a eating animation, the food asset āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
The game has some silly humor not too serious Make this
User prompt
Make groom sound
User prompt
After the animation is done, she returns back to where she was āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
She chases toy in play animation and stops when over āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
O Dog says yummy! After eat
User prompt
Make a grooming bush spawn when grooming click then it disappears after animation āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Put command buttons like play eat groom or bathe and tapping them does it
Code edit (1 edits merged)
Please save this source code
User prompt
Summer's Pet Care - Virtual Chihuahua
Initial prompt
Name raise a summer # Summer's Pet Care Game - Expected Details ## Game Overview This is a virtual pet care game featuring "Summer," a Chihuahua that players need to take care of by managing her happiness and hunger levels through various interactions. ## Main Menu - **Background**: Soft pastel pink (0xFFE4E6) - **Title**: "Summer's Pet Care" in bright pink text - **Start Button**: Light green button with "PLAY" text - **Background Music**: Menu music that fades out when starting the game ## Main Game Elements ### Summer (The Pet) - **Appearance**: A brown square representing a brindle-colored Chihuahua - **Position**: Center-bottom of the screen (x: 1024, y: 1600) - **Stats**: - Happiness (0-100, starts at 100) - Hunger (0-100, starts at 100) - **Interactions**: - **Petting**: Tap Summer directly to pet her (+5 happiness, plays bark sound, creates floating heart animation) - **Feeding**: Tap food items to feed Summer (+20 hunger, +10 happiness, plays eat sound) - **Playing**: Drag toys near Summer to play (+15 happiness, plays happy sound) ### UI Elements - **Title**: "Summer the Chihuahua" at the top - **Happiness Bar**: Green bar with background, shows current happiness level - **Hunger Bar**: Orange/red bar with background, shows current hunger level - **Bar Colors**: Change from green ā yellow ā red as levels decrease - **Text Labels**: Display exact happiness and hunger values ### Food Items - **Types**: Treats (small squares) and Bones (rectangles) - **Spawning**: Start with 2 food items, new ones spawn every 30 seconds (max 4 total) - **Interaction**: Tap to feed Summer, then the food disappears - **Positioning**: Random locations in the lower-middle area ### Toys - **Types**: Ball and Stick (different colored squares/rectangles) - **Interaction**: Drag toys around the screen to Summer to initiate play - **Starting Position**: Two toys placed on the lower sides of the screen ### Animations - **Eating**: Summer scales slightly when eating food - **Playing**: Summer bounces up and down with slight rotation when playing with toys - **Hearts**: Floating hearts appear when petting Summer, they float upward while fading out and scaling up - **Menu Transitions**: Smooth fade animations when transitioning from menu to game ### Game Mechanics - **Stat Decay**: - Hunger decreases by 1 every 5 seconds - Happiness decreases by 1 every 10 seconds - If hunger is below 30, happiness decreases faster (by 2 every 5 seconds) - **Game Over**: Occurs when both happiness and hunger reach 0 - **Music**: Background game music plays during gameplay ### Instructions - Text at the bottom explaining: "Tap Summer to pet her! Drag toys to play! Tap food to feed her!" ## Expected Assets The game uses simple geometric shapes as placeholders: - `simple_square`: For Summer, food items, toys, menu elements, and UI bars - `heart`: For the floating heart effect - Various colored versions for different game elements ## Sound Effects - `eat`: Plays when feeding Summer - `happy`: Plays when playing with Summer - `bark`: Plays when petting Summer - `menu_music`: Background music for the start menu - `game_music`: Background music during gameplay The game is designed to be a relaxing, casual pet care experience where players maintain Summer's well-being through simple touch interactions.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ArtBrush = Container.expand(function () { var self = Container.call(this); var brushGraphics = self.attachAsset('brush', { anchorX: 0.5, anchorY: 0.5 }); self.isActive = false; self.activate = function () { self.isActive = true; tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.easeOut }); }; self.deactivate = function () { self.isActive = false; tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 300, easing: tween.easeIn }); }; return self; }); var ArtCanvas = Container.expand(function () { var self = Container.call(this); var canvasGraphics = self.attachAsset('canvas', { anchorX: 0.5, anchorY: 0.5 }); self.strokes = []; self.currentColor = 0x000000; self.currentStrokeAsset = 'paintStrokeBlack'; self.isDrawing = false; self.addStroke = function (x, y) { var stroke = self.addChild(LK.getAsset(self.currentStrokeAsset, { anchorX: 0.5, anchorY: 0.5 })); stroke.x = x; stroke.y = y; self.strokes.push(stroke); // Add paint splash effect tween(stroke, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(stroke, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeIn }); } }); }; self.setColor = function (color) { self.currentColor = color; console.log("Setting color to:", color, "hex:", color.toString(16)); // Map color values to stroke assets if (color === 0xff0000) { self.currentStrokeAsset = 'paintStrokeRed'; } else if (color === 0x00ff00) { self.currentStrokeAsset = 'paintStrokeGreen'; } else if (color === 0x0000ff) { self.currentStrokeAsset = 'paintStrokeBlue'; } else if (color === 0x00ffff) { self.currentStrokeAsset = 'paintStrokeCyan'; } else if (color === 0xffffff) { self.currentStrokeAsset = 'paintStrokeWhite'; } else if (color === 0x000000) { self.currentStrokeAsset = 'paintStrokeBlack'; } else { self.currentStrokeAsset = 'paintStrokeBlack'; console.log("Unknown color, defaulting to black"); } console.log("Current stroke asset set to:", self.currentStrokeAsset); }; self.clearCanvas = function () { for (var i = 0; i < self.strokes.length; i++) { self.strokes[i].destroy(); } self.strokes = []; }; return self; }); var Car = Container.expand(function () { var self = Container.call(this); var carGraphics = self.attachAsset('car', { anchorX: 0.5, anchorY: 0.5 }); self.driveSpeed = 2 + Math.random() * 3; // Random drive speed self.direction = Math.random() < 0.5 ? 1 : -1; // Random initial direction self.lane = Math.random() < 0.5 ? 0 : 1; // Which lane (0 = top, 1 = bottom) // Random car colors var carColors = [0xFF4444, 0x4444FF, 0x44FF44, 0xFFFF44, 0xFF44FF, 0x44FFFF]; carGraphics.tint = carColors[Math.floor(Math.random() * carColors.length)]; self.update = function () { // Move car self.x += self.driveSpeed * self.direction; // Wrap around screen if (self.direction > 0 && self.x > 2100) { self.x = -100; } else if (self.direction < 0 && self.x < -100) { self.x = 2100; } // Add slight engine vibration if (LK.ticks % 10 === 0) { self.y += (Math.random() - 0.5) * 2; } }; return self; }); var CityBuilding = Container.expand(function (buildingType) { var self = Container.call(this); var buildingData = buildingTypes[buildingType]; var buildingGraphics = self.attachAsset('barBackground', { anchorX: 0.5, anchorY: 1.0 }); buildingGraphics.width = 80; buildingGraphics.height = 80; buildingGraphics.tint = buildingData.color; self.buildingType = buildingType; self.population = buildingData.population; self.happiness = buildingData.happiness; // Add construction animation self.constructBuilding = function () { self.scaleX = 0; self.scaleY = 0; tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 500, easing: tween.bounceOut }); }; // Add building info display self.down = function (x, y, obj) { self.showBuildingInfo(); }; self.showBuildingInfo = function () { var infoText = buildingType.toUpperCase(); if (self.population > 0) { infoText += '\nPop: ' + self.population; } if (self.happiness > 0) { infoText += '\nHappy: +' + self.happiness; } var infoDisplay = new Text2(infoText, { size: 30, fill: 0x000000 }); infoDisplay.anchor.set(0.5, 1); infoDisplay.x = self.x; infoDisplay.y = self.y - 100; game.addChild(infoDisplay); tween(infoDisplay, { alpha: 0, y: infoDisplay.y - 50 }, { duration: 2000, easing: tween.easeOut, onFinish: function onFinish() { infoDisplay.destroy(); } }); }; return self; }); var ColorPalette = Container.expand(function () { var self = Container.call(this); self.colors = [0xff0000, 0x00ff00, 0x0000ff, 0x00ffff, 0x000000, 0xffffff]; self.colorAssets = ['colorRed', 'colorGreen', 'colorBlue', 'colorCyan', 'colorBlack', 'colorWhite']; self.colorButtons = []; for (var i = 0; i < self.colors.length; i++) { var colorButton = self.addChild(LK.getAsset(self.colorAssets[i], { anchorX: 0.5, anchorY: 0.5 })); colorButton.x = i % 4 * 100; colorButton.y = Math.floor(i / 4) * 100; colorButton.colorValue = self.colors[i]; colorButton.assetName = self.colorAssets[i]; self.colorButtons.push(colorButton); // Add hover effect with scale animation colorButton.originalScale = 1.0; colorButton.down = function (x, y, obj) { tween(this, { scaleX: 1.2, scaleY: 1.2 }, { duration: 150, easing: tween.easeOut, onFinish: function () { tween(this, { scaleX: 1.0, scaleY: 1.0 }, { duration: 150, easing: tween.easeIn }); }.bind(this) }); }.bind(colorButton); } return self; }); var Food = Container.expand(function () { var self = Container.call(this); var foodGraphics = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5 }); self.down = function (x, y, obj) { self.feed(); }; self.feed = function () { // Create food next to Summer var foodToEat = new Food(); foodToEat.x = summer.x + 60; foodToEat.y = summer.y - 50; game.addChild(foodToEat); // Animate food moving to Summer's mouth and shrinking tween(foodToEat, { x: summer.x, y: summer.y - 80, scaleX: 0.3, scaleY: 0.3 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { // Make food disappear with eating animation tween(foodToEat, { alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { foodToEat.destroy(); } }); } }); hunger = Math.min(100, hunger + 20); happiness = Math.min(100, happiness + 10); updateHungerBar(); updateHappinessBar(); LK.getSound('eat').play(); LK.setTimeout(function () { LK.getSound('yummy').play(); summer.showSpeechBubble("Yummy!"); }, 500); // Remove from foods array var index = foods.indexOf(self); if (index > -1) { foods.splice(index, 1); } self.destroy(); }; return self; }); var GroomBrush = Container.expand(function () { var self = Container.call(this); var brushGraphics = self.attachAsset('groomBrush', { anchorX: 0.5, anchorY: 0.5 }); self.performGrooming = function () { // Start grooming animation - move brush back and forth tween(self, { x: self.x + 50, rotation: 0.3 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { x: self.x - 100, rotation: -0.3 }, { duration: 400, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { x: self.x + 50, rotation: 0, alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); } }); } }); }; return self; }); var Heart = Container.expand(function () { var self = Container.call(this); var heartGraphics = self.attachAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); self.floatUp = function () { tween(self, { y: self.y - 150, alpha: 0 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { if (hearts && hearts.indexOf) { var index = hearts.indexOf(self); if (index > -1) { hearts.splice(index, 1); } } self.destroy(); } }); }; return self; }); var LanaBoss = Container.expand(function () { var self = Container.call(this); var lanaGraphics = self.attachAsset('lana', { anchorX: 0.5, anchorY: 1.0 }); self.health = 100; self.maxHealth = 100; self.moveSpeed = 3; self.direction = 1; self.shootTimer = 0; self.attackPattern = 0; self.isInvulnerable = false; self.update = function () { // Move side to side self.x += self.moveSpeed * self.direction; if (self.x > 1800) { self.direction = -1; } else if (self.x < 248) { self.direction = 1; } // Shooting patterns self.shootTimer++; if (self.shootTimer >= 120) { // Shoot every 2 seconds self.shootBullets(); self.shootTimer = 0; } // Attack pattern changes based on health if (self.health < 50) { self.moveSpeed = 5; } else if (self.health < 25) { self.moveSpeed = 7; } }; self.shootBullets = function () { var bulletCount = self.health > 50 ? 1 : self.health > 25 ? 3 : 5; for (var i = 0; i < bulletCount; i++) { var bullet = new LanaBullet(); bullet.x = self.x + (i - Math.floor(bulletCount / 2)) * 60; bullet.y = self.y - 50; game.addChild(bullet); if (bossFightElements) { bossFightElements.push(bullet); } if (lanaBullets) { lanaBullets.push(bullet); } } LK.getSound('bossFight').play(); }; self.takeDamage = function (amount) { if (self.isInvulnerable) return; self.health -= amount; self.isInvulnerable = true; // Flash red when hit tween(lanaGraphics, { tint: 0xFF0000 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(lanaGraphics, { tint: 0xFFFFFF }, { duration: 200, easing: tween.easeIn }); } }); // Temporary invulnerability LK.setTimeout(function () { self.isInvulnerable = false; }, 500); LK.getSound('bossHit').play(); }; return self; }); var LanaBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('lanaBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.update = function () { self.y += self.speed; }; return self; }); var MemoryCard = Container.expand(function () { var self = Container.call(this); var cardGraphics = self.attachAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 }); cardGraphics.width = 120; cardGraphics.height = 120; cardGraphics.tint = 0x00FF00; //{36} // Bright green self.isFlipped = false; self.cardValue = 0; self.matched = false; var cardText = new Text2('?', { size: 60, fill: 0xFFFFFF }); cardText.anchor.set(0.5, 0.5); cardText.x = 0; cardText.y = 0; self.addChild(cardText); self.flip = function () { if (self.matched || self.isFlipped) return; self.isFlipped = true; cardText.setText(self.cardValue.toString()); tween(self, { scaleX: 0 }, { duration: 150, easing: tween.easeIn, onFinish: function onFinish() { cardGraphics.tint = 0x0080FF; // Bright blue tween(self, { scaleX: 1 }, { duration: 150, easing: tween.easeOut }); } }); }; self.flipBack = function () { if (self.matched) return; self.isFlipped = false; cardText.setText('?'); tween(self, { scaleX: 0 }, { duration: 150, easing: tween.easeIn, onFinish: function onFinish() { cardGraphics.tint = 0x00FF00; //{3x} // Bright green tween(self, { scaleX: 1 }, { duration: 150, easing: tween.easeOut }); } }); }; self.setMatched = function () { self.matched = true; cardGraphics.tint = 0xFFFF00; // Bright yellow/gold tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); }; self.down = function (x, y, obj) { if (!self.matched && !self.isFlipped) { self.flip(); } }; return self; }); var Person = Container.expand(function () { var self = Container.call(this); var personGraphics = self.attachAsset('person', { anchorX: 0.5, anchorY: 1.0 }); self.walkSpeed = 1 + Math.random() * 2; // Random walk speed self.direction = Math.random() < 0.5 ? 1 : -1; // Random initial direction self.targetX = 0; self.isWalking = false; self.startWalking = function () { if (self.isWalking) return; self.isWalking = true; // Set a random target within city area self.targetX = 400 + Math.random() * 1200; // Walking animation - slight bounce function walkBounce() { if (!self.isWalking) return; tween(self, { scaleX: 1.1, scaleY: 0.9 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { scaleX: 0.9, scaleY: 1.1 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { if (self.isWalking) { walkBounce(); } } }); } }); } walkBounce(); }; self.update = function () { if (!self.isWalking) return; // Move towards target if (Math.abs(self.x - self.targetX) > 5) { if (self.x < self.targetX) { self.x += self.walkSpeed; self.scaleX = Math.abs(self.scaleX); // Face right } else { self.x -= self.walkSpeed; self.scaleX = -Math.abs(self.scaleX); // Face left } } else { // Reached target, pick new one self.targetX = 400 + Math.random() * 1200; } // Keep within bounds if (self.x < 300) { self.x = 300; self.targetX = 400 + Math.random() * 800; } else if (self.x > 1700) { self.x = 1700; self.targetX = 600 + Math.random() * 800; } }; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -8; self.update = function () { self.y += self.speed; }; return self; }); var Street = Container.expand(function () { var self = Container.call(this); var streetGraphics = self.attachAsset('street', { anchorX: 0.5, anchorY: 0.5 }); // Add street lines var line1 = self.addChild(LK.getAsset('streetLine', { anchorX: 0.5, anchorY: 0.5 })); line1.x = 0; line1.y = -10; var line2 = self.addChild(LK.getAsset('streetLine', { anchorX: 0.5, anchorY: 0.5 })); line2.x = 0; line2.y = 10; return self; }); var Summer = Container.expand(function () { var self = Container.call(this); var summerGraphics = self.attachAsset('summer', { anchorX: 0.5, anchorY: 1.0 }); self.originalScale = 1.0; self.isAnimating = false; self.down = function (x, y, obj) { if (!self.isAnimating) { self.pet(); } }; self.pet = function () { happiness = Math.min(100, happiness + 5); updateHappinessBar(); LK.getSound('bark').play(); self.createHeart(); self.bounce(); self.showSpeechBubble("Woof!"); }; self.createHeart = function () { var heart = new Heart(); heart.x = self.x + (Math.random() - 0.5) * 100; heart.y = self.y - 50; game.addChild(heart); hearts.push(heart); }; self.bounce = function () { if (self.isAnimating) return; self.isAnimating = true; tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: self.originalScale, scaleY: self.originalScale }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { self.isAnimating = false; } }); } }); }; self.playAnimation = function () { if (self.isAnimating) return; self.isAnimating = true; tween(self, { rotation: 0.2 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { rotation: -0.2 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { rotation: 0 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { self.isAnimating = false; } }); } }); } }); }; self.showSpeechBubble = function (text) { var speechBubble = new Text2(text, { size: 40, fill: 0x000000 }); speechBubble.anchor.set(0.5, 1); speechBubble.x = self.x; speechBubble.y = self.y - summerGraphics.height / 2 - 20; // Position above Summer's head game.addChild(speechBubble); tween(speechBubble, { alpha: 0, y: speechBubble.y - 50 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { speechBubble.destroy(); } }); }; return self; }); var Toy = Container.expand(function () { var self = Container.call(this); var toyGraphics = self.attachAsset('toy', { anchorX: 0.5, anchorY: 0.5 }); self.isDragging = false; self.down = function (x, y, obj) { self.isDragging = true; self.startDragX = x; self.startDragY = y; }; self.checkPlayInteraction = function () { var distance = Math.sqrt(Math.pow(self.x - summer.x, 2) + Math.pow(self.y - summer.y, 2)); if (distance < 150) { happiness = Math.min(100, happiness + 15); updateHappinessBar(); LK.getSound('play').play(); summer.playAnimation(); summer.showSpeechBubble("Zoomies!"); // Remove from toys array var index = toys.indexOf(self); if (index > -1) { toys.splice(index, 1); } self.destroy(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xFFB6C1 }); /**** * Game Code ****/ // Add Array.find polyfill for compatibility if (!Array.prototype.find) { Array.prototype.find = function (predicate) { if (this === null) { throw new TypeError('Array.prototype.find called on null or undefined'); } if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } var list = Object(this); var length = parseInt(list.length) || 0; var thisArg = arguments[1]; var value; for (var i = 0; i < length; i++) { value = list[i]; if (predicate.call(thisArg, value, i, list)) { return value; } } return undefined; }; } var gameState = 'splash'; // 'splash', 'menu', 'playing', 'art', 'minigames', or 'bossfight' // Boss fight variables var bossFightActive = false; var bossFightElements = []; var lanaBoss = null; var playerFighter = null; var playerBullets = []; var lanaBullets = []; var playerHealth = 100; var bossHealthBar = null; var playerHealthBar = null; var shootCooldown = 0; var miniGamesMenuElements = []; var previousGameState = null; var menuSummer = null; var gamePlayElements = []; var happiness = 100; var hunger = 100; var foods = []; var toys = []; var hearts = []; var draggedToy = null; var memoryGameButton = null; var patternGameButton = null; var catchGameButton = null; var popLockGameButton = null; var stackerGameButton = null; var stackerGameActive = false; var stackerGameElements = []; var stackerScore = 0; var stackerLevel = 1; var stackerBlocks = []; var stackerCurrentRow = []; var stackerCurrentLevel = 0; var stackerMovingBlocks = []; var stackerDirection = 1; var stackerSpeed = 2; var stackerIsMoving = false; var stackerTotalLevels = 15; var stackerBlockWidth = 80; var stackerRowWidth = 7; var stackerStartY = 2200; var catchGameActive = false; var catchGameElements = []; var catchScore = 0; var catchTimeLeft = 30; var fallingTreats = []; var summerCatcher = null; var catchGameTimer = 0; var memoryGameElements = []; var memoryCards = []; var flippedCards = []; var memoryGameActive = false; var memoryScore = 0; var memoryMovesCount = 0; var patternGameActive = false; var patternGameElements = []; var patternSequence = []; var playerSequence = []; var patternLevel = 1; var patternScore = 0; var currentPatternIndex = 0; var showingPattern = false; var acceptingInput = false; var patternButtons = []; var popLockGameActive = false; var popLockGameElements = []; var popLockScore = 0; var popLockLevel = 1; var currentLockIndex = 0; var lockIndicators = []; var lockTargetZones = []; var lockMovingIndicator = null; var lockDirection = 1; var lockSpeed = 3; var isLockMoving = false; var locksCompleted = 0; var totalLocks = 3; var summer = null; var happinessBarFill = null; var hungerBarFill = null; var happinessText = null; var hungerText = null; // Art studio mode variables var artCanvas = null; var colorPalette = null; var artBrush = null; var artModeElements = []; var isDrawing = false; var lastDrawX = 0; var lastDrawY = 0; // Create splash screen function createSplashScreen() { // Black background already set in game initialization game.setBackgroundColor(0x000000); // Create logo var logo = game.addChild(LK.getAsset('summerLogo', { anchorX: 0.5, anchorY: 0.5 })); logo.x = 1024; logo.y = 1200; // Create text var splashText = new Text2('Summer Productions Presents', { size: 80, fill: 0xFFFFFF }); splashText.anchor.set(0.5, 0.5); splashText.x = 1024; splashText.y = 1500; game.addChild(splashText); // Fade in animation logo.alpha = 0; splashText.alpha = 0; tween(logo, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); tween(splashText, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); // Music will start when transitioning to menu // After 4 seconds, transition to main menu LK.setTimeout(function () { // Fade out splash screen tween(logo, { alpha: 0 }, { duration: 500, easing: tween.easeInOut }); tween(splashText, { alpha: 0 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { logo.destroy(); splashText.destroy(); gameState = 'menu'; game.setBackgroundColor(0xFFB6C1); // Start music when transitioning to menu LK.playMusic('bgmusic', { loop: true }); createMainMenu(); } }); }, 4000); } // Create main menu function createMainMenu() { // Music will start when title flies in // Game title - start off screen var titleText = new Text2('RAISE A SUMMER', { size: 120, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = -500; // Start off screen left titleText.y = 800; game.addChild(titleText); // Fly in animation tween(titleText, { x: 1024 }, { duration: 1500, easing: tween.easeOut }); // Music already started during splash screen // Add pulsing animation to title function animateTitle() { tween(titleText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(titleText, { scaleX: 1.0, scaleY: 1.0 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { animateTitle(); } } }); } }); } animateTitle(); // Play button var menuPlayButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); menuPlayButton.width = 400; menuPlayButton.height = 150; menuPlayButton.x = 1024; menuPlayButton.y = 1300; menuPlayButton.tint = 0x32CD32; var menuPlayButtonText = new Text2('PLAY', { size: 80, fill: 0xFFFFFF }); menuPlayButtonText.anchor.set(0.5, 0.5); menuPlayButtonText.x = menuPlayButton.x; menuPlayButtonText.y = menuPlayButton.y; game.addChild(menuPlayButtonText); // Art Studio button var menuArtButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); menuArtButton.width = 400; menuArtButton.height = 150; menuArtButton.x = 1024; menuArtButton.y = 1500; menuArtButton.tint = 0x9370DB; var menuArtButtonText = new Text2('ART STUDIO', { size: 70, fill: 0xFFFFFF }); menuArtButtonText.anchor.set(0.5, 0.5); menuArtButtonText.x = menuArtButton.x; menuArtButtonText.y = menuArtButton.y; game.addChild(menuArtButtonText); // Mini Games button var menuMiniGamesButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); menuMiniGamesButton.width = 400; menuMiniGamesButton.height = 150; menuMiniGamesButton.x = 1024; menuMiniGamesButton.y = 1700; menuMiniGamesButton.tint = 0xFF6B35; var menuMiniGamesButtonText = new Text2('MINI GAMES', { size: 70, fill: 0xFFFFFF }); menuMiniGamesButtonText.anchor.set(0.5, 0.5); menuMiniGamesButtonText.x = menuMiniGamesButton.x; menuMiniGamesButtonText.y = menuMiniGamesButton.y; game.addChild(menuMiniGamesButtonText); // City Builder button var menuCityBuilderButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); menuCityBuilderButton.width = 400; menuCityBuilderButton.height = 150; menuCityBuilderButton.x = 1024; menuCityBuilderButton.y = 1900; menuCityBuilderButton.tint = 0x4A90E2; var menuCityBuilderButtonText = new Text2('CITY BUILDER', { size: 70, fill: 0xFFFFFF }); menuCityBuilderButtonText.anchor.set(0.5, 0.5); menuCityBuilderButtonText.x = menuCityBuilderButton.x; menuCityBuilderButtonText.y = menuCityBuilderButton.y; game.addChild(menuCityBuilderButtonText); // Lana Boss Fight button var menuBossFightButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); menuBossFightButton.width = 400; menuBossFightButton.height = 150; menuBossFightButton.x = 1024; menuBossFightButton.y = 2100; menuBossFightButton.tint = 0x8B0000; var menuBossFightButtonText = new Text2('LANA BOSS FIGHT', { size: 70, fill: 0xFFFFFF }); menuBossFightButtonText.anchor.set(0.5, 0.5); menuBossFightButtonText.x = menuBossFightButton.x; menuBossFightButtonText.y = menuBossFightButton.y; game.addChild(menuBossFightButtonText); // Add bouncing animation to menu play button function animateMenuPlayButton() { tween(menuPlayButton, { y: menuPlayButton.y - 20 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuPlayButton, { y: menuPlayButton.y + 20 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { animateMenuPlayButton(); } } }); } }); tween(menuPlayButtonText, { y: menuPlayButtonText.y - 20 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuPlayButtonText, { y: menuPlayButtonText.y + 20 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { animateMenuPlayButton(); } } }); } }); } animateMenuPlayButton(); // Add subtitle var subtitleText = new Text2('Your Virtual Pet Companion', { size: 60, fill: 0xFFB6C1 }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 1024; subtitleText.y = 950; subtitleText.alpha = 0; game.addChild(subtitleText); // Fade in subtitle after a delay LK.setTimeout(function () { if (gameState === 'menu') { tween(subtitleText, { alpha: 1 }, { duration: 1500, easing: tween.easeInOut }); } }, 1000); // Create ten floating Summer characters in background var floatingSummers = []; for (var s = 0; s < 10; s++) { var floatingSummer = game.addChild(new Summer()); floatingSummer.x = Math.random() * 2048; floatingSummer.y = Math.random() * 2732; floatingSummer.alpha = 0.6; // Make them semi-transparent floatingSummer.scaleX = 0.7; // Make them smaller floatingSummer.scaleY = 0.7; floatingSummers.push(floatingSummer); // Start individual floating animation for each Summer startIndividualFloatingAnimation(floatingSummer); } // Store the main menu Summer (keeping original behavior) menuSummer = floatingSummers[0]; // Make the first one more prominent menuSummer.alpha = 1.0; menuSummer.scaleX = 1.0; menuSummer.scaleY = 1.0; // Add floating food decorations var decorativeItems = []; var _loop = function _loop() { decorativeFood = game.addChild(LK.getAsset('food', { anchorX: 0.5, anchorY: 0.5 })); decorativeFood.x = Math.random() * 2048; decorativeFood.y = Math.random() * 2732; decorativeFood.alpha = 0.3; decorativeFood.scaleX = 0.5; decorativeFood.scaleY = 0.5; decorativeItems.push(decorativeFood); // Float around randomly function floatDecoration(item) { tween(item, { x: Math.random() * 2048, y: Math.random() * 2732, rotation: item.rotation + (Math.random() - 0.5) * Math.PI }, { duration: 5000 + Math.random() * 3000, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { floatDecoration(item); } } }); } floatDecoration(decorativeFood); }, decorativeFood; for (var i = 0; i < 8; i++) { _loop(); } // Add bouncing animation to art studio button function animateMenuArtButton() { tween(menuArtButton, { y: menuArtButton.y - 15 }, { duration: 1200, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuArtButton, { y: menuArtButton.y + 15 }, { duration: 1200, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { animateMenuArtButton(); } } }); } }); tween(menuArtButtonText, { y: menuArtButtonText.y - 15 }, { duration: 1200, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuArtButtonText, { y: menuArtButtonText.y + 15 }, { duration: 1200, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { animateMenuArtButton(); } } }); } }); } animateMenuArtButton(); // Add bouncing animation to mini games button function animateMenuMiniGamesButton() { tween(menuMiniGamesButton, { y: menuMiniGamesButton.y - 18 }, { duration: 1100, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuMiniGamesButton, { y: menuMiniGamesButton.y + 18 }, { duration: 1100, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { animateMenuMiniGamesButton(); } } }); } }); tween(menuMiniGamesButtonText, { y: menuMiniGamesButtonText.y - 18 }, { duration: 1100, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuMiniGamesButtonText, { y: menuMiniGamesButtonText.y + 18 }, { duration: 1100, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { animateMenuMiniGamesButton(); } } }); } }); } animateMenuMiniGamesButton(); // Add bouncing animation to city builder button function animateMenuCityBuilderButton() { tween(menuCityBuilderButton, { y: menuCityBuilderButton.y - 22 }, { duration: 1300, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuCityBuilderButton, { y: menuCityBuilderButton.y + 22 }, { duration: 1300, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { animateMenuCityBuilderButton(); } } }); } }); tween(menuCityBuilderButtonText, { y: menuCityBuilderButtonText.y - 22 }, { duration: 1300, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuCityBuilderButtonText, { y: menuCityBuilderButtonText.y + 22 }, { duration: 1300, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { animateMenuCityBuilderButton(); } } }); } }); } animateMenuCityBuilderButton(); // Add bouncing animation to boss fight button function animateMenuBossFightButton() { tween(menuBossFightButton, { y: menuBossFightButton.y - 25 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuBossFightButton, { y: menuBossFightButton.y + 25 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'menu') { animateMenuBossFightButton(); } } }); } }); tween(menuBossFightButtonText, { y: menuBossFightButtonText.y - 25 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuBossFightButtonText, { y: menuBossFightButtonText.y + 25 }, { duration: 1500, easing: tween.easeInOut }); } }); } animateMenuBossFightButton(); // Store menu elements for cleanup gamePlayElements = [titleText, subtitleText, menuPlayButton, menuPlayButtonText, menuArtButton, menuArtButtonText, menuMiniGamesButton, menuMiniGamesButtonText, menuCityBuilderButton, menuCityBuilderButtonText, menuBossFightButton, menuBossFightButtonText].concat(decorativeItems); } function startFloatingAnimation() { if (!menuSummer || gameState !== 'menu') return; // Random floating movement - use full screen dimensions with boundaries // Screen is 2048x2732, leave margin for Summer's size (200px) var margin = 100; var targetX = margin + Math.random() * (2048 - 2 * margin); var targetY = margin + Math.random() * (2732 - 2 * margin); tween(menuSummer, { x: targetX, y: targetY, rotation: (Math.random() - 0.5) * 0.5 }, { duration: 3000 + Math.random() * 2000, easing: tween.easeInOut, onFinish: function onFinish() { // Do a flip if (!menuSummer || gameState !== 'menu') return; tween(menuSummer, { rotation: menuSummer.rotation + Math.PI * 2 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { // Continue floating if (gameState === 'menu') { startFloatingAnimation(); } } }); } }); // Spawn floating hearts around Summer if (Math.random() < 0.3) { var menuHeart = new Heart(); menuHeart.x = menuSummer.x + (Math.random() - 0.5) * 150; menuHeart.y = menuSummer.y + (Math.random() - 0.5) * 150; game.addChild(menuHeart); menuHeart.floatUp(); } } function startIndividualFloatingAnimation(summerChar) { if (!summerChar || gameState !== 'menu') return; // Random floating movement - use full screen dimensions with boundaries // Screen is 2048x2732, leave margin for Summer's size (200px) var margin = 100; var targetX = margin + Math.random() * (2048 - 2 * margin); var targetY = margin + Math.random() * (2732 - 2 * margin); tween(summerChar, { x: targetX, y: targetY, rotation: (Math.random() - 0.5) * 0.5 }, { duration: 4000 + Math.random() * 3000, easing: tween.easeInOut, onFinish: function onFinish() { // Do a gentle rotation if (!summerChar || gameState !== 'menu') return; tween(summerChar, { rotation: summerChar.rotation + (Math.random() - 0.5) * Math.PI }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { // Continue floating startIndividualFloatingAnimation(summerChar); } }); } }); // Occasionally spawn floating hearts around this Summer if (Math.random() < 0.2) { var menuHeart = new Heart(); menuHeart.x = summerChar.x + (Math.random() - 0.5) * 150; menuHeart.y = summerChar.y + (Math.random() - 0.5) * 150; game.addChild(menuHeart); menuHeart.floatUp(); } } function startArtStudio() { // Store previous game state var previousState = gameState; // Remove menu elements if coming from menu if (previousState === 'menu') { for (var i = 0; i < gamePlayElements.length; i++) { gamePlayElements[i].destroy(); } gamePlayElements = []; // Remove all floating summers if (menuSummer) { var children = game.children.slice(); for (var i = 0; i < children.length; i++) { if (children[i] instanceof Summer) { children[i].destroy(); } } menuSummer = null; } } // If coming from gameplay, hide game UI elements but preserve Summer if (previousState === 'playing') { // Hide UI elements but don't destroy them var gameChildren = game.children.slice(); for (var i = 0; i < gameChildren.length; i++) { var child = gameChildren[i]; // Hide everything except Summer and hearts if (!(child instanceof Summer) && !(child instanceof Heart)) { child.visible = false; } } } // Create art studio elements createArtStudio(); gameState = 'art'; } function startMemoryGame() { // Clean up mini games menu for (var i = 0; i < miniGamesMenuElements.length; i++) { miniGamesMenuElements[i].destroy(); } miniGamesMenuElements = []; // Initialize memory game memoryGameActive = true; memoryScore = 0; memoryMovesCount = 0; gameState = 'memory'; // Create game title var memoryTitle = new Text2('MEMORY MATCH', { size: 100, fill: 0x4CAF50 }); memoryTitle.anchor.set(0.5, 0.5); memoryTitle.x = 1024; memoryTitle.y = 300; game.addChild(memoryTitle); memoryGameElements.push(memoryTitle); // Create score display var scoreText = new Text2('Score: 0 | Moves: 0', { size: 60, fill: 0x333333 }); scoreText.anchor.set(0.5, 0.5); scoreText.x = 1024; scoreText.y = 450; game.addChild(scoreText); memoryGameElements.push(scoreText); // Create 4x4 grid of cards var cardValues = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8]; // Shuffle the array for (var i = cardValues.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = cardValues[i]; cardValues[i] = cardValues[j]; cardValues[j] = temp; } var startX = 1024 - 4 * 140 / 2 + 70; var startY = 800; for (var row = 0; row < 4; row++) { for (var col = 0; col < 4; col++) { var card = new MemoryCard(); card.x = startX + col * 140; card.y = startY + row * 140; card.cardValue = cardValues[row * 4 + col]; game.addChild(card); memoryCards.push(card); memoryGameElements.push(card); } } // Create back button var backButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); backButton.width = 200; backButton.height = 80; backButton.x = 1024; backButton.y = 2500; backButton.tint = 0x757575; memoryGameElements.push(backButton); var backButtonText = new Text2('BACK', { size: 50, fill: 0xFFFFFF }); backButtonText.anchor.set(0.5, 0.5); backButtonText.x = backButton.x; backButtonText.y = backButton.y; game.addChild(backButtonText); memoryGameElements.push(backButtonText); } function startPatternGame() { // Clean up mini games menu for (var i = 0; i < miniGamesMenuElements.length; i++) { miniGamesMenuElements[i].destroy(); } miniGamesMenuElements = []; // Initialize pattern game patternGameActive = true; patternLevel = 1; patternScore = 0; patternSequence = []; playerSequence = []; currentPatternIndex = 0; showingPattern = false; acceptingInput = false; gameState = 'pattern'; // Create game title var patternTitle = new Text2('PATTERN REPEAT', { size: 100, fill: 0x2196F3 }); patternTitle.anchor.set(0.5, 0.5); patternTitle.x = 1024; patternTitle.y = 300; game.addChild(patternTitle); patternGameElements.push(patternTitle); // Create score and level display var scoreText = new Text2('Level: 1 | Score: 0', { size: 60, fill: 0x333333 }); scoreText.anchor.set(0.5, 0.5); scoreText.x = 1024; scoreText.y = 450; game.addChild(scoreText); patternGameElements.push(scoreText); // Create instruction text var instructionText = new Text2('Watch the pattern, then repeat it!', { size: 50, fill: 0x666666 }); instructionText.anchor.set(0.5, 0.5); instructionText.x = 1024; instructionText.y = 550; game.addChild(instructionText); patternGameElements.push(instructionText); // Create 4 colored buttons in a 2x2 grid var buttonColors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00]; // Bright Red, Bright Green, Bright Blue, Bright Yellow var buttonSize = 200; var spacing = 250; var startX = 1024 - spacing / 2; var startY = 1200; for (var i = 0; i < 4; i++) { var button = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); button.width = buttonSize; button.height = buttonSize; button.x = startX + i % 2 * spacing; button.y = startY + Math.floor(i / 2) * spacing; button.tint = buttonColors[i]; button.buttonIndex = i; button.originalTint = buttonColors[i]; button.originalScale = 1.0; patternButtons.push(button); patternGameElements.push(button); } // Create back button var backButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); backButton.width = 200; backButton.height = 80; backButton.x = 1024; backButton.y = 2500; backButton.tint = 0x757575; patternGameElements.push(backButton); var backButtonText = new Text2('BACK', { size: 50, fill: 0xFFFFFF }); backButtonText.anchor.set(0.5, 0.5); backButtonText.x = backButton.x; backButtonText.y = backButton.y; game.addChild(backButtonText); patternGameElements.push(backButtonText); // Start first level generateNewPattern(); } function startCatchGame() { // Clean up mini games menu for (var i = 0; i < miniGamesMenuElements.length; i++) { miniGamesMenuElements[i].destroy(); } miniGamesMenuElements = []; // Initialize catch game catchGameActive = true; catchScore = 0; catchTimeLeft = 30; fallingTreats = []; catchGameTimer = 0; gameState = 'catch'; // Create game title var catchTitle = new Text2('CATCH THE TREATS', { size: 100, fill: 0xFF9800 }); catchTitle.anchor.set(0.5, 0.5); catchTitle.x = 1024; catchTitle.y = 300; game.addChild(catchTitle); catchGameElements.push(catchTitle); // Create score and time display var scoreText = new Text2('Score: 0 | Time: 30', { size: 60, fill: 0x333333 }); scoreText.anchor.set(0.5, 0.5); scoreText.x = 1024; scoreText.y = 450; game.addChild(scoreText); catchGameElements.push(scoreText); // Create instruction text var instructionText = new Text2('Move Summer to catch falling treats!', { size: 50, fill: 0x666666 }); instructionText.anchor.set(0.5, 0.5); instructionText.x = 1024; instructionText.y = 550; game.addChild(instructionText); catchGameElements.push(instructionText); // Create Summer catcher at bottom summerCatcher = game.addChild(new Summer()); summerCatcher.x = 1024; summerCatcher.y = 2300; summerCatcher.scaleX = 0.8; summerCatcher.scaleY = 0.8; catchGameElements.push(summerCatcher); // Create back button var backButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); backButton.width = 200; backButton.height = 80; backButton.x = 1024; backButton.y = 2500; backButton.tint = 0x757575; catchGameElements.push(backButton); var backButtonText = new Text2('BACK', { size: 50, fill: 0xFFFFFF }); backButtonText.anchor.set(0.5, 0.5); backButtonText.x = backButton.x; backButtonText.y = backButton.y; game.addChild(backButtonText); catchGameElements.push(backButtonText); } function createMiniGamesMenu() { // Store the previous state so we can return to it previousGameState = gameState; // Remove current menu elements if coming from main menu if (gameState === 'menu') { for (var i = 0; i < gamePlayElements.length; i++) { gamePlayElements[i].destroy(); } gamePlayElements = []; // Remove all floating summers if (menuSummer) { var children = game.children.slice(); for (var i = 0; i < children.length; i++) { if (children[i] instanceof Summer) { children[i].destroy(); } } menuSummer = null; } } // Create title var miniGamesTitle = new Text2('MINI GAMES', { size: 120, fill: 0xFF6B35 }); miniGamesTitle.anchor.set(0.5, 0.5); miniGamesTitle.x = 1024; miniGamesTitle.y = 400; game.addChild(miniGamesTitle); miniGamesMenuElements.push(miniGamesTitle); // Create subtitle var miniGamesSubtitle = new Text2('Choose a fun mini game to play!', { size: 60, fill: 0x333333 }); miniGamesSubtitle.anchor.set(0.5, 0.5); miniGamesSubtitle.x = 1024; miniGamesSubtitle.y = 550; game.addChild(miniGamesSubtitle); miniGamesMenuElements.push(miniGamesSubtitle); // Memory Game button memoryGameButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); memoryGameButton.width = 500; memoryGameButton.height = 150; memoryGameButton.x = 1024; memoryGameButton.y = 800; memoryGameButton.tint = 0x4CAF50; miniGamesMenuElements.push(memoryGameButton); var memoryGameText = new Text2('MEMORY MATCH', { size: 70, fill: 0xFFFFFF }); memoryGameText.anchor.set(0.5, 0.5); memoryGameText.x = memoryGameButton.x; memoryGameText.y = memoryGameButton.y; game.addChild(memoryGameText); miniGamesMenuElements.push(memoryGameText); // Pattern Game button patternGameButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); patternGameButton.width = 500; patternGameButton.height = 150; patternGameButton.x = 1024; patternGameButton.y = 1000; patternGameButton.tint = 0x2196F3; miniGamesMenuElements.push(patternGameButton); var patternGameText = new Text2('PATTERN REPEAT', { size: 70, fill: 0xFFFFFF }); patternGameText.anchor.set(0.5, 0.5); patternGameText.x = patternGameButton.x; patternGameText.y = patternGameButton.y; game.addChild(patternGameText); miniGamesMenuElements.push(patternGameText); // Catch Game button catchGameButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); catchGameButton.width = 500; catchGameButton.height = 150; catchGameButton.x = 1024; catchGameButton.y = 1200; catchGameButton.tint = 0xFF9800; miniGamesMenuElements.push(catchGameButton); var catchGameText = new Text2('CATCH THE TREATS', { size: 70, fill: 0xFFFFFF }); catchGameText.anchor.set(0.5, 0.5); catchGameText.x = catchGameButton.x; catchGameText.y = catchGameButton.y; game.addChild(catchGameText); miniGamesMenuElements.push(catchGameText); // Pop Lock Game button popLockGameButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); popLockGameButton.width = 500; popLockGameButton.height = 150; popLockGameButton.x = 1024; popLockGameButton.y = 1400; popLockGameButton.tint = 0x9C27B0; miniGamesMenuElements.push(popLockGameButton); var popLockGameText = new Text2('POP LOCK', { size: 70, fill: 0xFFFFFF }); popLockGameText.anchor.set(0.5, 0.5); popLockGameText.x = popLockGameButton.x; popLockGameText.y = popLockGameButton.y; game.addChild(popLockGameText); miniGamesMenuElements.push(popLockGameText); // Stacker Game button stackerGameButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); stackerGameButton.width = 500; stackerGameButton.height = 150; stackerGameButton.x = 1024; stackerGameButton.y = 1600; stackerGameButton.tint = 0xFF4500; // Bright orange-red miniGamesMenuElements.push(stackerGameButton); var stackerGameText = new Text2('STACKER', { size: 70, fill: 0xFFFFFF }); stackerGameText.anchor.set(0.5, 0.5); stackerGameText.x = stackerGameButton.x; stackerGameText.y = stackerGameButton.y; game.addChild(stackerGameText); miniGamesMenuElements.push(stackerGameText); // Back button var backToMainButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); backToMainButton.width = 300; backToMainButton.height = 100; backToMainButton.x = 1024; backToMainButton.y = 1800; backToMainButton.tint = 0x757575; miniGamesMenuElements.push(backToMainButton); var backToMainText = new Text2('BACK', { size: 60, fill: 0xFFFFFF }); backToMainText.anchor.set(0.5, 0.5); backToMainText.x = backToMainButton.x; backToMainText.y = backToMainButton.y; game.addChild(backToMainText); miniGamesMenuElements.push(backToMainText); // Add button animations function animateMiniGameButtons() { // Memory button animation if (memoryGameButton && typeof tween === 'function') { tween(memoryGameButton, { scaleX: 1.05, scaleY: 1.05 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { if (memoryGameButton) { tween(memoryGameButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'minigames') { animateMiniGameButtons(); } } }); } } }); } // Pattern button animation (offset timing) LK.setTimeout(function () { if (gameState === 'minigames') { tween(patternGameButton, { scaleX: 1.05, scaleY: 1.05 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(patternGameButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 2000, easing: tween.easeInOut }); } }); } }, 700); // Catch button animation (offset timing) LK.setTimeout(function () { if (gameState === 'minigames') { tween(catchGameButton, { scaleX: 1.05, scaleY: 1.05 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(catchGameButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 2000, easing: tween.easeInOut }); } }); } }, 1400); // Pop Lock button animation (offset timing) LK.setTimeout(function () { if (gameState === 'minigames' && popLockGameButton) { tween(popLockGameButton, { scaleX: 1.05, scaleY: 1.05 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { if (popLockGameButton) { tween(popLockGameButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 2000, easing: tween.easeInOut }); } } }); } }, 2100); // Stacker button animation (offset timing) LK.setTimeout(function () { if (gameState === 'minigames' && stackerGameButton) { tween(stackerGameButton, { scaleX: 1.05, scaleY: 1.05 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { if (stackerGameButton) { tween(stackerGameButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 2000, easing: tween.easeInOut }); } } }); } }, 2800); } animateMiniGameButtons(); gameState = 'minigames'; } function generateNewPattern() { // Add one more button to the sequence var randomButton = Math.floor(Math.random() * 4); patternSequence.push(randomButton); playerSequence = []; currentPatternIndex = 0; // Start showing the pattern after a brief delay LK.setTimeout(function () { showPattern(); }, 1000); } function showPattern() { showingPattern = true; acceptingInput = false; currentPatternIndex = 0; // Update instruction var instructionElement = patternGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Watch the pattern...'); } showNextPatternStep(); } function showNextPatternStep() { if (currentPatternIndex >= patternSequence.length) { // Pattern shown completely, now accept player input showingPattern = false; acceptingInput = true; currentPatternIndex = 0; // Update instruction var instructionElement = patternGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Now repeat the pattern!'); } return; } var buttonIndex = patternSequence[currentPatternIndex]; var button = patternButtons[buttonIndex]; // Highlight button tween(button, { scaleX: 1.2, scaleY: 1.2, tint: 0xFFFFFF }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(button, { scaleX: 1.0, scaleY: 1.0, tint: button.originalTint }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { currentPatternIndex++; LK.setTimeout(function () { showNextPatternStep(); }, 200); } }); } }); } function handlePatternButtonPress(buttonIndex) { if (!acceptingInput || showingPattern) return; var button = patternButtons[buttonIndex]; // Visual feedback for button press tween(button, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(button, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); playerSequence.push(buttonIndex); // Check if this button matches the pattern if (buttonIndex !== patternSequence[playerSequence.length - 1]) { // Wrong button - game over handlePatternGameOver(); return; } // Check if pattern is complete if (playerSequence.length === patternSequence.length) { // Level complete! patternLevel++; patternScore += patternLevel * 10; // Update score display var scoreElement = patternGameElements[1]; if (scoreElement && scoreElement.setText) { scoreElement.setText('Level: ' + patternLevel + ' | Score: ' + patternScore); } // Update instruction var instructionElement = patternGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Great! Get ready for level ' + patternLevel + '...'); } // Start next level after delay LK.setTimeout(function () { generateNewPattern(); }, 1500); } } function handlePatternGameOver() { acceptingInput = false; showingPattern = false; // Update instruction to show game over var instructionElement = patternGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Game Over! Final Score: ' + patternScore); } // Flash all buttons red for (var i = 0; i < patternButtons.length; i++) { var button = patternButtons[i]; tween(button, { tint: 0xFF0000 }, { duration: 200, easing: tween.easeOut, onFinish: function () { tween(this, { tint: this.originalTint }, { duration: 200, easing: tween.easeIn }); }.bind(button) }); } // Allow restart after delay LK.setTimeout(function () { if (instructionElement && instructionElement.setText) { instructionElement.setText('Click any button to play again!'); } // Reset game state for restart patternLevel = 1; patternScore = 0; patternSequence = []; playerSequence = []; acceptingInput = true; // Update score display var scoreElement = patternGameElements[1]; if (scoreElement && scoreElement.setText) { scoreElement.setText('Level: 1 | Score: 0'); } }, 2000); } function startStackerGame() { // Clean up mini games menu for (var i = 0; i < miniGamesMenuElements.length; i++) { miniGamesMenuElements[i].destroy(); } miniGamesMenuElements = []; // Initialize stacker game with simplified variables stackerGameActive = true; stackerScore = 0; stackerCurrentLevel = 1; stackerBlocks = []; // Array to store stationary blocks for each level stackerMovingBlocks = []; // Current moving blocks stackerDirection = 1; stackerSpeed = 3; stackerIsMoving = false; gameState = 'stacker'; // Create game title var stackerTitle = new Text2('STACKER', { size: 100, fill: 0xFF4500 }); stackerTitle.anchor.set(0.5, 0.5); stackerTitle.x = 1024; stackerTitle.y = 300; game.addChild(stackerTitle); stackerGameElements.push(stackerTitle); // Create score and level display var scoreText = new Text2('Level: 1 | Score: 0', { size: 60, fill: 0x333333 }); scoreText.anchor.set(0.5, 0.5); scoreText.x = 1024; scoreText.y = 450; game.addChild(scoreText); stackerGameElements.push(scoreText); // Create instruction text var instructionText = new Text2('Tap to stop the moving blocks!', { size: 50, fill: 0x666666 }); instructionText.anchor.set(0.5, 0.5); instructionText.x = 1024; instructionText.y = 550; game.addChild(instructionText); stackerGameElements.push(instructionText); // Create back button var backButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); backButton.width = 200; backButton.height = 80; backButton.x = 1024; backButton.y = 2500; backButton.tint = 0x757575; stackerGameElements.push(backButton); var backButtonText = new Text2('BACK', { size: 50, fill: 0xFFFFFF }); backButtonText.anchor.set(0.5, 0.5); backButtonText.x = backButton.x; backButtonText.y = backButton.y; game.addChild(backButtonText); stackerGameElements.push(backButtonText); // Create the base foundation row createStackerFoundation(); // Start first level startStackerLevel(); } function createStackerFoundation() { // Create base foundation with 7 blocks var baseY = 2200; var baseBlocks = []; var baseWidth = 7; var blockWidth = 80; var startX = 1024 - baseWidth * blockWidth / 2 + blockWidth / 2; var _loop2 = function _loop2() { function startPopLockGame() { // Clean up mini games menu for (var i = 0; i < miniGamesMenuElements.length; i++) { miniGamesMenuElements[i].destroy(); } miniGamesMenuElements = []; // Initialize pop lock game popLockGameActive = true; popLockScore = 0; popLockLevel = 1; currentLockIndex = 0; lockIndicators = []; lockTargetZones = []; lockMovingIndicator = null; lockDirection = 1; lockSpeed = 3; isLockMoving = false; locksCompleted = 0; totalLocks = 3; gameState = 'poplock'; // Create game title var popLockTitle = new Text2('POP LOCK', { size: 100, fill: 0x9C27B0 }); popLockTitle.anchor.set(0.5, 0.5); popLockTitle.x = 1024; popLockTitle.y = 300; game.addChild(popLockTitle); popLockGameElements.push(popLockTitle); // Create score and level display var scoreText = new Text2('Level: 1 | Score: 0', { size: 60, fill: 0x333333 }); scoreText.anchor.set(0.5, 0.5); scoreText.x = 1024; scoreText.y = 450; game.addChild(scoreText); popLockGameElements.push(scoreText); // Create instruction text var instructionText = new Text2('Click when the indicator hits the target zone!', { size: 50, fill: 0x666666 }); instructionText.anchor.set(0.5, 0.5); instructionText.x = 1024; instructionText.y = 550; game.addChild(instructionText); popLockGameElements.push(instructionText); // Create locks display createPopLockInterface(); // Create back button var backButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); backButton.width = 200; backButton.height = 80; backButton.x = 1024; backButton.y = 2500; backButton.tint = 0x757575; popLockGameElements.push(backButton); var backButtonText = new Text2('BACK', { size: 50, fill: 0xFFFFFF }); backButtonText.anchor.set(0.5, 0.5); backButtonText.x = backButton.x; backButtonText.y = backButton.y; game.addChild(backButtonText); popLockGameElements.push(backButtonText); // Start the first lock startNextLock(); } block = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); block.width = blockWidth; block.height = 40; block.x = startX + i * blockWidth; block.y = baseY; block.tint = 0x4CAF50; // Green foundation stackerGameElements.push(block); baseBlocks.push(block); }, block; for (var i = 0; i < baseWidth; i++) { _loop2(); } stackerBlocks[0] = baseBlocks; // Store foundation as level 0 } function startStackerLevel() { if (stackerCurrentLevel > 10) { // Player reached the top! handleStackerWin(); return; } // Clean up any existing moving blocks for (var i = 0; i < stackerMovingBlocks.length; i++) { stackerMovingBlocks[i].destroy(); } stackerMovingBlocks = []; // Get the width of previous level to determine current level's starting width var previousLevel = stackerCurrentLevel - 1; var previousWidth = stackerBlocks[previousLevel] ? stackerBlocks[previousLevel].length : 7; var currentWidth = Math.max(1, Math.min(previousWidth, 7)); // Ensure at least 1 block, max 7 // Create moving blocks for current level var currentY = 2200 - stackerCurrentLevel * 50; var blockWidth = 80; var startX = 1024 - currentWidth * blockWidth / 2 + blockWidth / 2; // Level colors var levelColors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFA500, 0x800080, 0xFFC0CB, 0x32CD32]; for (var i = 0; i < currentWidth; i++) { var movingBlock = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); movingBlock.width = blockWidth; movingBlock.height = 40; movingBlock.x = startX + i * blockWidth; movingBlock.y = currentY; movingBlock.tint = levelColors[(stackerCurrentLevel - 1) % levelColors.length]; stackerGameElements.push(movingBlock); stackerMovingBlocks.push(movingBlock); } // Start moving stackerIsMoving = true; stackerDirection = 1; stackerSpeed = 3 + stackerCurrentLevel * 0.5; // Increase speed with level } function stopStackerBlocks() { if (!stackerIsMoving || stackerMovingBlocks.length === 0) return; stackerIsMoving = false; // Find the previous level blocks to check alignment var previousLevel = stackerCurrentLevel - 1; var previousBlocks = stackerBlocks[previousLevel]; if (!previousBlocks || previousBlocks.length === 0) { handleStackerGameOver(); return; } // Check which moving blocks align with previous level blocks var alignedBlocks = []; var blockWidth = 80; for (var i = 0; i < stackerMovingBlocks.length; i++) { var movingBlock = stackerMovingBlocks[i]; var isAligned = false; // Check if this moving block overlaps with any previous level block for (var j = 0; j < previousBlocks.length; j++) { var prevBlock = previousBlocks[j]; var overlap = Math.abs(movingBlock.x - prevBlock.x); if (overlap < blockWidth * 0.7) { // 70% overlap required isAligned = true; break; } } if (isAligned) { alignedBlocks.push(movingBlock); // Success animation tween(movingBlock, { scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(movingBlock, { scaleY: 1.0 }, { duration: 200, easing: tween.easeIn }); } }); } else { // Block not aligned - animate it falling tween(movingBlock, { y: movingBlock.y + 400, alpha: 0, rotation: (Math.random() - 0.5) * Math.PI }, { duration: 1000, easing: tween.easeIn, onFinish: function onFinish() { movingBlock.destroy(); } }); } } // Store aligned blocks for this level stackerBlocks[stackerCurrentLevel] = alignedBlocks; // Check if any blocks remain if (alignedBlocks.length === 0) { // Game over - no blocks aligned handleStackerGameOver(); return; } // Update score stackerScore += alignedBlocks.length * stackerCurrentLevel * 10; updateStackerScore(); // Move to next level after delay LK.setTimeout(function () { stackerCurrentLevel++; startStackerLevel(); }, 1000); } function handleStackerGameOver() { stackerGameActive = false; var instructionElement = stackerGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Game Over! Final Score: ' + stackerScore + ' - Tap to restart'); } // Flash remaining blocks red for (var i = 0; i < stackerMovingBlocks.length; i++) { var block = stackerMovingBlocks[i]; tween(block, { tint: 0xFF0000 }, { duration: 300, easing: tween.easeOut }); } } function handleStackerWin() { stackerGameActive = false; var instructionElement = stackerGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('YOU WIN! Perfect Stack! Score: ' + stackerScore + ' - Tap to restart'); } // Celebration animation - make all blocks pulse with gold color for (var level = 0; level < stackerBlocks.length; level++) { if (stackerBlocks[level]) { for (var i = 0; i < stackerBlocks[level].length; i++) { var block = stackerBlocks[level][i]; if (block) { tween(block, { tint: 0xFFD700, scaleX: 1.2, scaleY: 1.2 }, { duration: 500, easing: tween.easeOut, onFinish: function () { tween(this, { scaleX: 1.0, scaleY: 1.0 }, { duration: 500, easing: tween.easeIn }); }.bind(block) }); } } } } } function resetStackerGame() { // Clean up all existing blocks for (var level = 0; level < stackerBlocks.length; level++) { if (stackerBlocks[level]) { for (var i = 0; i < stackerBlocks[level].length; i++) { if (stackerBlocks[level][i]) { stackerBlocks[level][i].destroy(); } } } } for (var i = 0; i < stackerMovingBlocks.length; i++) { stackerMovingBlocks[i].destroy(); } // Reset game variables stackerScore = 0; stackerCurrentLevel = 1; stackerBlocks = []; stackerMovingBlocks = []; stackerDirection = 1; stackerSpeed = 3; stackerIsMoving = false; stackerGameActive = true; // Update score display updateStackerScore(); // Recreate foundation createStackerFoundation(); // Reset instruction var instructionElement = stackerGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Tap to stop the moving blocks!'); } } function updateStackerScore() { var scoreElement = stackerGameElements[1]; if (scoreElement && scoreElement.setText) { scoreElement.setText('Level: ' + stackerCurrentLevel + ' | Score: ' + stackerScore); } } function createPopLockInterface() { // Create 3 lock cylinders vertically arranged var startY = 800; var lockSpacing = 300; for (var i = 0; i < totalLocks; i++) { // Lock cylinder background (bright white circle) var lockCylinder = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); lockCylinder.width = 600; lockCylinder.height = 100; lockCylinder.x = 1024; lockCylinder.y = startY + i * lockSpacing; lockCylinder.tint = 0xFFFFFF; // Bright white popLockGameElements.push(lockCylinder); // Target zone (bright red indicator area) var targetZone = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); targetZone.width = 120; targetZone.height = 80; targetZone.x = 1024 + (Math.random() - 0.5) * 300; // Random position within cylinder targetZone.y = startY + i * lockSpacing; targetZone.tint = 0xFF0000; // Bright red targetZone.visible = false; // Initially hidden popLockGameElements.push(targetZone); lockTargetZones.push(targetZone); // Lock status indicator var lockStatus = new Text2('LOCKED', { size: 40, fill: 0xFF0000 }); lockStatus.anchor.set(0.5, 0.5); lockStatus.x = 1024; lockStatus.y = startY + i * lockSpacing + 70; game.addChild(lockStatus); popLockGameElements.push(lockStatus); lockIndicators.push(lockStatus); } } function startNextLock() { if (currentLockIndex >= totalLocks) { // All locks completed - level complete! handleLevelComplete(); return; } // Show target zone for current lock lockTargetZones[currentLockIndex].visible = true; // Create moving indicator for current lock var startY = 800; var lockSpacing = 300; lockMovingIndicator = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); lockMovingIndicator.width = 20; lockMovingIndicator.height = 80; lockMovingIndicator.x = 1024 - 280; // Start at left edge lockMovingIndicator.y = startY + currentLockIndex * lockSpacing; lockMovingIndicator.tint = 0x00FF00; // Bright green popLockGameElements.push(lockMovingIndicator); // Start moving isLockMoving = true; lockDirection = 1; lockSpeed = 3 + popLockLevel; // Increase speed with level } function handleLockSuccess() { // Lock picked successfully! popLockScore += 10 * popLockLevel; lockIndicators[currentLockIndex].setText('UNLOCKED'); lockIndicators[currentLockIndex].tint = 0x4CAF50; // Hide target zone lockTargetZones[currentLockIndex].visible = false; // Destroy moving indicator if (lockMovingIndicator) { lockMovingIndicator.destroy(); lockMovingIndicator = null; } isLockMoving = false; locksCompleted++; currentLockIndex++; // Update score display var scoreElement = popLockGameElements[1]; if (scoreElement && scoreElement.setText) { scoreElement.setText('Level: ' + popLockLevel + ' | Score: ' + popLockScore); } // Animation for successful lock tween(lockIndicators[currentLockIndex - 1], { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(lockIndicators[currentLockIndex - 1], { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeIn }); } }); // Start next lock after brief delay LK.setTimeout(function () { startNextLock(); }, 500); } function handleLockFailure() { // Lock picking failed! var instructionElement = popLockGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Missed! Try again!'); } // Flash red if (lockMovingIndicator) { tween(lockMovingIndicator, { tint: 0xFF0000 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { if (lockMovingIndicator) { tween(lockMovingIndicator, { tint: 0xFFFF00 }, { duration: 200, easing: tween.easeIn }); } } }); } // Reset instruction after delay LK.setTimeout(function () { var instructionElement = popLockGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Click when the indicator hits the target zone!'); } }, 1500); } function handleLevelComplete() { // All locks completed! popLockLevel++; currentLockIndex = 0; locksCompleted = 0; totalLocks = Math.min(5, 3 + Math.floor(popLockLevel / 2)); // Increase locks with level // Update instruction var instructionElement = popLockGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Level ' + popLockLevel + ' - Get ready!'); } // Reset all lock indicators for (var i = 0; i < lockIndicators.length; i++) { lockIndicators[i].setText('LOCKED'); lockIndicators[i].tint = 0xFF0000; } // Start next level after delay LK.setTimeout(function () { // Clear old interface if we need more locks if (totalLocks > lockIndicators.length) { // Clean up old interface for (var i = 0; i < popLockGameElements.length; i++) { if (popLockGameElements[i] !== popLockGameElements[0] && popLockGameElements[i] !== popLockGameElements[1] && popLockGameElements[i] !== popLockGameElements[2] && popLockGameElements[i] !== popLockGameElements[popLockGameElements.length - 1] && popLockGameElements[i] !== popLockGameElements[popLockGameElements.length - 2]) { popLockGameElements[i].destroy(); } } lockIndicators = []; lockTargetZones = []; // Recreate interface with more locks createPopLockInterface(); } var instructionElement = popLockGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Click when the indicator hits the target zone!'); } startNextLock(); }, 2000); } function checkLockTiming() { if (!isLockMoving || !lockMovingIndicator) return; // Check if indicator is within target zone var targetZone = lockTargetZones[currentLockIndex]; var indicatorX = lockMovingIndicator.x; var targetLeft = targetZone.x - targetZone.width / 2; var targetRight = targetZone.x + targetZone.width / 2; if (indicatorX >= targetLeft && indicatorX <= targetRight) { handleLockSuccess(); } else { handleLockFailure(); } } function spawnTreat() { var treat = game.addChild(LK.getAsset('food', { anchorX: 0.5, anchorY: 0.5 })); treat.x = Math.random() * 1600 + 224; // Keep treats within screen bounds treat.y = 200; treat.fallSpeed = 3 + Math.random() * 4; // Random fall speed between 3-7 treat.caught = false; // Make treats brighter with random bright colors var brightColors = [0xFF6600, 0xFF0066, 0x66FF00, 0x0066FF, 0xFFFF00, 0xFF0000]; treat.tint = brightColors[Math.floor(Math.random() * brightColors.length)]; fallingTreats.push(treat); catchGameElements.push(treat); // Add spawning animation treat.scaleX = 0; treat.scaleY = 0; tween(treat, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.bounceOut }); } function updateCityBuilderUI() { // Update money display if (cityBuilderElements[1] && cityBuilderElements[1].setText) { cityBuilderElements[1].setText('Money: $' + cityMoney); } // Update population display if (cityBuilderElements[2] && cityBuilderElements[2].setText) { cityBuilderElements[2].setText('Population: ' + cityPopulation); } // Update happiness display if (cityBuilderElements[3] && cityBuilderElements[3].setText) { cityBuilderElements[3].setText('Happiness: ' + cityHappiness + '%'); } // Add income based on buildings every few seconds if (LK.ticks % 300 === 0) { // Every 5 seconds var income = 0; for (var i = 0; i < cityBuildings.length; i++) { var building = cityBuildings[i]; if (building.buildingType === 'shop') { income += 10; } else if (building.buildingType === 'office') { income += 15; } else if (building.buildingType === 'house') { income += 5; } } cityMoney += income; if (income > 0) { // Show income notification var incomeText = new Text2('+$' + income, { size: 40, fill: 0x2E8B57 }); incomeText.anchor.set(0, 0.5); incomeText.x = 400; incomeText.y = 400; game.addChild(incomeText); tween(incomeText, { alpha: 0, y: incomeText.y - 50 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { incomeText.destroy(); } }); } } } function updateCatchGameScore() { var scoreElement = catchGameElements[1]; if (scoreElement && scoreElement.setText) { scoreElement.setText('Score: ' + catchScore + ' | Time: ' + catchTimeLeft); } } function handleCatchGameOver() { catchGameActive = false; // Update instruction to show game over var instructionElement = catchGameElements[2]; if (instructionElement && instructionElement.setText) { instructionElement.setText('Game Over! Final Score: ' + catchScore + ' treats caught!'); } // Flash Summer for game over effect if (summerCatcher) { tween(summerCatcher, { tint: 0xFF0000 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(summerCatcher, { tint: 0xFFFFFF }, { duration: 200, easing: tween.easeIn }); } }); } // Allow restart after delay LK.setTimeout(function () { if (instructionElement && instructionElement.setText) { instructionElement.setText('Click BACK to return to menu'); } }, 2000); } function startBossFight() { // Store previous game state var previousState = gameState; // Remove menu elements if coming from menu if (previousState === 'menu') { for (var i = 0; i < gamePlayElements.length; i++) { gamePlayElements[i].destroy(); } gamePlayElements = []; // Remove all floating summers if (menuSummer) { var children = game.children.slice(); for (var i = 0; i < children.length; i++) { if (children[i] instanceof Summer) { children[i].destroy(); } } menuSummer = null; } } // Create boss fight elements createBossFight(); gameState = 'bossfight'; } function createBossFight() { bossFightActive = true; playerHealth = 100; playerBullets = []; lanaBullets = []; shootCooldown = 0; // Create title var bossTitle = new Text2('LANA BOSS FIGHT', { size: 100, fill: 0x8B0000 }); bossTitle.anchor.set(0.5, 0.5); bossTitle.x = 1024; bossTitle.y = 200; game.addChild(bossTitle); bossFightElements.push(bossTitle); // Create boss health bar var bossHealthBg = game.addChild(LK.getAsset('barBackground', { anchorX: 0, anchorY: 0 })); bossHealthBg.x = 624; bossHealthBg.y = 300; bossHealthBg.width = 800; bossHealthBg.height = 50; bossFightElements.push(bossHealthBg); bossHealthBar = game.addChild(LK.getAsset('bossHealthBar', { anchorX: 0, anchorY: 0 })); bossHealthBar.x = 624; bossHealthBar.y = 300; bossFightElements.push(bossHealthBar); var bossHealthText = new Text2('LANA HEALTH', { size: 40, fill: 0xFFFFFF }); bossHealthText.anchor.set(0.5, 0.5); bossHealthText.x = 1024; bossHealthText.y = 280; game.addChild(bossHealthText); bossFightElements.push(bossHealthText); // Create player health bar var playerHealthBg = game.addChild(LK.getAsset('barBackground', { anchorX: 0, anchorY: 0 })); playerHealthBg.x = 200; playerHealthBg.y = 150; playerHealthBg.width = 400; playerHealthBg.height = 40; bossFightElements.push(playerHealthBg); playerHealthBar = game.addChild(LK.getAsset('playerHealthBar', { anchorX: 0, anchorY: 0 })); playerHealthBar.x = 200; playerHealthBar.y = 150; bossFightElements.push(playerHealthBar); var playerHealthText = new Text2('PLAYER HEALTH', { size: 40, fill: 0xFFFFFF }); playerHealthText.anchor.set(0, 0.5); playerHealthText.x = 650; playerHealthText.y = 170; game.addChild(playerHealthText); bossFightElements.push(playerHealthText); // Create Lana boss lanaBoss = new LanaBoss(); lanaBoss.x = 1024; lanaBoss.y = 600; game.addChild(lanaBoss); bossFightElements.push(lanaBoss); // Create player fighter (Summer) playerFighter = new Summer(); playerFighter.x = 1024; playerFighter.y = 2300; playerFighter.scaleX = 0.8; playerFighter.scaleY = 0.8; game.addChild(playerFighter); bossFightElements.push(playerFighter); // Create instructions var instructions = new Text2('Move with touch/drag, tap to shoot!', { size: 50, fill: 0x333333 }); instructions.anchor.set(0.5, 0.5); instructions.x = 1024; instructions.y = 2600; game.addChild(instructions); bossFightElements.push(instructions); // Create shoot button in bottom right corner var shootButton = game.addChild(LK.getAsset('shootButton', { anchorX: 0.5, anchorY: 0.5 })); shootButton.x = 1900; shootButton.y = 2500; bossFightElements.push(shootButton); var shootButtonText = new Text2('SHOOT', { size: 40, fill: 0xFFFFFF }); shootButtonText.anchor.set(0.5, 0.5); shootButtonText.x = shootButton.x; shootButtonText.y = shootButton.y; game.addChild(shootButtonText); bossFightElements.push(shootButtonText); // Add pulsing animation to shoot button function animateShootButton() { tween(shootButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(shootButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'bossfight') { animateShootButton(); } } }); } }); } animateShootButton(); // Create back button var backButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); backButton.width = 200; backButton.height = 80; backButton.x = 150; backButton.y = 2650; backButton.tint = 0x757575; bossFightElements.push(backButton); var backButtonText = new Text2('BACK', { size: 50, fill: 0xFFFFFF }); backButtonText.anchor.set(0.5, 0.5); backButtonText.x = backButton.x; backButtonText.y = backButton.y; game.addChild(backButtonText); bossFightElements.push(backButtonText); } function startCityBuilder() { // Store previous game state var previousState = gameState; // Remove menu elements if coming from menu if (previousState === 'menu') { for (var i = 0; i < gamePlayElements.length; i++) { gamePlayElements[i].destroy(); } gamePlayElements = []; // Remove all floating summers if (menuSummer) { var children = game.children.slice(); for (var i = 0; i < children.length; i++) { if (children[i] instanceof Summer) { children[i].destroy(); } } menuSummer = null; } } // Create city builder elements createCityBuilder(); gameState = 'citybuilder'; } function createCityBuilder() { cityBuilderActive = true; // Create title var cityTitle = new Text2('CITY BUILDER', { size: 100, fill: 0x4A90E2 }); cityTitle.anchor.set(0.5, 0.5); cityTitle.x = 1024; cityTitle.y = 200; game.addChild(cityTitle); cityBuilderElements.push(cityTitle); // Create resource display var moneyText = new Text2('Money: $' + cityMoney, { size: 60, fill: 0x2E8B57 }); moneyText.anchor.set(0, 0.5); moneyText.x = 100; moneyText.y = 400; game.addChild(moneyText); cityBuilderElements.push(moneyText); var popText = new Text2('Population: ' + cityPopulation, { size: 60, fill: 0x4169E1 }); popText.anchor.set(0, 0.5); popText.x = 100; popText.y = 500; game.addChild(popText); cityBuilderElements.push(popText); var happyText = new Text2('Happiness: ' + cityHappiness + '%', { size: 60, fill: 0xFF6347 }); happyText.anchor.set(0, 0.5); happyText.x = 100; happyText.y = 600; game.addChild(happyText); cityBuilderElements.push(happyText); // Create building selection buttons var buildingNames = ['house', 'shop', 'park', 'office', 'street']; var buildingLabels = ['HOUSE ($100)', 'SHOP ($200)', 'PARK ($150)', 'OFFICE ($300)', 'STREET ($50)']; for (var i = 0; i < buildingNames.length; i++) { var button = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); button.width = 175; // Slightly smaller to fit 5 buttons button.height = 80; button.x = 150 + i * 175; // Adjusted spacing button.y = 800; button.tint = buildingTypes[buildingNames[i]].color; button.buildingType = buildingNames[i]; cityBuilderElements.push(button); var buttonText = new Text2(buildingLabels[i], { size: 30, // Slightly smaller text fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); buttonText.x = button.x; buttonText.y = button.y; game.addChild(buttonText); cityBuilderElements.push(buttonText); } // Create building area var buildingArea = game.addChild(LK.getAsset('canvas', { anchorX: 0.5, anchorY: 0.5 })); buildingArea.x = 1024; buildingArea.y = 1600; buildingArea.alpha = 0.3; buildingArea.width = 1400; buildingArea.height = 1000; cityBuilderElements.push(buildingArea); // Create instructions var instructions = new Text2('Select a building type above, then click in the city area to build!', { size: 50, fill: 0x333333 }); instructions.anchor.set(0.5, 0.5); instructions.x = 1024; instructions.y = 950; game.addChild(instructions); cityBuilderElements.push(instructions); // Create back button var backButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); backButton.width = 200; backButton.height = 80; backButton.x = 1024; backButton.y = 2600; backButton.tint = 0x757575; cityBuilderElements.push(backButton); var backButtonText = new Text2('BACK', { size: 50, fill: 0xFFFFFF }); backButtonText.anchor.set(0.5, 0.5); backButtonText.x = backButton.x; backButtonText.y = backButton.y; game.addChild(backButtonText); cityBuilderElements.push(backButtonText); } function createArtStudio() { // Create title var artTitle = new Text2('ART STUDIO', { size: 100, fill: 0x4B0082 }); artTitle.anchor.set(0.5, 0.5); artTitle.x = 1024; artTitle.y = 200; game.addChild(artTitle); artModeElements.push(artTitle); // Create canvas artCanvas = game.addChild(new ArtCanvas()); artCanvas.x = 1024; artCanvas.y = 1200; artModeElements.push(artCanvas); // Create color palette colorPalette = game.addChild(new ColorPalette()); colorPalette.x = 200; colorPalette.y = 600; artModeElements.push(colorPalette); // Create brush artBrush = game.addChild(new ArtBrush()); if (artBrush) { artBrush.x = 200; artBrush.y = 400; artBrush.activate(); artModeElements.push(artBrush); } // Create or reposition Summer in art mode if (!summer) { summer = game.addChild(new Summer()); artModeElements.push(summer); } summer.x = 1800; summer.y = 800; summer.scaleX = 0.8; summer.scaleY = 0.8; summer.visible = true; // Ensure Summer appears in front of canvas game.removeChild(summer); game.addChild(summer); // Add art studio buttons var backButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); backButton.width = 200; backButton.height = 80; backButton.x = 150; backButton.y = 2600; backButton.tint = 0x808080; artModeElements.push(backButton); var backButtonText = new Text2('BACK', { size: 40, fill: 0xFFFFFF }); backButtonText.anchor.set(0.5, 0.5); backButtonText.x = backButton.x; backButtonText.y = backButton.y; game.addChild(backButtonText); artModeElements.push(backButtonText); var clearButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); clearButton.width = 200; clearButton.height = 80; clearButton.x = 400; clearButton.y = 2600; clearButton.tint = 0xff4444; artModeElements.push(clearButton); var clearButtonText = new Text2('CLEAR', { size: 40, fill: 0xFFFFFF }); clearButtonText.anchor.set(0.5, 0.5); clearButtonText.x = clearButton.x; clearButtonText.y = clearButton.y; game.addChild(clearButtonText); artModeElements.push(clearButtonText); // Add instructions var instructions = new Text2('Tap colors to change brush, draw on canvas!', { size: 45, fill: 0x333333 }); instructions.anchor.set(0.5, 0.5); instructions.x = 1024; instructions.y = 2650; game.addChild(instructions); artModeElements.push(instructions); } function startGame() { // Music already playing - no transition needed // Remove menu elements for (var i = 0; i < gamePlayElements.length; i++) { gamePlayElements[i].destroy(); } gamePlayElements = []; // Remove all floating summers if (menuSummer) { // Find and destroy all Summer instances in the game var children = game.children.slice(); // Create a copy to iterate safely for (var i = 0; i < children.length; i++) { if (children[i] instanceof Summer) { children[i].destroy(); } } menuSummer = null; } // Create game Summer summer = game.addChild(new Summer()); summer.x = 1024; summer.y = 2200; // Create game UI and elements createGameUI(); gameState = 'playing'; } function createGameUI() { // Create UI bars var happinessBarBg = game.addChild(LK.getAsset('barBackground', { anchorX: 0, anchorY: 0 })); happinessBarBg.x = 200; happinessBarBg.y = 150; happinessBarFill = game.addChild(LK.getAsset('happinessBar', { anchorX: 0, anchorY: 0 })); happinessBarFill.x = 200; happinessBarFill.y = 150; var hungerBarBg = game.addChild(LK.getAsset('barBackground', { anchorX: 0, anchorY: 0 })); hungerBarBg.x = 200; hungerBarBg.y = 250; hungerBarFill = game.addChild(LK.getAsset('hungerBar', { anchorX: 0, anchorY: 0 })); hungerBarFill.x = 200; hungerBarFill.y = 250; // Create UI text happinessText = new Text2('Happiness: 100', { size: 50, fill: 0x000000 }); happinessText.anchor.set(0, 0.5); happinessText.x = 650; happinessText.y = 170; game.addChild(happinessText); hungerText = new Text2('Hunger: 100', { size: 50, fill: 0x000000 }); hungerText.anchor.set(0, 0.5); hungerText.x = 650; hungerText.y = 270; game.addChild(hungerText); var instructionText = new Text2('Use buttons below to care for Summer!', { size: 40, fill: 0x333333 }); instructionText.anchor.set(0.5, 1); instructionText.x = 1024; instructionText.y = 2680; game.addChild(instructionText); // Create command buttons var buttonWidth = 300; var buttonHeight = 120; var buttonY = 2400; var buttonSpacing = 400; // Store button references globally window.petButton = null; window.feedButton = null; window.playButton = null; window.groomButton = null; // Pet button var petButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); petButton.width = buttonWidth; petButton.height = buttonHeight; petButton.x = 300; petButton.y = buttonY; petButton.tint = 0xFF69B4; window.petButton = petButton; // Add gentle pulsing animation to pet button function animatePetButton() { tween(petButton, { scaleX: 1.05, scaleY: 1.05 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { tween(petButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'playing') { animatePetButton(); } } }); } }); } animatePetButton(); var petButtonText = new Text2('PET', { size: 50, fill: 0xFFFFFF }); petButtonText.anchor.set(0.5, 0.5); petButtonText.x = petButton.x; petButtonText.y = petButton.y; game.addChild(petButtonText); // Feed button var feedButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); feedButton.width = buttonWidth; feedButton.height = buttonHeight; feedButton.x = 700; feedButton.y = buttonY; feedButton.tint = 0x32CD32; window.feedButton = feedButton; // Add floating animation to feed button function animateFeedButton() { tween(feedButton, { y: buttonY - 10, rotation: 0.05 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(feedButton, { y: buttonY, rotation: -0.05 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'playing') { animateFeedButton(); } } }); } }); } animateFeedButton(); var feedButtonText = new Text2('FEED', { size: 50, fill: 0xFFFFFF }); feedButtonText.anchor.set(0.5, 0.5); feedButtonText.x = feedButton.x; feedButtonText.y = feedButton.y; game.addChild(feedButtonText); // Play button var playButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); playButton.width = buttonWidth; playButton.height = buttonHeight; playButton.x = 1100; playButton.y = buttonY; playButton.tint = 0x4169E1; window.playButton = playButton; var playButtonText = new Text2('PLAY', { size: 50, fill: 0xFFFFFF }); playButtonText.anchor.set(0.5, 0.5); playButtonText.x = playButton.x; playButtonText.y = playButton.y; game.addChild(playButtonText); // Groom button var groomButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); groomButton.width = buttonWidth; groomButton.height = buttonHeight; groomButton.x = 1500; groomButton.y = buttonY; groomButton.tint = 0x9370DB; window.groomButton = groomButton; // Add wobble animation to play button var _animatePlayButton = function animatePlayButton() { tween(playButton, { rotation: 0.1, scaleX: 1.02, scaleY: 1.02 }, { duration: 1200, easing: tween.easeInOut, onFinish: function onFinish() { tween(playButton, { rotation: -0.1, scaleX: 0.98, scaleY: 0.98 }, { duration: 1200, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'playing') { _animatePlayButton(); } } }); } }); }; _animatePlayButton(); var groomButtonText = new Text2('GROOM', { size: 50, fill: 0xFFFFFF }); groomButtonText.anchor.set(0.5, 0.5); groomButtonText.x = groomButton.x; groomButtonText.y = groomButton.y; game.addChild(groomButtonText); // Add gentle shake animation to groom button function animateGroomButton() { tween(groomButton, { x: 1500 + 5, rotation: 0.08 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(groomButton, { x: 1500 - 5, rotation: -0.08 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(groomButton, { x: 1500, rotation: 0 }, { duration: 400, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'playing') { LK.setTimeout(function () { animateGroomButton(); }, 2000); } } }); } }); } }); } animateGroomButton(); // Back to Menu button var backToMenuButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); backToMenuButton.width = 200; backToMenuButton.height = 80; backToMenuButton.x = 800; backToMenuButton.y = 2580; backToMenuButton.tint = 0x757575; window.backToMenuButton = backToMenuButton; var backToMenuButtonText = new Text2('MENU', { size: 40, fill: 0xFFFFFF }); backToMenuButtonText.anchor.set(0.5, 0.5); backToMenuButtonText.x = backToMenuButton.x; backToMenuButtonText.y = backToMenuButton.y; game.addChild(backToMenuButtonText); // Art Studio button var artStudioButton = game.addChild(LK.getAsset('barBackground', { anchorX: 0.5, anchorY: 0.5 })); artStudioButton.width = 200; artStudioButton.height = 80; artStudioButton.x = 1250; artStudioButton.y = 2580; artStudioButton.tint = 0x9370DB; window.artStudioButton = artStudioButton; var artStudioButtonText = new Text2('ART', { size: 40, fill: 0xFFFFFF }); artStudioButtonText.anchor.set(0.5, 0.5); artStudioButtonText.x = artStudioButton.x; artStudioButtonText.y = artStudioButton.y; game.addChild(artStudioButtonText); // Add gentle pulse animation to back to menu button function animateBackToMenuButton() { tween(backToMenuButton, { scaleX: 1.03, scaleY: 1.03 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(backToMenuButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'playing') { animateBackToMenuButton(); } } }); } }); tween(backToMenuButtonText, { scaleX: 1.03, scaleY: 1.03 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(backToMenuButtonText, { scaleX: 1.0, scaleY: 1.0 }, { duration: 2000, easing: tween.easeInOut }); } }); } animateBackToMenuButton(); // Add floating animation to art studio button function animateArtStudioButton() { tween(artStudioButton, { y: 2570, scaleX: 1.05, scaleY: 1.05 }, { duration: 1400, easing: tween.easeInOut, onFinish: function onFinish() { tween(artStudioButton, { y: 2580, scaleX: 1.0, scaleY: 1.0 }, { duration: 1400, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'playing') { animateArtStudioButton(); } } }); } }); tween(artStudioButtonText, { y: 2570 }, { duration: 1400, easing: tween.easeInOut, onFinish: function onFinish() { tween(artStudioButtonText, { y: 2580 }, { duration: 1400, easing: tween.easeInOut, onFinish: function onFinish() { if (gameState === 'playing') { animateArtStudioButton(); } } }); } }); } animateArtStudioButton(); // Initial spawn spawnFood(); spawnToy(); } // Timers var hungerTimer = 0; var happinessTimer = 0; var foodSpawnTimer = 0; var toySpawnTimer = 0; // City Builder mode variables var cityBuilderActive = false; var cityBuilderElements = []; var cityBuildings = []; var cityMoney = 1000; var cityPopulation = 0; var cityHappiness = 50; var selectedBuildingType = 'house'; var buildingTypes = { house: { cost: 100, color: 0x8B4513, population: 4, happiness: 2 }, shop: { cost: 200, color: 0x32CD32, population: 0, happiness: 5 }, park: { cost: 150, color: 0x228B22, population: 0, happiness: 8 }, office: { cost: 300, color: 0x708090, population: 0, happiness: 1 }, street: { cost: 50, color: 0x2F2F2F, population: 0, happiness: 1 } }; // City people and cars var cityPeople = []; var cityCars = []; var cityStreets = []; // Initialize splash screen createSplashScreen(); // Background music already playing function updateHappinessBar() { var percentage = happiness / 100; if (happinessBarFill) { // Stop any existing tween on the bar tween.stop(happinessBarFill, { width: true }); // Animate the bar width change tween(happinessBarFill, { width: 400 * percentage }, { duration: 500, easing: tween.easeOut }); // Add a brief pulse effect tween(happinessBarFill, { scaleY: 1.2 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(happinessBarFill, { scaleY: 1.0 }, { duration: 150, easing: tween.easeIn }); } }); if (happiness > 60) { happinessBarFill.tint = 0x00FF00; } else if (happiness > 30) { happinessBarFill.tint = 0xFFFF00; } else { happinessBarFill.tint = 0xFF0000; } } if (happinessText) { happinessText.setText('Happiness: ' + happiness); // Add text bounce effect tween(happinessText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(happinessText, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeIn }); } }); } } function updateHungerBar() { var percentage = hunger / 100; if (hungerBarFill) { // Stop any existing tween on the bar tween.stop(hungerBarFill, { width: true }); // Animate the bar width change tween(hungerBarFill, { width: 400 * percentage }, { duration: 500, easing: tween.easeOut }); // Add a brief pulse effect tween(hungerBarFill, { scaleY: 1.2 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(hungerBarFill, { scaleY: 1.0 }, { duration: 150, easing: tween.easeIn }); } }); if (hunger > 60) { hungerBarFill.tint = 0x00FF00; } else if (hunger > 30) { hungerBarFill.tint = 0xFFFF00; } else { hungerBarFill.tint = 0xFF0000; } } if (hungerText) { hungerText.setText('Hunger: ' + hunger); // Add text bounce effect tween(hungerText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(hungerText, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeIn }); } }); } } function spawnFood() { if (foods.length < 4) { var food = new Food(); food.x = Math.random() * 1800 + 124; food.y = Math.random() * 1000 + 400; foods.push(food); game.addChild(food); // Start with food invisible and small food.alpha = 0; food.scaleX = 0; food.scaleY = 0; // Animate food appearing with bounce effect tween(food, { alpha: 1, scaleX: 1.3, scaleY: 1.3 }, { duration: 300, easing: tween.bounceOut, onFinish: function onFinish() { tween(food, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut }); } }); } } function spawnToy() { if (toys.length < 2) { var toy = new Toy(); toy.x = Math.random() * 1800 + 124; toy.y = Math.random() * 1000 + 400; toys.push(toy); game.addChild(toy); // Start with toy invisible and small toy.alpha = 0; toy.scaleX = 0; toy.scaleY = 0; // Animate toy appearing with elastic effect tween(toy, { alpha: 1, scaleX: 1.2, scaleY: 1.2 }, { duration: 400, easing: tween.elasticOut, onFinish: function onFinish() { tween(toy, { scaleX: 1.0, scaleY: 1.0 }, { duration: 300, easing: tween.easeOut }); } }); } } game.move = function (x, y, obj) { if (gameState === 'art' && isDrawing && artCanvas) { // Continue drawing on canvas if (x >= 224 && x <= 1824 && y >= 600 && y <= 1800) { var localX = x - artCanvas.x; var localY = y - artCanvas.y; artCanvas.addStroke(localX, localY); // Play brush sound occasionally while drawing if (Math.random() < 0.3) { LK.getSound('paintbrush').play(); } } } if (gameState === 'catch' && summerCatcher) { // Move Summer catcher horizontally only, keep at bottom summerCatcher.x = Math.max(100, Math.min(1948, x)); // Keep Summer within screen bounds } if (gameState === 'bossfight' && playerFighter) { // Move player fighter horizontally only, keep at bottom playerFighter.x = Math.max(100, Math.min(1948, x)); } if (draggedToy) { draggedToy.x = x; draggedToy.y = y; } }; game.down = function (x, y, obj) { // Handle menu state if (gameState === 'menu') { // Check for play button click (centered at 1024, 1300) if (x >= 824 && x <= 1224 && y >= 1225 && y <= 1375) { startGame(); return; } // Check for art studio button click (centered at 1024, 1500) if (x >= 824 && x <= 1224 && y >= 1425 && y <= 1575) { startArtStudio(); return; } // Check for mini games button click (centered at 1024, 1700) if (x >= 824 && x <= 1224 && y >= 1625 && y <= 1775) { createMiniGamesMenu(); return; } // Check for city builder button click (centered at 1024, 1900) if (x >= 824 && x <= 1224 && y >= 1825 && y <= 1975) { startCityBuilder(); return; } // Check for boss fight button click (centered at 1024, 2100) if (x >= 824 && x <= 1224 && y >= 2025 && y <= 2175) { startBossFight(); return; } return; } // Handle mini games menu state if (gameState === 'minigames') { // Check back button (1024, 1800) if (x >= 874 && x <= 1174 && y >= 1750 && y <= 1850) { // Clean up mini games menu for (var i = 0; i < miniGamesMenuElements.length; i++) { miniGamesMenuElements[i].destroy(); } miniGamesMenuElements = []; // Return to main menu gameState = 'menu'; createMainMenu(); return; } // Check Memory Game button (1024, 800) if (x >= 774 && x <= 1274 && y >= 725 && y <= 875) { // Add click animation tween(memoryGameButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(memoryGameButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); // Start Memory Game LK.setTimeout(function () { startMemoryGame(); }, 200); return; } // Check Pattern Game button (1024, 1000) if (x >= 774 && x <= 1274 && y >= 925 && y <= 1075) { // Add click animation tween(patternGameButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(patternGameButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); // Start Pattern Game LK.setTimeout(function () { startPatternGame(); }, 200); return; } // Check Catch Game button (1024, 1200) if (x >= 774 && x <= 1274 && y >= 1125 && y <= 1275) { // Add click animation tween(catchGameButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(catchGameButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); // Start Catch Game LK.setTimeout(function () { startCatchGame(); }, 200); return; } // Check Pop Lock Game button (1024, 1400) if (x >= 774 && x <= 1274 && y >= 1325 && y <= 1475) { // Add click animation tween(popLockGameButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(popLockGameButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); // Start Pop Lock Game LK.setTimeout(function () { startPopLockGame(); }, 200); return; } // Check Stacker Game button (1024, 1600) if (x >= 774 && x <= 1274 && y >= 1525 && y <= 1675) { // Add click animation tween(stackerGameButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(stackerGameButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); // Start Stacker Game LK.setTimeout(function () { startStackerGame(); }, 200); return; } return; } // Handle memory game state if (gameState === 'memory') { // Check back button (1024, 2500) if (x >= 924 && x <= 1124 && y >= 2460 && y <= 2540) { // Clean up memory game for (var i = 0; i < memoryGameElements.length; i++) { memoryGameElements[i].destroy(); } memoryGameElements = []; memoryCards = []; flippedCards = []; memoryGameActive = false; // Return to mini games menu createMiniGamesMenu(); return; } return; } // Handle pattern game state if (gameState === 'pattern') { // Check back button (1024, 2500) if (x >= 924 && x <= 1124 && y >= 2460 && y <= 2540) { // Clean up pattern game for (var i = 0; i < patternGameElements.length; i++) { patternGameElements[i].destroy(); } patternGameElements = []; patternButtons = []; patternGameActive = false; // Return to mini games menu createMiniGamesMenu(); return; } // Check pattern button clicks if (patternButtons && patternButtons.length > 0) { var buttonSize = 200; var spacing = 250; var startX = 1024 - spacing / 2; var startY = 1200; for (var i = 0; i < 4; i++) { var buttonX = startX + i % 2 * spacing; var buttonY = startY + Math.floor(i / 2) * spacing; if (x >= buttonX - buttonSize / 2 && x <= buttonX + buttonSize / 2 && y >= buttonY - buttonSize / 2 && y <= buttonY + buttonSize / 2) { if (acceptingInput && !showingPattern) { handlePatternButtonPress(i); } else if (!patternGameActive || patternSequence.length === 0) { // Restart game generateNewPattern(); } return; } } } return; } // Handle catch game state if (gameState === 'catch') { // Check back button (1024, 2500) if (x >= 924 && x <= 1124 && y >= 2460 && y <= 2540) { // Clean up catch game for (var i = 0; i < catchGameElements.length; i++) { catchGameElements[i].destroy(); } catchGameElements = []; fallingTreats = []; summerCatcher = null; catchGameActive = false; // Return to mini games menu createMiniGamesMenu(); return; } return; } // Handle pop lock game state if (gameState === 'poplock') { // Check back button (1024, 2500) if (x >= 924 && x <= 1124 && y >= 2460 && y <= 2540) { // Clean up pop lock game for (var i = 0; i < popLockGameElements.length; i++) { popLockGameElements[i].destroy(); } popLockGameElements = []; lockIndicators = []; lockTargetZones = []; if (lockMovingIndicator) { lockMovingIndicator.destroy(); lockMovingIndicator = null; } popLockGameActive = false; isLockMoving = false; // Return to mini games menu createMiniGamesMenu(); return; } // Check for lock timing click if (isLockMoving) { checkLockTiming(); } return; } // Handle stacker game state if (gameState === 'stacker') { // Check back button (1024, 2500) if (x >= 924 && x <= 1124 && y >= 2460 && y <= 2540) { // Clean up stacker game for (var i = 0; i < stackerGameElements.length; i++) { stackerGameElements[i].destroy(); } stackerGameElements = []; // Clean up blocks for (var level = 0; level < stackerBlocks.length; level++) { for (var j = 0; j < stackerBlocks[level].length; j++) { if (stackerBlocks[level][j]) { stackerBlocks[level][j].destroy(); } } } for (var i = 0; i < stackerMovingBlocks.length; i++) { stackerMovingBlocks[i].destroy(); } stackerBlocks = []; stackerMovingBlocks = []; stackerGameActive = false; stackerIsMoving = false; // Return to mini games menu createMiniGamesMenu(); return; } // Check for stacker click (stop blocks) if (stackerIsMoving) { stopStackerBlocks(); } else if (!stackerGameActive) { // Restart game resetStackerGame(); startStackerLevel(); } return; } // Handle boss fight updates if (gameState === 'bossfight' && bossFightActive) { // Update shoot cooldown if (shootCooldown > 0) { shootCooldown--; } // Update player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; if (bullet.y < 0) { // Bullet went off screen bullet.destroy(); playerBullets.splice(i, 1); var elementIndex = bossFightElements.indexOf(bullet); if (elementIndex > -1) { bossFightElements.splice(elementIndex, 1); } continue; } // Check collision with Lana boss if (lanaBoss && bullet.intersects(lanaBoss)) { // Hit the boss lanaBoss.takeDamage(10); bullet.destroy(); playerBullets.splice(i, 1); var elementIndex = bossFightElements.indexOf(bullet); if (elementIndex > -1) { bossFightElements.splice(elementIndex, 1); } // Update boss health bar if (bossHealthBar) { var healthPercentage = lanaBoss.health / lanaBoss.maxHealth; bossHealthBar.width = 800 * healthPercentage; } // Check if boss is defeated if (lanaBoss.health <= 0) { LK.showYouWin(); } continue; } // Check collision with Lana bullets for (var j = lanaBullets.length - 1; j >= 0; j--) { var lanaBullet = lanaBullets[j]; if (bullet.intersects(lanaBullet)) { // Bullets collide and destroy each other bullet.destroy(); lanaBullet.destroy(); playerBullets.splice(i, 1); lanaBullets.splice(j, 1); // Remove from boss fight elements var bulletIndex = bossFightElements.indexOf(bullet); if (bulletIndex > -1) { bossFightElements.splice(bulletIndex, 1); } var lanaBulletIndex = bossFightElements.indexOf(lanaBullet); if (lanaBulletIndex > -1) { bossFightElements.splice(lanaBulletIndex, 1); } break; } } } // Update Lana bullets for (var i = lanaBullets.length - 1; i >= 0; i--) { var bullet = lanaBullets[i]; if (bullet.y > 2732) { // Bullet went off screen bullet.destroy(); lanaBullets.splice(i, 1); var elementIndex = bossFightElements.indexOf(bullet); if (elementIndex > -1) { bossFightElements.splice(elementIndex, 1); } continue; } // Check collision with player if (playerFighter && bullet.intersects(playerFighter)) { // Hit the player playerHealth -= 15; bullet.destroy(); lanaBullets.splice(i, 1); var elementIndex = bossFightElements.indexOf(bullet); if (elementIndex > -1) { bossFightElements.splice(elementIndex, 1); } // Update player health bar if (playerHealthBar) { var healthPercentage = playerHealth / 100; playerHealthBar.width = 400 * healthPercentage; } // Check if player is defeated if (playerHealth <= 0) { LK.showGameOver(); } // Flash screen red briefly LK.effects.flashScreen(0xff0000, 300); } } return; } // Handle boss fight state if (gameState === 'bossfight') { // Check back button (150, 2650) if (x >= 50 && x <= 250 && y >= 2610 && y <= 2690) { // Clean up boss fight elements for (var i = 0; i < bossFightElements.length; i++) { bossFightElements[i].destroy(); } bossFightElements = []; playerBullets = []; lanaBullets = []; lanaBoss = null; playerFighter = null; bossFightActive = false; // Return to menu gameState = 'menu'; createMainMenu(); return; } // Check shoot button (1900, 2500) if (x >= 1840 && x <= 1960 && y >= 2440 && y <= 2560) { // Shoot button clicked - add visual feedback var shootButton = bossFightElements.find(function (element) { return element.x === 1900 && element.y === 250; }); if (shootButton) { tween(shootButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(shootButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); } // Shoot player bullet if not in cooldown if (shootCooldown <= 0) { var bullet = new PlayerBullet(); bullet.x = playerFighter.x; bullet.y = playerFighter.y - 50; game.addChild(bullet); playerBullets.push(bullet); bossFightElements.push(bullet); shootCooldown = 15; // Cooldown frames LK.getSound('playerShoot').play(); } return; } // General screen tap for shooting (keep as backup) if (shootCooldown <= 0) { var bullet = new PlayerBullet(); bullet.x = playerFighter.x; bullet.y = playerFighter.y - 50; game.addChild(bullet); playerBullets.push(bullet); bossFightElements.push(bullet); shootCooldown = 15; // Cooldown frames LK.getSound('playerShoot').play(); } return; } // Handle city builder state if (gameState === 'citybuilder') { // Check back button (1024, 2600) if (x >= 924 && x <= 1124 && y >= 2560 && y <= 2640) { // Clean up city builder elements for (var i = 0; i < cityBuilderElements.length; i++) { cityBuilderElements[i].destroy(); } cityBuilderElements = []; for (var i = 0; i < cityBuildings.length; i++) { cityBuildings[i].destroy(); } cityBuildings = []; // Clean up people and cars for (var i = 0; i < cityPeople.length; i++) { cityPeople[i].destroy(); } cityPeople = []; for (var i = 0; i < cityCars.length; i++) { cityCars[i].destroy(); } cityCars = []; for (var i = 0; i < cityStreets.length; i++) { cityStreets[i].destroy(); } cityStreets = []; cityBuilderActive = false; // Reset city stats cityMoney = 1000; cityPopulation = 0; cityHappiness = 50; selectedBuildingType = 'house'; // Return to menu gameState = 'menu'; createMainMenu(); return; } // Check building selection buttons (y = 800) if (y >= 760 && y <= 840) { var buildingNames = ['house', 'shop', 'park', 'office', 'street']; for (var i = 0; i < buildingNames.length; i++) { var buttonX = 150 + i * 175; // Adjusted spacing for 5 buttons if (x >= buttonX - 87 && x <= buttonX + 87) { selectedBuildingType = buildingNames[i]; // Visual feedback for selection var button = cityBuilderElements[4 + i * 2]; // Get button element if (button) { tween(button, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(button, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeIn }); } }); } return; } } } // Check building area (1400x1000 centered at 1024, 1600) if (x >= 324 && x <= 1724 && y >= 1100 && y <= 2100) { // Try to build var buildingCost = buildingTypes[selectedBuildingType].cost; if (cityMoney >= buildingCost) { // Create new building or street if (selectedBuildingType === 'street') { var newStreet = new Street(); newStreet.x = x; newStreet.y = y; game.addChild(newStreet); cityStreets.push(newStreet); cityBuilderElements.push(newStreet); // Spawn cars on this street if (Math.random() < 0.7) { var newCar = new Car(); newCar.x = x + (Math.random() - 0.5) * 300; newCar.y = y + (newCar.lane === 0 ? -15 : 15); game.addChild(newCar); cityCars.push(newCar); cityBuilderElements.push(newCar); } } else { var newBuilding = new CityBuilding(selectedBuildingType); newBuilding.x = x; newBuilding.y = y; game.addChild(newBuilding); cityBuildings.push(newBuilding); newBuilding.constructBuilding(); // Spawn people near buildings with population if (buildingTypes[selectedBuildingType].population > 0) { var peopleToSpawn = Math.floor(buildingTypes[selectedBuildingType].population / 2); for (var p = 0; p < peopleToSpawn; p++) { var newPerson = new Person(); newPerson.x = x + (Math.random() - 0.5) * 100; newPerson.y = y + 60; game.addChild(newPerson); cityPeople.push(newPerson); cityBuilderElements.push(newPerson); newPerson.startWalking(); } } } // Update resources cityMoney -= buildingCost; cityPopulation += buildingTypes[selectedBuildingType].population; cityHappiness = Math.min(100, cityHappiness + buildingTypes[selectedBuildingType].happiness); // Update displays updateCityBuilderUI(); // Play build sound LK.getSound('play').play(); } else { // Not enough money - show error var errorText = new Text2('Not enough money!', { size: 50, fill: 0xFF0000 }); errorText.anchor.set(0.5, 0.5); errorText.x = x; errorText.y = y - 50; game.addChild(errorText); tween(errorText, { alpha: 0, y: errorText.y - 100 }, { duration: 2000, easing: tween.easeOut, onFinish: function onFinish() { errorText.destroy(); } }); } return; } return; } // Handle art studio state if (gameState === 'art') { // Check back button (150, 2600) if (x >= 50 && x <= 250 && y >= 2560 && y <= 2640) { // Check if there are hidden game elements (indicating we came from gameplay) var hasHiddenGameElements = false; var gameChildren = game.children.slice(); for (var i = 0; i < gameChildren.length; i++) { if (!gameChildren[i].visible && !(gameChildren[i] instanceof Summer) && !(gameChildren[i] instanceof Heart)) { hasHiddenGameElements = true; break; } } // Clean up art studio elements for (var i = 0; i < artModeElements.length; i++) { // Don't destroy Summer if returning to gameplay if (hasHiddenGameElements && artModeElements[i] instanceof Summer) { continue; } artModeElements[i].destroy(); } artModeElements = []; artCanvas = null; colorPalette = null; artBrush = null; if (hasHiddenGameElements) { // Return to gameplay - restore UI visibility for (var i = 0; i < gameChildren.length; i++) { gameChildren[i].visible = true; } gameState = 'playing'; // Reposition Summer back to gameplay position if (summer) { summer.x = 1024; summer.y = 2200; summer.scaleX = 1.0; summer.scaleY = 1.0; } } else { // Return to menu summer = null; gameState = 'menu'; createMainMenu(); } return; } // Check clear button (400, 2600) if (x >= 300 && x <= 500 && y >= 2560 && y <= 2640) { if (artCanvas) { artCanvas.clearCanvas(); if (summer) { summer.showSpeechBubble("Fresh canvas!"); } } return; } // Check color palette clicks if (colorPalette && x >= 150 && x <= 450 && y >= 550 && y <= 750) { for (var i = 0; i < colorPalette.colorButtons.length; i++) { var colorButton = colorPalette.colorButtons[i]; var buttonX = colorPalette.x + colorButton.x; var buttonY = colorPalette.y + colorButton.y; if (x >= buttonX - 40 && x <= buttonX + 40 && y >= buttonY - 40 && y <= buttonY + 40) { if (artCanvas) { artCanvas.setColor(colorButton.colorValue); // Visual feedback - make selected color button pulse tween(colorButton, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(colorButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeIn }); } }); // Change brush color to match selected color if (artBrush) { artBrush.children[0].tint = colorButton.colorValue; } if (summer) { var colorNames = ["red", "green", "blue", "cyan", "black", "white"]; summer.showSpeechBubble("Nice " + colorNames[i] + " color!"); } } return; } } } // Check canvas drawing area if (artCanvas && x >= 224 && x <= 1824 && y >= 600 && y <= 1800) { isDrawing = true; lastDrawX = x; lastDrawY = y; var localX = x - artCanvas.x; var localY = y - artCanvas.y; artCanvas.addStroke(localX, localY); LK.getSound('paintbrush').play(); return; } return; } // Handle gameplay state if (gameState === 'playing') { // Check button clicks var buttonY = 2400; var buttonHeight = 120; var buttonWidth = 300; // Check if clicking in button area if (y >= buttonY - buttonHeight / 2 && y <= buttonY + buttonHeight / 2) { // Pet button if (x >= 300 - buttonWidth / 2 && x <= 300 + buttonWidth / 2) { // Add button press animation if (window.petButton) { tween(window.petButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(window.petButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); } summer.pet(); return; } // Feed button if (x >= 700 - buttonWidth / 2 && x <= 700 + buttonWidth / 2) { // Add button press animation if (window.feedButton) { tween(window.feedButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(window.feedButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); } // Create food next to Summer var foodToEat = new Food(); foodToEat.x = summer.x + 60; foodToEat.y = summer.y - 50; game.addChild(foodToEat); // Animate food moving to Summer's mouth and shrinking tween(foodToEat, { x: summer.x, y: summer.y - 80, scaleX: 0.3, scaleY: 0.3 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { // Make food disappear with eating animation tween(foodToEat, { alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { foodToEat.destroy(); } }); } }); hunger = Math.min(100, hunger + 20); happiness = Math.min(100, happiness + 10); updateHungerBar(); updateHappinessBar(); LK.getSound('eat').play(); LK.setTimeout(function () { LK.getSound('yummy').play(); summer.showSpeechBubble("Yummy!"); }, 500); return; } // Play button if (x >= 1100 - buttonWidth / 2 && x <= 1100 + buttonWidth / 2) { // Add button press animation if (window.playButton) { tween(window.playButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(window.playButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); } happiness = Math.min(100, happiness + 15); updateHappinessBar(); LK.getSound('play').play(); // Find nearest toy to chase var nearestToy = null; var nearestDistance = Infinity; if (toys && toys.length > 0) { for (var i = 0; i < toys.length; i++) { var toy = toys[i]; if (toy && toy.x !== undefined && toy.y !== undefined) { var distance = Math.sqrt(Math.pow(summer.x - toy.x, 2) + Math.pow(summer.y - toy.y, 2)); if (distance < nearestDistance) { nearestDistance = distance; nearestToy = toy; } } } } // Chase the nearest toy if one exists if (nearestToy && !summer.isAnimating) { summer.isAnimating = true; // Store original position var originalX = summer.x; var originalY = summer.y; // Chase animation - move Summer towards the toy tween(summer, { x: nearestToy.x, y: nearestToy.y }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { // Play animation when reaching the toy summer.playAnimation(); // Return to original position after play animation LK.setTimeout(function () { tween(summer, { x: originalX, y: originalY }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { summer.isAnimating = false; } }); }, 900); // Wait for play animation to finish } }); } else { summer.playAnimation(); } return; } // Groom button if (x >= 1500 - buttonWidth / 2 && x <= 1500 + buttonWidth / 2) { // Add button press animation if (window.groomButton) { tween(window.groomButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(window.groomButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); } happiness = Math.min(100, happiness + 8); updateHappinessBar(); LK.getSound('groom').play(); summer.bounce(); summer.showSpeechBubble("So fresh!"); // Spawn grooming brush near Summer var groomBrush = new GroomBrush(); groomBrush.x = summer.x - 80; groomBrush.y = summer.y - 100; game.addChild(groomBrush); groomBrush.performGrooming(); return; } } // Check for back to menu button click (centered at 800, 2580) if (y >= 2540 && y <= 2620 && x >= 700 && x <= 900) { // Add button press animation if (window.backToMenuButton) { tween(window.backToMenuButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(window.backToMenuButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); } // Clean up game elements var gameChildren = game.children.slice(); for (var i = 0; i < gameChildren.length; i++) { if (!(gameChildren[i] instanceof Summer) && !(gameChildren[i] instanceof Heart)) { gameChildren[i].destroy(); } } // Clean up arrays foods = []; toys = []; hearts = []; // Reset game variables happiness = 100; hunger = 100; summer = null; happinessBarFill = null; hungerBarFill = null; happinessText = null; hungerText = null; // Return to main menu gameState = 'menu'; createMainMenu(); return; } // Check for art studio button click (centered at 1250, 2580) if (y >= 2540 && y <= 2620 && x >= 1150 && x <= 1350) { // Add button press animation if (window.artStudioButton) { tween(window.artStudioButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(window.artStudioButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.bounceOut }); } }); } // Transition to art studio startArtStudio(); return; } // Check if clicking on a toy if (toys && toys.length > 0) { for (var i = 0; i < toys.length; i++) { var toy = toys[i]; if (toy && toy.x !== undefined && toy.y !== undefined) { var distance = Math.sqrt(Math.pow(x - toy.x, 2) + Math.pow(y - toy.y, 2)); if (distance < 50) { draggedToy = toy; break; } } } } } }; game.up = function (x, y, obj) { if (gameState === 'art') { isDrawing = false; if (summer && Math.random() < 0.4) { var encouragements = ["Beautiful!", "Amazing art!", "So creative!", "I love it!"]; var randomEncouragement = encouragements[Math.floor(Math.random() * encouragements.length)]; summer.showSpeechBubble(randomEncouragement); } } if (draggedToy) { draggedToy.checkPlayInteraction(); draggedToy = null; } }; game.update = function () { // Handle mini games menu mode if (gameState === 'minigames') { // Add gentle floating animation to title if (LK.ticks % 300 === 0) { var titleElement = miniGamesMenuElements[0]; // The title if (titleElement) { tween(titleElement, { y: titleElement.y - 10 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { tween(titleElement, { y: titleElement.y + 10 }, { duration: 1500, easing: tween.easeInOut }); } }); } } return; } // Handle memory game mode if (gameState === 'memory' && memoryGameActive) { // Check for flipped cards var currentFlipped = []; for (var i = 0; i < memoryCards.length; i++) { if (memoryCards[i].isFlipped && !memoryCards[i].matched) { currentFlipped.push(memoryCards[i]); } } // If two cards are flipped, check for match if (currentFlipped.length === 2 && flippedCards.length < 2) { flippedCards = currentFlipped.slice(); memoryMovesCount++; // Update score display var scoreElement = memoryGameElements[1]; if (scoreElement && scoreElement.setText) { scoreElement.setText('Score: ' + memoryScore + ' | Moves: ' + memoryMovesCount); } LK.setTimeout(function () { if (flippedCards[0].cardValue === flippedCards[1].cardValue) { // Match found flippedCards[0].setMatched(); flippedCards[1].setMatched(); memoryScore += 10; // Check if game is complete var allMatched = true; for (var i = 0; i < memoryCards.length; i++) { if (!memoryCards[i].matched) { allMatched = false; break; } } if (allMatched) { LK.setTimeout(function () { // Game complete - show victory message var victoryText = new Text2('YOU WIN!', { size: 120, fill: 0xFFD700 }); victoryText.anchor.set(0.5, 0.5); victoryText.x = 1024; victoryText.y = 1366; game.addChild(victoryText); memoryGameElements.push(victoryText); // Animate victory text tween(victoryText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 500, easing: tween.bounceOut }); }, 500); } } else { // No match - flip cards back flippedCards[0].flipBack(); flippedCards[1].flipBack(); } flippedCards = []; }, 1000); } return; } // Handle pattern game mode if (gameState === 'pattern' && patternGameActive) { // Add gentle pulsing animation to pattern buttons when waiting for input if (acceptingInput && !showingPattern && LK.ticks % 120 === 0) { for (var i = 0; i < patternButtons.length; i++) { var button = patternButtons[i]; if (button && !button.isAnimating) { button.isAnimating = true; tween(button, { scaleX: 1.05, scaleY: 1.05 }, { duration: 1000, easing: tween.easeInOut, onFinish: function () { tween(this, { scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function () { this.isAnimating = false; }.bind(this) }); }.bind(button) }); } } } return; } // Handle pop lock game mode if (gameState === 'poplock' && popLockGameActive) { // Move the indicator back and forth if (isLockMoving && lockMovingIndicator) { lockMovingIndicator.x += lockSpeed * lockDirection; // Bounce off edges var leftEdge = 1024 - 280; var rightEdge = 1024 + 280; if (lockMovingIndicator.x >= rightEdge) { lockMovingIndicator.x = rightEdge; lockDirection = -1; } else if (lockMovingIndicator.x <= leftEdge) { lockMovingIndicator.x = leftEdge; lockDirection = 1; } } return; } // Handle stacker game mode if (gameState === 'stacker' && stackerGameActive) { // Move the blocks back and forth if (stackerIsMoving && stackerMovingBlocks.length > 0) { var blockWidth = 80; var gameAreaWidth = 600; // Total area for movement var leftBound = 1024 - gameAreaWidth / 2; var rightBound = 1024 + gameAreaWidth / 2; // Move all blocks in the current row together for (var i = 0; i < stackerMovingBlocks.length; i++) { stackerMovingBlocks[i].x += stackerSpeed * stackerDirection; } // Check boundaries using first and last blocks if (stackerMovingBlocks.length > 0) { var firstBlock = stackerMovingBlocks[0]; var lastBlock = stackerMovingBlocks[stackerMovingBlocks.length - 1]; var groupWidth = (stackerMovingBlocks.length - 1) * blockWidth; // Check if hitting right boundary if (lastBlock.x + blockWidth / 2 >= rightBound) { // Adjust position and reverse direction var adjustment = lastBlock.x + blockWidth / 2 - rightBound; for (var i = 0; i < stackerMovingBlocks.length; i++) { stackerMovingBlocks[i].x -= adjustment; } stackerDirection = -1; } // Check if hitting left boundary else if (firstBlock.x - blockWidth / 2 <= leftBound) { // Adjust position and reverse direction var adjustment = leftBound - (firstBlock.x - blockWidth / 2); for (var i = 0; i < stackerMovingBlocks.length; i++) { stackerMovingBlocks[i].x += adjustment; } stackerDirection = 1; } } } return; } // Handle catch game mode if (gameState === 'catch' && catchGameActive) { catchGameTimer++; // Decrease time every second (60 ticks) if (catchGameTimer >= 60) { catchTimeLeft--; updateCatchGameScore(); catchGameTimer = 0; // Check if time is up if (catchTimeLeft <= 0) { handleCatchGameOver(); } } // Spawn treats periodically if (LK.ticks % 90 === 0 && catchTimeLeft > 0) { // Spawn every 1.5 seconds spawnTreat(); } // Update falling treats for (var i = fallingTreats.length - 1; i >= 0; i--) { var treat = fallingTreats[i]; if (!treat || treat.caught) continue; // Move treat down treat.y += treat.fallSpeed; // Check collision with Summer if (summerCatcher && !treat.caught) { var distance = Math.sqrt(Math.pow(treat.x - summerCatcher.x, 2) + Math.pow(treat.y - summerCatcher.y, 2)); if (distance < 80) { // Treat caught! treat.caught = true; catchScore++; updateCatchGameScore(); // Animate treat being caught tween(treat, { scaleX: 1.5, scaleY: 1.5, alpha: 0, y: treat.y - 50 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { treat.destroy(); } }); // Remove from array fallingTreats.splice(i, 1); catchGameElements.splice(catchGameElements.indexOf(treat), 1); // Summer celebration if (summerCatcher) { tween(summerCatcher, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(summerCatcher, { scaleX: 0.8, scaleY: 0.8 }, { duration: 100, easing: tween.bounceOut }); } }); } continue; } } // Remove treats that fell off screen if (treat.y > 2732) { treat.destroy(); fallingTreats.splice(i, 1); var elementIndex = catchGameElements.indexOf(treat); if (elementIndex > -1) { catchGameElements.splice(elementIndex, 1); } } } return; } // Handle city builder mode if (gameState === 'citybuilder' && cityBuilderActive) { // Update city economics and happiness updateCityBuilderUI(); // Update people walking for (var i = 0; i < cityPeople.length; i++) { if (cityPeople[i] && typeof cityPeople[i].update === 'function') { cityPeople[i].update(); } } // Update cars driving for (var i = 0; i < cityCars.length; i++) { if (cityCars[i] && typeof cityCars[i].update === 'function') { cityCars[i].update(); } } // Randomly spawn more people and cars if (LK.ticks % 900 === 0 && cityBuildings.length > 0) { // Every 15 seconds // Spawn a person near a random building if (cityPeople.length < cityPopulation / 2) { var randomBuilding = cityBuildings[Math.floor(Math.random() * cityBuildings.length)]; if (randomBuilding) { var newPerson = new Person(); newPerson.x = randomBuilding.x + (Math.random() - 0.5) * 100; newPerson.y = randomBuilding.y + 60; game.addChild(newPerson); cityPeople.push(newPerson); cityBuilderElements.push(newPerson); newPerson.startWalking(); } } } if (LK.ticks % 600 === 0 && cityStreets.length > 0) { // Every 10 seconds // Spawn a car on a random street if (cityCars.length < cityStreets.length * 2) { var randomStreet = cityStreets[Math.floor(Math.random() * cityStreets.length)]; if (randomStreet) { var newCar = new Car(); newCar.x = randomStreet.x + (Math.random() - 0.5) * 300; newCar.y = randomStreet.y + (newCar.lane === 0 ? -15 : 15); game.addChild(newCar); cityCars.push(newCar); cityBuilderElements.push(newCar); } } } // Add gentle building animations if (LK.ticks % 240 === 0 && cityBuildings.length > 0) { var randomBuilding = cityBuildings[Math.floor(Math.random() * cityBuildings.length)]; if (randomBuilding && !randomBuilding.isAnimating) { randomBuilding.isAnimating = true; tween(randomBuilding, { scaleX: 1.05, scaleY: 1.05 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(randomBuilding, { scaleX: 1.0, scaleY: 1.0 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { randomBuilding.isAnimating = false; } }); } }); } } return; } // Handle art studio mode if (gameState === 'art') { // Add gentle swaying animation to Summer in art mode if (summer && !summer.isAnimating && LK.ticks % 200 === 0) { tween(summer, { rotation: (Math.random() - 0.5) * 0.1 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(summer, { rotation: 0 }, { duration: 1000, easing: tween.easeInOut }); } }); } // Animate art brush if (artBrush && artBrush.rotation !== undefined && LK.ticks % 120 === 0) { tween(artBrush, { rotation: artBrush.rotation + 0.2 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { if (artBrush && artBrush.rotation !== undefined) { tween(artBrush, { rotation: artBrush.rotation - 0.2 }, { duration: 500, easing: tween.easeInOut }); } } }); } return; } // Only run game logic during gameplay if (gameState === 'playing') { // Add idle breathing animation to Summer if (summer && !summer.isAnimating && LK.ticks % 180 === 0) { tween(summer, { scaleY: 1.02 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(summer, { scaleY: 1.0 }, { duration: 1000, easing: tween.easeInOut }); } }); } // Update timers hungerTimer++; happinessTimer++; foodSpawnTimer++; toySpawnTimer++; // Hunger decreases every 5 seconds (300 ticks) if (hungerTimer >= 300) { hunger = Math.max(0, hunger - 1); updateHungerBar(); hungerTimer = 0; } // Happiness decreases every 10 seconds (600 ticks) or faster when hungry var happinessDecayRate = hunger < 30 ? 300 : 600; if (happinessTimer >= happinessDecayRate) { happiness = Math.max(0, happiness - 1); updateHappinessBar(); happinessTimer = 0; } // Spawn food every 30 seconds (1800 ticks) if (foodSpawnTimer >= 1800) { spawnFood(); foodSpawnTimer = 0; } // Spawn toys every 45 seconds (2700 ticks) if (toySpawnTimer >= 2700) { spawnToy(); toySpawnTimer = 0; } // Update floating hearts if (hearts && hearts.length > 0) { for (var i = hearts.length - 1; i >= 0; i--) { var heart = hearts[i]; if (heart && heart.alpha !== undefined && heart.alpha === 1 && typeof heart.floatUp === 'function') { heart.floatUp(); } } } // Check game over condition if (happiness <= 0 && hunger <= 0) { LK.showGameOver(); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var ArtBrush = Container.expand(function () {
var self = Container.call(this);
var brushGraphics = self.attachAsset('brush', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = false;
self.activate = function () {
self.isActive = true;
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut
});
};
self.deactivate = function () {
self.isActive = false;
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeIn
});
};
return self;
});
var ArtCanvas = Container.expand(function () {
var self = Container.call(this);
var canvasGraphics = self.attachAsset('canvas', {
anchorX: 0.5,
anchorY: 0.5
});
self.strokes = [];
self.currentColor = 0x000000;
self.currentStrokeAsset = 'paintStrokeBlack';
self.isDrawing = false;
self.addStroke = function (x, y) {
var stroke = self.addChild(LK.getAsset(self.currentStrokeAsset, {
anchorX: 0.5,
anchorY: 0.5
}));
stroke.x = x;
stroke.y = y;
self.strokes.push(stroke);
// Add paint splash effect
tween(stroke, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(stroke, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
};
self.setColor = function (color) {
self.currentColor = color;
console.log("Setting color to:", color, "hex:", color.toString(16));
// Map color values to stroke assets
if (color === 0xff0000) {
self.currentStrokeAsset = 'paintStrokeRed';
} else if (color === 0x00ff00) {
self.currentStrokeAsset = 'paintStrokeGreen';
} else if (color === 0x0000ff) {
self.currentStrokeAsset = 'paintStrokeBlue';
} else if (color === 0x00ffff) {
self.currentStrokeAsset = 'paintStrokeCyan';
} else if (color === 0xffffff) {
self.currentStrokeAsset = 'paintStrokeWhite';
} else if (color === 0x000000) {
self.currentStrokeAsset = 'paintStrokeBlack';
} else {
self.currentStrokeAsset = 'paintStrokeBlack';
console.log("Unknown color, defaulting to black");
}
console.log("Current stroke asset set to:", self.currentStrokeAsset);
};
self.clearCanvas = function () {
for (var i = 0; i < self.strokes.length; i++) {
self.strokes[i].destroy();
}
self.strokes = [];
};
return self;
});
var Car = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.driveSpeed = 2 + Math.random() * 3; // Random drive speed
self.direction = Math.random() < 0.5 ? 1 : -1; // Random initial direction
self.lane = Math.random() < 0.5 ? 0 : 1; // Which lane (0 = top, 1 = bottom)
// Random car colors
var carColors = [0xFF4444, 0x4444FF, 0x44FF44, 0xFFFF44, 0xFF44FF, 0x44FFFF];
carGraphics.tint = carColors[Math.floor(Math.random() * carColors.length)];
self.update = function () {
// Move car
self.x += self.driveSpeed * self.direction;
// Wrap around screen
if (self.direction > 0 && self.x > 2100) {
self.x = -100;
} else if (self.direction < 0 && self.x < -100) {
self.x = 2100;
}
// Add slight engine vibration
if (LK.ticks % 10 === 0) {
self.y += (Math.random() - 0.5) * 2;
}
};
return self;
});
var CityBuilding = Container.expand(function (buildingType) {
var self = Container.call(this);
var buildingData = buildingTypes[buildingType];
var buildingGraphics = self.attachAsset('barBackground', {
anchorX: 0.5,
anchorY: 1.0
});
buildingGraphics.width = 80;
buildingGraphics.height = 80;
buildingGraphics.tint = buildingData.color;
self.buildingType = buildingType;
self.population = buildingData.population;
self.happiness = buildingData.happiness;
// Add construction animation
self.constructBuilding = function () {
self.scaleX = 0;
self.scaleY = 0;
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 500,
easing: tween.bounceOut
});
};
// Add building info display
self.down = function (x, y, obj) {
self.showBuildingInfo();
};
self.showBuildingInfo = function () {
var infoText = buildingType.toUpperCase();
if (self.population > 0) {
infoText += '\nPop: ' + self.population;
}
if (self.happiness > 0) {
infoText += '\nHappy: +' + self.happiness;
}
var infoDisplay = new Text2(infoText, {
size: 30,
fill: 0x000000
});
infoDisplay.anchor.set(0.5, 1);
infoDisplay.x = self.x;
infoDisplay.y = self.y - 100;
game.addChild(infoDisplay);
tween(infoDisplay, {
alpha: 0,
y: infoDisplay.y - 50
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
infoDisplay.destroy();
}
});
};
return self;
});
var ColorPalette = Container.expand(function () {
var self = Container.call(this);
self.colors = [0xff0000, 0x00ff00, 0x0000ff, 0x00ffff, 0x000000, 0xffffff];
self.colorAssets = ['colorRed', 'colorGreen', 'colorBlue', 'colorCyan', 'colorBlack', 'colorWhite'];
self.colorButtons = [];
for (var i = 0; i < self.colors.length; i++) {
var colorButton = self.addChild(LK.getAsset(self.colorAssets[i], {
anchorX: 0.5,
anchorY: 0.5
}));
colorButton.x = i % 4 * 100;
colorButton.y = Math.floor(i / 4) * 100;
colorButton.colorValue = self.colors[i];
colorButton.assetName = self.colorAssets[i];
self.colorButtons.push(colorButton);
// Add hover effect with scale animation
colorButton.originalScale = 1.0;
colorButton.down = function (x, y, obj) {
tween(this, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function () {
tween(this, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}.bind(this)
});
}.bind(colorButton);
}
return self;
});
var Food = Container.expand(function () {
var self = Container.call(this);
var foodGraphics = self.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
self.feed();
};
self.feed = function () {
// Create food next to Summer
var foodToEat = new Food();
foodToEat.x = summer.x + 60;
foodToEat.y = summer.y - 50;
game.addChild(foodToEat);
// Animate food moving to Summer's mouth and shrinking
tween(foodToEat, {
x: summer.x,
y: summer.y - 80,
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Make food disappear with eating animation
tween(foodToEat, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
foodToEat.destroy();
}
});
}
});
hunger = Math.min(100, hunger + 20);
happiness = Math.min(100, happiness + 10);
updateHungerBar();
updateHappinessBar();
LK.getSound('eat').play();
LK.setTimeout(function () {
LK.getSound('yummy').play();
summer.showSpeechBubble("Yummy!");
}, 500);
// Remove from foods array
var index = foods.indexOf(self);
if (index > -1) {
foods.splice(index, 1);
}
self.destroy();
};
return self;
});
var GroomBrush = Container.expand(function () {
var self = Container.call(this);
var brushGraphics = self.attachAsset('groomBrush', {
anchorX: 0.5,
anchorY: 0.5
});
self.performGrooming = function () {
// Start grooming animation - move brush back and forth
tween(self, {
x: self.x + 50,
rotation: 0.3
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
x: self.x - 100,
rotation: -0.3
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
x: self.x + 50,
rotation: 0,
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
}
});
}
});
};
return self;
});
var Heart = Container.expand(function () {
var self = Container.call(this);
var heartGraphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
self.floatUp = function () {
tween(self, {
y: self.y - 150,
alpha: 0
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
if (hearts && hearts.indexOf) {
var index = hearts.indexOf(self);
if (index > -1) {
hearts.splice(index, 1);
}
}
self.destroy();
}
});
};
return self;
});
var LanaBoss = Container.expand(function () {
var self = Container.call(this);
var lanaGraphics = self.attachAsset('lana', {
anchorX: 0.5,
anchorY: 1.0
});
self.health = 100;
self.maxHealth = 100;
self.moveSpeed = 3;
self.direction = 1;
self.shootTimer = 0;
self.attackPattern = 0;
self.isInvulnerable = false;
self.update = function () {
// Move side to side
self.x += self.moveSpeed * self.direction;
if (self.x > 1800) {
self.direction = -1;
} else if (self.x < 248) {
self.direction = 1;
}
// Shooting patterns
self.shootTimer++;
if (self.shootTimer >= 120) {
// Shoot every 2 seconds
self.shootBullets();
self.shootTimer = 0;
}
// Attack pattern changes based on health
if (self.health < 50) {
self.moveSpeed = 5;
} else if (self.health < 25) {
self.moveSpeed = 7;
}
};
self.shootBullets = function () {
var bulletCount = self.health > 50 ? 1 : self.health > 25 ? 3 : 5;
for (var i = 0; i < bulletCount; i++) {
var bullet = new LanaBullet();
bullet.x = self.x + (i - Math.floor(bulletCount / 2)) * 60;
bullet.y = self.y - 50;
game.addChild(bullet);
if (bossFightElements) {
bossFightElements.push(bullet);
}
if (lanaBullets) {
lanaBullets.push(bullet);
}
}
LK.getSound('bossFight').play();
};
self.takeDamage = function (amount) {
if (self.isInvulnerable) return;
self.health -= amount;
self.isInvulnerable = true;
// Flash red when hit
tween(lanaGraphics, {
tint: 0xFF0000
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(lanaGraphics, {
tint: 0xFFFFFF
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// Temporary invulnerability
LK.setTimeout(function () {
self.isInvulnerable = false;
}, 500);
LK.getSound('bossHit').play();
};
return self;
});
var LanaBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('lanaBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.update = function () {
self.y += self.speed;
};
return self;
});
var MemoryCard = Container.expand(function () {
var self = Container.call(this);
var cardGraphics = self.attachAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
});
cardGraphics.width = 120;
cardGraphics.height = 120;
cardGraphics.tint = 0x00FF00; //{36} // Bright green
self.isFlipped = false;
self.cardValue = 0;
self.matched = false;
var cardText = new Text2('?', {
size: 60,
fill: 0xFFFFFF
});
cardText.anchor.set(0.5, 0.5);
cardText.x = 0;
cardText.y = 0;
self.addChild(cardText);
self.flip = function () {
if (self.matched || self.isFlipped) return;
self.isFlipped = true;
cardText.setText(self.cardValue.toString());
tween(self, {
scaleX: 0
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
cardGraphics.tint = 0x0080FF; // Bright blue
tween(self, {
scaleX: 1
}, {
duration: 150,
easing: tween.easeOut
});
}
});
};
self.flipBack = function () {
if (self.matched) return;
self.isFlipped = false;
cardText.setText('?');
tween(self, {
scaleX: 0
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
cardGraphics.tint = 0x00FF00; //{3x} // Bright green
tween(self, {
scaleX: 1
}, {
duration: 150,
easing: tween.easeOut
});
}
});
};
self.setMatched = function () {
self.matched = true;
cardGraphics.tint = 0xFFFF00; // Bright yellow/gold
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
};
self.down = function (x, y, obj) {
if (!self.matched && !self.isFlipped) {
self.flip();
}
};
return self;
});
var Person = Container.expand(function () {
var self = Container.call(this);
var personGraphics = self.attachAsset('person', {
anchorX: 0.5,
anchorY: 1.0
});
self.walkSpeed = 1 + Math.random() * 2; // Random walk speed
self.direction = Math.random() < 0.5 ? 1 : -1; // Random initial direction
self.targetX = 0;
self.isWalking = false;
self.startWalking = function () {
if (self.isWalking) return;
self.isWalking = true;
// Set a random target within city area
self.targetX = 400 + Math.random() * 1200;
// Walking animation - slight bounce
function walkBounce() {
if (!self.isWalking) return;
tween(self, {
scaleX: 1.1,
scaleY: 0.9
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 0.9,
scaleY: 1.1
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.isWalking) {
walkBounce();
}
}
});
}
});
}
walkBounce();
};
self.update = function () {
if (!self.isWalking) return;
// Move towards target
if (Math.abs(self.x - self.targetX) > 5) {
if (self.x < self.targetX) {
self.x += self.walkSpeed;
self.scaleX = Math.abs(self.scaleX); // Face right
} else {
self.x -= self.walkSpeed;
self.scaleX = -Math.abs(self.scaleX); // Face left
}
} else {
// Reached target, pick new one
self.targetX = 400 + Math.random() * 1200;
}
// Keep within bounds
if (self.x < 300) {
self.x = 300;
self.targetX = 400 + Math.random() * 800;
} else if (self.x > 1700) {
self.x = 1700;
self.targetX = 600 + Math.random() * 800;
}
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Street = Container.expand(function () {
var self = Container.call(this);
var streetGraphics = self.attachAsset('street', {
anchorX: 0.5,
anchorY: 0.5
});
// Add street lines
var line1 = self.addChild(LK.getAsset('streetLine', {
anchorX: 0.5,
anchorY: 0.5
}));
line1.x = 0;
line1.y = -10;
var line2 = self.addChild(LK.getAsset('streetLine', {
anchorX: 0.5,
anchorY: 0.5
}));
line2.x = 0;
line2.y = 10;
return self;
});
var Summer = Container.expand(function () {
var self = Container.call(this);
var summerGraphics = self.attachAsset('summer', {
anchorX: 0.5,
anchorY: 1.0
});
self.originalScale = 1.0;
self.isAnimating = false;
self.down = function (x, y, obj) {
if (!self.isAnimating) {
self.pet();
}
};
self.pet = function () {
happiness = Math.min(100, happiness + 5);
updateHappinessBar();
LK.getSound('bark').play();
self.createHeart();
self.bounce();
self.showSpeechBubble("Woof!");
};
self.createHeart = function () {
var heart = new Heart();
heart.x = self.x + (Math.random() - 0.5) * 100;
heart.y = self.y - 50;
game.addChild(heart);
hearts.push(heart);
};
self.bounce = function () {
if (self.isAnimating) return;
self.isAnimating = true;
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: self.originalScale,
scaleY: self.originalScale
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isAnimating = false;
}
});
}
});
};
self.playAnimation = function () {
if (self.isAnimating) return;
self.isAnimating = true;
tween(self, {
rotation: 0.2
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: -0.2
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: 0
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.isAnimating = false;
}
});
}
});
}
});
};
self.showSpeechBubble = function (text) {
var speechBubble = new Text2(text, {
size: 40,
fill: 0x000000
});
speechBubble.anchor.set(0.5, 1);
speechBubble.x = self.x;
speechBubble.y = self.y - summerGraphics.height / 2 - 20; // Position above Summer's head
game.addChild(speechBubble);
tween(speechBubble, {
alpha: 0,
y: speechBubble.y - 50
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
speechBubble.destroy();
}
});
};
return self;
});
var Toy = Container.expand(function () {
var self = Container.call(this);
var toyGraphics = self.attachAsset('toy', {
anchorX: 0.5,
anchorY: 0.5
});
self.isDragging = false;
self.down = function (x, y, obj) {
self.isDragging = true;
self.startDragX = x;
self.startDragY = y;
};
self.checkPlayInteraction = function () {
var distance = Math.sqrt(Math.pow(self.x - summer.x, 2) + Math.pow(self.y - summer.y, 2));
if (distance < 150) {
happiness = Math.min(100, happiness + 15);
updateHappinessBar();
LK.getSound('play').play();
summer.playAnimation();
summer.showSpeechBubble("Zoomies!");
// Remove from toys array
var index = toys.indexOf(self);
if (index > -1) {
toys.splice(index, 1);
}
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xFFB6C1
});
/****
* Game Code
****/
// Add Array.find polyfill for compatibility
if (!Array.prototype.find) {
Array.prototype.find = function (predicate) {
if (this === null) {
throw new TypeError('Array.prototype.find called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = parseInt(list.length) || 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return value;
}
}
return undefined;
};
}
var gameState = 'splash'; // 'splash', 'menu', 'playing', 'art', 'minigames', or 'bossfight'
// Boss fight variables
var bossFightActive = false;
var bossFightElements = [];
var lanaBoss = null;
var playerFighter = null;
var playerBullets = [];
var lanaBullets = [];
var playerHealth = 100;
var bossHealthBar = null;
var playerHealthBar = null;
var shootCooldown = 0;
var miniGamesMenuElements = [];
var previousGameState = null;
var menuSummer = null;
var gamePlayElements = [];
var happiness = 100;
var hunger = 100;
var foods = [];
var toys = [];
var hearts = [];
var draggedToy = null;
var memoryGameButton = null;
var patternGameButton = null;
var catchGameButton = null;
var popLockGameButton = null;
var stackerGameButton = null;
var stackerGameActive = false;
var stackerGameElements = [];
var stackerScore = 0;
var stackerLevel = 1;
var stackerBlocks = [];
var stackerCurrentRow = [];
var stackerCurrentLevel = 0;
var stackerMovingBlocks = [];
var stackerDirection = 1;
var stackerSpeed = 2;
var stackerIsMoving = false;
var stackerTotalLevels = 15;
var stackerBlockWidth = 80;
var stackerRowWidth = 7;
var stackerStartY = 2200;
var catchGameActive = false;
var catchGameElements = [];
var catchScore = 0;
var catchTimeLeft = 30;
var fallingTreats = [];
var summerCatcher = null;
var catchGameTimer = 0;
var memoryGameElements = [];
var memoryCards = [];
var flippedCards = [];
var memoryGameActive = false;
var memoryScore = 0;
var memoryMovesCount = 0;
var patternGameActive = false;
var patternGameElements = [];
var patternSequence = [];
var playerSequence = [];
var patternLevel = 1;
var patternScore = 0;
var currentPatternIndex = 0;
var showingPattern = false;
var acceptingInput = false;
var patternButtons = [];
var popLockGameActive = false;
var popLockGameElements = [];
var popLockScore = 0;
var popLockLevel = 1;
var currentLockIndex = 0;
var lockIndicators = [];
var lockTargetZones = [];
var lockMovingIndicator = null;
var lockDirection = 1;
var lockSpeed = 3;
var isLockMoving = false;
var locksCompleted = 0;
var totalLocks = 3;
var summer = null;
var happinessBarFill = null;
var hungerBarFill = null;
var happinessText = null;
var hungerText = null;
// Art studio mode variables
var artCanvas = null;
var colorPalette = null;
var artBrush = null;
var artModeElements = [];
var isDrawing = false;
var lastDrawX = 0;
var lastDrawY = 0;
// Create splash screen
function createSplashScreen() {
// Black background already set in game initialization
game.setBackgroundColor(0x000000);
// Create logo
var logo = game.addChild(LK.getAsset('summerLogo', {
anchorX: 0.5,
anchorY: 0.5
}));
logo.x = 1024;
logo.y = 1200;
// Create text
var splashText = new Text2('Summer Productions Presents', {
size: 80,
fill: 0xFFFFFF
});
splashText.anchor.set(0.5, 0.5);
splashText.x = 1024;
splashText.y = 1500;
game.addChild(splashText);
// Fade in animation
logo.alpha = 0;
splashText.alpha = 0;
tween(logo, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut
});
tween(splashText, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut
});
// Music will start when transitioning to menu
// After 4 seconds, transition to main menu
LK.setTimeout(function () {
// Fade out splash screen
tween(logo, {
alpha: 0
}, {
duration: 500,
easing: tween.easeInOut
});
tween(splashText, {
alpha: 0
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
logo.destroy();
splashText.destroy();
gameState = 'menu';
game.setBackgroundColor(0xFFB6C1);
// Start music when transitioning to menu
LK.playMusic('bgmusic', {
loop: true
});
createMainMenu();
}
});
}, 4000);
}
// Create main menu
function createMainMenu() {
// Music will start when title flies in
// Game title - start off screen
var titleText = new Text2('RAISE A SUMMER', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = -500; // Start off screen left
titleText.y = 800;
game.addChild(titleText);
// Fly in animation
tween(titleText, {
x: 1024
}, {
duration: 1500,
easing: tween.easeOut
});
// Music already started during splash screen
// Add pulsing animation to title
function animateTitle() {
tween(titleText, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(titleText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
animateTitle();
}
}
});
}
});
}
animateTitle();
// Play button
var menuPlayButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
menuPlayButton.width = 400;
menuPlayButton.height = 150;
menuPlayButton.x = 1024;
menuPlayButton.y = 1300;
menuPlayButton.tint = 0x32CD32;
var menuPlayButtonText = new Text2('PLAY', {
size: 80,
fill: 0xFFFFFF
});
menuPlayButtonText.anchor.set(0.5, 0.5);
menuPlayButtonText.x = menuPlayButton.x;
menuPlayButtonText.y = menuPlayButton.y;
game.addChild(menuPlayButtonText);
// Art Studio button
var menuArtButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
menuArtButton.width = 400;
menuArtButton.height = 150;
menuArtButton.x = 1024;
menuArtButton.y = 1500;
menuArtButton.tint = 0x9370DB;
var menuArtButtonText = new Text2('ART STUDIO', {
size: 70,
fill: 0xFFFFFF
});
menuArtButtonText.anchor.set(0.5, 0.5);
menuArtButtonText.x = menuArtButton.x;
menuArtButtonText.y = menuArtButton.y;
game.addChild(menuArtButtonText);
// Mini Games button
var menuMiniGamesButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
menuMiniGamesButton.width = 400;
menuMiniGamesButton.height = 150;
menuMiniGamesButton.x = 1024;
menuMiniGamesButton.y = 1700;
menuMiniGamesButton.tint = 0xFF6B35;
var menuMiniGamesButtonText = new Text2('MINI GAMES', {
size: 70,
fill: 0xFFFFFF
});
menuMiniGamesButtonText.anchor.set(0.5, 0.5);
menuMiniGamesButtonText.x = menuMiniGamesButton.x;
menuMiniGamesButtonText.y = menuMiniGamesButton.y;
game.addChild(menuMiniGamesButtonText);
// City Builder button
var menuCityBuilderButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
menuCityBuilderButton.width = 400;
menuCityBuilderButton.height = 150;
menuCityBuilderButton.x = 1024;
menuCityBuilderButton.y = 1900;
menuCityBuilderButton.tint = 0x4A90E2;
var menuCityBuilderButtonText = new Text2('CITY BUILDER', {
size: 70,
fill: 0xFFFFFF
});
menuCityBuilderButtonText.anchor.set(0.5, 0.5);
menuCityBuilderButtonText.x = menuCityBuilderButton.x;
menuCityBuilderButtonText.y = menuCityBuilderButton.y;
game.addChild(menuCityBuilderButtonText);
// Lana Boss Fight button
var menuBossFightButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
menuBossFightButton.width = 400;
menuBossFightButton.height = 150;
menuBossFightButton.x = 1024;
menuBossFightButton.y = 2100;
menuBossFightButton.tint = 0x8B0000;
var menuBossFightButtonText = new Text2('LANA BOSS FIGHT', {
size: 70,
fill: 0xFFFFFF
});
menuBossFightButtonText.anchor.set(0.5, 0.5);
menuBossFightButtonText.x = menuBossFightButton.x;
menuBossFightButtonText.y = menuBossFightButton.y;
game.addChild(menuBossFightButtonText);
// Add bouncing animation to menu play button
function animateMenuPlayButton() {
tween(menuPlayButton, {
y: menuPlayButton.y - 20
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(menuPlayButton, {
y: menuPlayButton.y + 20
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
animateMenuPlayButton();
}
}
});
}
});
tween(menuPlayButtonText, {
y: menuPlayButtonText.y - 20
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(menuPlayButtonText, {
y: menuPlayButtonText.y + 20
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
animateMenuPlayButton();
}
}
});
}
});
}
animateMenuPlayButton();
// Add subtitle
var subtitleText = new Text2('Your Virtual Pet Companion', {
size: 60,
fill: 0xFFB6C1
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 950;
subtitleText.alpha = 0;
game.addChild(subtitleText);
// Fade in subtitle after a delay
LK.setTimeout(function () {
if (gameState === 'menu') {
tween(subtitleText, {
alpha: 1
}, {
duration: 1500,
easing: tween.easeInOut
});
}
}, 1000);
// Create ten floating Summer characters in background
var floatingSummers = [];
for (var s = 0; s < 10; s++) {
var floatingSummer = game.addChild(new Summer());
floatingSummer.x = Math.random() * 2048;
floatingSummer.y = Math.random() * 2732;
floatingSummer.alpha = 0.6; // Make them semi-transparent
floatingSummer.scaleX = 0.7; // Make them smaller
floatingSummer.scaleY = 0.7;
floatingSummers.push(floatingSummer);
// Start individual floating animation for each Summer
startIndividualFloatingAnimation(floatingSummer);
}
// Store the main menu Summer (keeping original behavior)
menuSummer = floatingSummers[0];
// Make the first one more prominent
menuSummer.alpha = 1.0;
menuSummer.scaleX = 1.0;
menuSummer.scaleY = 1.0;
// Add floating food decorations
var decorativeItems = [];
var _loop = function _loop() {
decorativeFood = game.addChild(LK.getAsset('food', {
anchorX: 0.5,
anchorY: 0.5
}));
decorativeFood.x = Math.random() * 2048;
decorativeFood.y = Math.random() * 2732;
decorativeFood.alpha = 0.3;
decorativeFood.scaleX = 0.5;
decorativeFood.scaleY = 0.5;
decorativeItems.push(decorativeFood);
// Float around randomly
function floatDecoration(item) {
tween(item, {
x: Math.random() * 2048,
y: Math.random() * 2732,
rotation: item.rotation + (Math.random() - 0.5) * Math.PI
}, {
duration: 5000 + Math.random() * 3000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
floatDecoration(item);
}
}
});
}
floatDecoration(decorativeFood);
},
decorativeFood;
for (var i = 0; i < 8; i++) {
_loop();
}
// Add bouncing animation to art studio button
function animateMenuArtButton() {
tween(menuArtButton, {
y: menuArtButton.y - 15
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(menuArtButton, {
y: menuArtButton.y + 15
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
animateMenuArtButton();
}
}
});
}
});
tween(menuArtButtonText, {
y: menuArtButtonText.y - 15
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(menuArtButtonText, {
y: menuArtButtonText.y + 15
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
animateMenuArtButton();
}
}
});
}
});
}
animateMenuArtButton();
// Add bouncing animation to mini games button
function animateMenuMiniGamesButton() {
tween(menuMiniGamesButton, {
y: menuMiniGamesButton.y - 18
}, {
duration: 1100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(menuMiniGamesButton, {
y: menuMiniGamesButton.y + 18
}, {
duration: 1100,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
animateMenuMiniGamesButton();
}
}
});
}
});
tween(menuMiniGamesButtonText, {
y: menuMiniGamesButtonText.y - 18
}, {
duration: 1100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(menuMiniGamesButtonText, {
y: menuMiniGamesButtonText.y + 18
}, {
duration: 1100,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
animateMenuMiniGamesButton();
}
}
});
}
});
}
animateMenuMiniGamesButton();
// Add bouncing animation to city builder button
function animateMenuCityBuilderButton() {
tween(menuCityBuilderButton, {
y: menuCityBuilderButton.y - 22
}, {
duration: 1300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(menuCityBuilderButton, {
y: menuCityBuilderButton.y + 22
}, {
duration: 1300,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
animateMenuCityBuilderButton();
}
}
});
}
});
tween(menuCityBuilderButtonText, {
y: menuCityBuilderButtonText.y - 22
}, {
duration: 1300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(menuCityBuilderButtonText, {
y: menuCityBuilderButtonText.y + 22
}, {
duration: 1300,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
animateMenuCityBuilderButton();
}
}
});
}
});
}
animateMenuCityBuilderButton();
// Add bouncing animation to boss fight button
function animateMenuBossFightButton() {
tween(menuBossFightButton, {
y: menuBossFightButton.y - 25
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(menuBossFightButton, {
y: menuBossFightButton.y + 25
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
animateMenuBossFightButton();
}
}
});
}
});
tween(menuBossFightButtonText, {
y: menuBossFightButtonText.y - 25
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(menuBossFightButtonText, {
y: menuBossFightButtonText.y + 25
}, {
duration: 1500,
easing: tween.easeInOut
});
}
});
}
animateMenuBossFightButton();
// Store menu elements for cleanup
gamePlayElements = [titleText, subtitleText, menuPlayButton, menuPlayButtonText, menuArtButton, menuArtButtonText, menuMiniGamesButton, menuMiniGamesButtonText, menuCityBuilderButton, menuCityBuilderButtonText, menuBossFightButton, menuBossFightButtonText].concat(decorativeItems);
}
function startFloatingAnimation() {
if (!menuSummer || gameState !== 'menu') return;
// Random floating movement - use full screen dimensions with boundaries
// Screen is 2048x2732, leave margin for Summer's size (200px)
var margin = 100;
var targetX = margin + Math.random() * (2048 - 2 * margin);
var targetY = margin + Math.random() * (2732 - 2 * margin);
tween(menuSummer, {
x: targetX,
y: targetY,
rotation: (Math.random() - 0.5) * 0.5
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Do a flip
if (!menuSummer || gameState !== 'menu') return;
tween(menuSummer, {
rotation: menuSummer.rotation + Math.PI * 2
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Continue floating
if (gameState === 'menu') {
startFloatingAnimation();
}
}
});
}
});
// Spawn floating hearts around Summer
if (Math.random() < 0.3) {
var menuHeart = new Heart();
menuHeart.x = menuSummer.x + (Math.random() - 0.5) * 150;
menuHeart.y = menuSummer.y + (Math.random() - 0.5) * 150;
game.addChild(menuHeart);
menuHeart.floatUp();
}
}
function startIndividualFloatingAnimation(summerChar) {
if (!summerChar || gameState !== 'menu') return;
// Random floating movement - use full screen dimensions with boundaries
// Screen is 2048x2732, leave margin for Summer's size (200px)
var margin = 100;
var targetX = margin + Math.random() * (2048 - 2 * margin);
var targetY = margin + Math.random() * (2732 - 2 * margin);
tween(summerChar, {
x: targetX,
y: targetY,
rotation: (Math.random() - 0.5) * 0.5
}, {
duration: 4000 + Math.random() * 3000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Do a gentle rotation
if (!summerChar || gameState !== 'menu') return;
tween(summerChar, {
rotation: summerChar.rotation + (Math.random() - 0.5) * Math.PI
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Continue floating
startIndividualFloatingAnimation(summerChar);
}
});
}
});
// Occasionally spawn floating hearts around this Summer
if (Math.random() < 0.2) {
var menuHeart = new Heart();
menuHeart.x = summerChar.x + (Math.random() - 0.5) * 150;
menuHeart.y = summerChar.y + (Math.random() - 0.5) * 150;
game.addChild(menuHeart);
menuHeart.floatUp();
}
}
function startArtStudio() {
// Store previous game state
var previousState = gameState;
// Remove menu elements if coming from menu
if (previousState === 'menu') {
for (var i = 0; i < gamePlayElements.length; i++) {
gamePlayElements[i].destroy();
}
gamePlayElements = [];
// Remove all floating summers
if (menuSummer) {
var children = game.children.slice();
for (var i = 0; i < children.length; i++) {
if (children[i] instanceof Summer) {
children[i].destroy();
}
}
menuSummer = null;
}
}
// If coming from gameplay, hide game UI elements but preserve Summer
if (previousState === 'playing') {
// Hide UI elements but don't destroy them
var gameChildren = game.children.slice();
for (var i = 0; i < gameChildren.length; i++) {
var child = gameChildren[i];
// Hide everything except Summer and hearts
if (!(child instanceof Summer) && !(child instanceof Heart)) {
child.visible = false;
}
}
}
// Create art studio elements
createArtStudio();
gameState = 'art';
}
function startMemoryGame() {
// Clean up mini games menu
for (var i = 0; i < miniGamesMenuElements.length; i++) {
miniGamesMenuElements[i].destroy();
}
miniGamesMenuElements = [];
// Initialize memory game
memoryGameActive = true;
memoryScore = 0;
memoryMovesCount = 0;
gameState = 'memory';
// Create game title
var memoryTitle = new Text2('MEMORY MATCH', {
size: 100,
fill: 0x4CAF50
});
memoryTitle.anchor.set(0.5, 0.5);
memoryTitle.x = 1024;
memoryTitle.y = 300;
game.addChild(memoryTitle);
memoryGameElements.push(memoryTitle);
// Create score display
var scoreText = new Text2('Score: 0 | Moves: 0', {
size: 60,
fill: 0x333333
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 1024;
scoreText.y = 450;
game.addChild(scoreText);
memoryGameElements.push(scoreText);
// Create 4x4 grid of cards
var cardValues = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8];
// Shuffle the array
for (var i = cardValues.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = cardValues[i];
cardValues[i] = cardValues[j];
cardValues[j] = temp;
}
var startX = 1024 - 4 * 140 / 2 + 70;
var startY = 800;
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++) {
var card = new MemoryCard();
card.x = startX + col * 140;
card.y = startY + row * 140;
card.cardValue = cardValues[row * 4 + col];
game.addChild(card);
memoryCards.push(card);
memoryGameElements.push(card);
}
}
// Create back button
var backButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
backButton.width = 200;
backButton.height = 80;
backButton.x = 1024;
backButton.y = 2500;
backButton.tint = 0x757575;
memoryGameElements.push(backButton);
var backButtonText = new Text2('BACK', {
size: 50,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = backButton.x;
backButtonText.y = backButton.y;
game.addChild(backButtonText);
memoryGameElements.push(backButtonText);
}
function startPatternGame() {
// Clean up mini games menu
for (var i = 0; i < miniGamesMenuElements.length; i++) {
miniGamesMenuElements[i].destroy();
}
miniGamesMenuElements = [];
// Initialize pattern game
patternGameActive = true;
patternLevel = 1;
patternScore = 0;
patternSequence = [];
playerSequence = [];
currentPatternIndex = 0;
showingPattern = false;
acceptingInput = false;
gameState = 'pattern';
// Create game title
var patternTitle = new Text2('PATTERN REPEAT', {
size: 100,
fill: 0x2196F3
});
patternTitle.anchor.set(0.5, 0.5);
patternTitle.x = 1024;
patternTitle.y = 300;
game.addChild(patternTitle);
patternGameElements.push(patternTitle);
// Create score and level display
var scoreText = new Text2('Level: 1 | Score: 0', {
size: 60,
fill: 0x333333
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 1024;
scoreText.y = 450;
game.addChild(scoreText);
patternGameElements.push(scoreText);
// Create instruction text
var instructionText = new Text2('Watch the pattern, then repeat it!', {
size: 50,
fill: 0x666666
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 550;
game.addChild(instructionText);
patternGameElements.push(instructionText);
// Create 4 colored buttons in a 2x2 grid
var buttonColors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00]; // Bright Red, Bright Green, Bright Blue, Bright Yellow
var buttonSize = 200;
var spacing = 250;
var startX = 1024 - spacing / 2;
var startY = 1200;
for (var i = 0; i < 4; i++) {
var button = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
button.width = buttonSize;
button.height = buttonSize;
button.x = startX + i % 2 * spacing;
button.y = startY + Math.floor(i / 2) * spacing;
button.tint = buttonColors[i];
button.buttonIndex = i;
button.originalTint = buttonColors[i];
button.originalScale = 1.0;
patternButtons.push(button);
patternGameElements.push(button);
}
// Create back button
var backButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
backButton.width = 200;
backButton.height = 80;
backButton.x = 1024;
backButton.y = 2500;
backButton.tint = 0x757575;
patternGameElements.push(backButton);
var backButtonText = new Text2('BACK', {
size: 50,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = backButton.x;
backButtonText.y = backButton.y;
game.addChild(backButtonText);
patternGameElements.push(backButtonText);
// Start first level
generateNewPattern();
}
function startCatchGame() {
// Clean up mini games menu
for (var i = 0; i < miniGamesMenuElements.length; i++) {
miniGamesMenuElements[i].destroy();
}
miniGamesMenuElements = [];
// Initialize catch game
catchGameActive = true;
catchScore = 0;
catchTimeLeft = 30;
fallingTreats = [];
catchGameTimer = 0;
gameState = 'catch';
// Create game title
var catchTitle = new Text2('CATCH THE TREATS', {
size: 100,
fill: 0xFF9800
});
catchTitle.anchor.set(0.5, 0.5);
catchTitle.x = 1024;
catchTitle.y = 300;
game.addChild(catchTitle);
catchGameElements.push(catchTitle);
// Create score and time display
var scoreText = new Text2('Score: 0 | Time: 30', {
size: 60,
fill: 0x333333
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 1024;
scoreText.y = 450;
game.addChild(scoreText);
catchGameElements.push(scoreText);
// Create instruction text
var instructionText = new Text2('Move Summer to catch falling treats!', {
size: 50,
fill: 0x666666
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 550;
game.addChild(instructionText);
catchGameElements.push(instructionText);
// Create Summer catcher at bottom
summerCatcher = game.addChild(new Summer());
summerCatcher.x = 1024;
summerCatcher.y = 2300;
summerCatcher.scaleX = 0.8;
summerCatcher.scaleY = 0.8;
catchGameElements.push(summerCatcher);
// Create back button
var backButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
backButton.width = 200;
backButton.height = 80;
backButton.x = 1024;
backButton.y = 2500;
backButton.tint = 0x757575;
catchGameElements.push(backButton);
var backButtonText = new Text2('BACK', {
size: 50,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = backButton.x;
backButtonText.y = backButton.y;
game.addChild(backButtonText);
catchGameElements.push(backButtonText);
}
function createMiniGamesMenu() {
// Store the previous state so we can return to it
previousGameState = gameState;
// Remove current menu elements if coming from main menu
if (gameState === 'menu') {
for (var i = 0; i < gamePlayElements.length; i++) {
gamePlayElements[i].destroy();
}
gamePlayElements = [];
// Remove all floating summers
if (menuSummer) {
var children = game.children.slice();
for (var i = 0; i < children.length; i++) {
if (children[i] instanceof Summer) {
children[i].destroy();
}
}
menuSummer = null;
}
}
// Create title
var miniGamesTitle = new Text2('MINI GAMES', {
size: 120,
fill: 0xFF6B35
});
miniGamesTitle.anchor.set(0.5, 0.5);
miniGamesTitle.x = 1024;
miniGamesTitle.y = 400;
game.addChild(miniGamesTitle);
miniGamesMenuElements.push(miniGamesTitle);
// Create subtitle
var miniGamesSubtitle = new Text2('Choose a fun mini game to play!', {
size: 60,
fill: 0x333333
});
miniGamesSubtitle.anchor.set(0.5, 0.5);
miniGamesSubtitle.x = 1024;
miniGamesSubtitle.y = 550;
game.addChild(miniGamesSubtitle);
miniGamesMenuElements.push(miniGamesSubtitle);
// Memory Game button
memoryGameButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
memoryGameButton.width = 500;
memoryGameButton.height = 150;
memoryGameButton.x = 1024;
memoryGameButton.y = 800;
memoryGameButton.tint = 0x4CAF50;
miniGamesMenuElements.push(memoryGameButton);
var memoryGameText = new Text2('MEMORY MATCH', {
size: 70,
fill: 0xFFFFFF
});
memoryGameText.anchor.set(0.5, 0.5);
memoryGameText.x = memoryGameButton.x;
memoryGameText.y = memoryGameButton.y;
game.addChild(memoryGameText);
miniGamesMenuElements.push(memoryGameText);
// Pattern Game button
patternGameButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
patternGameButton.width = 500;
patternGameButton.height = 150;
patternGameButton.x = 1024;
patternGameButton.y = 1000;
patternGameButton.tint = 0x2196F3;
miniGamesMenuElements.push(patternGameButton);
var patternGameText = new Text2('PATTERN REPEAT', {
size: 70,
fill: 0xFFFFFF
});
patternGameText.anchor.set(0.5, 0.5);
patternGameText.x = patternGameButton.x;
patternGameText.y = patternGameButton.y;
game.addChild(patternGameText);
miniGamesMenuElements.push(patternGameText);
// Catch Game button
catchGameButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
catchGameButton.width = 500;
catchGameButton.height = 150;
catchGameButton.x = 1024;
catchGameButton.y = 1200;
catchGameButton.tint = 0xFF9800;
miniGamesMenuElements.push(catchGameButton);
var catchGameText = new Text2('CATCH THE TREATS', {
size: 70,
fill: 0xFFFFFF
});
catchGameText.anchor.set(0.5, 0.5);
catchGameText.x = catchGameButton.x;
catchGameText.y = catchGameButton.y;
game.addChild(catchGameText);
miniGamesMenuElements.push(catchGameText);
// Pop Lock Game button
popLockGameButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
popLockGameButton.width = 500;
popLockGameButton.height = 150;
popLockGameButton.x = 1024;
popLockGameButton.y = 1400;
popLockGameButton.tint = 0x9C27B0;
miniGamesMenuElements.push(popLockGameButton);
var popLockGameText = new Text2('POP LOCK', {
size: 70,
fill: 0xFFFFFF
});
popLockGameText.anchor.set(0.5, 0.5);
popLockGameText.x = popLockGameButton.x;
popLockGameText.y = popLockGameButton.y;
game.addChild(popLockGameText);
miniGamesMenuElements.push(popLockGameText);
// Stacker Game button
stackerGameButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
stackerGameButton.width = 500;
stackerGameButton.height = 150;
stackerGameButton.x = 1024;
stackerGameButton.y = 1600;
stackerGameButton.tint = 0xFF4500; // Bright orange-red
miniGamesMenuElements.push(stackerGameButton);
var stackerGameText = new Text2('STACKER', {
size: 70,
fill: 0xFFFFFF
});
stackerGameText.anchor.set(0.5, 0.5);
stackerGameText.x = stackerGameButton.x;
stackerGameText.y = stackerGameButton.y;
game.addChild(stackerGameText);
miniGamesMenuElements.push(stackerGameText);
// Back button
var backToMainButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
backToMainButton.width = 300;
backToMainButton.height = 100;
backToMainButton.x = 1024;
backToMainButton.y = 1800;
backToMainButton.tint = 0x757575;
miniGamesMenuElements.push(backToMainButton);
var backToMainText = new Text2('BACK', {
size: 60,
fill: 0xFFFFFF
});
backToMainText.anchor.set(0.5, 0.5);
backToMainText.x = backToMainButton.x;
backToMainText.y = backToMainButton.y;
game.addChild(backToMainText);
miniGamesMenuElements.push(backToMainText);
// Add button animations
function animateMiniGameButtons() {
// Memory button animation
if (memoryGameButton && typeof tween === 'function') {
tween(memoryGameButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (memoryGameButton) {
tween(memoryGameButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'minigames') {
animateMiniGameButtons();
}
}
});
}
}
});
}
// Pattern button animation (offset timing)
LK.setTimeout(function () {
if (gameState === 'minigames') {
tween(patternGameButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(patternGameButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2000,
easing: tween.easeInOut
});
}
});
}
}, 700);
// Catch button animation (offset timing)
LK.setTimeout(function () {
if (gameState === 'minigames') {
tween(catchGameButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(catchGameButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2000,
easing: tween.easeInOut
});
}
});
}
}, 1400);
// Pop Lock button animation (offset timing)
LK.setTimeout(function () {
if (gameState === 'minigames' && popLockGameButton) {
tween(popLockGameButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (popLockGameButton) {
tween(popLockGameButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2000,
easing: tween.easeInOut
});
}
}
});
}
}, 2100);
// Stacker button animation (offset timing)
LK.setTimeout(function () {
if (gameState === 'minigames' && stackerGameButton) {
tween(stackerGameButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (stackerGameButton) {
tween(stackerGameButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2000,
easing: tween.easeInOut
});
}
}
});
}
}, 2800);
}
animateMiniGameButtons();
gameState = 'minigames';
}
function generateNewPattern() {
// Add one more button to the sequence
var randomButton = Math.floor(Math.random() * 4);
patternSequence.push(randomButton);
playerSequence = [];
currentPatternIndex = 0;
// Start showing the pattern after a brief delay
LK.setTimeout(function () {
showPattern();
}, 1000);
}
function showPattern() {
showingPattern = true;
acceptingInput = false;
currentPatternIndex = 0;
// Update instruction
var instructionElement = patternGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Watch the pattern...');
}
showNextPatternStep();
}
function showNextPatternStep() {
if (currentPatternIndex >= patternSequence.length) {
// Pattern shown completely, now accept player input
showingPattern = false;
acceptingInput = true;
currentPatternIndex = 0;
// Update instruction
var instructionElement = patternGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Now repeat the pattern!');
}
return;
}
var buttonIndex = patternSequence[currentPatternIndex];
var button = patternButtons[buttonIndex];
// Highlight button
tween(button, {
scaleX: 1.2,
scaleY: 1.2,
tint: 0xFFFFFF
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(button, {
scaleX: 1.0,
scaleY: 1.0,
tint: button.originalTint
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
currentPatternIndex++;
LK.setTimeout(function () {
showNextPatternStep();
}, 200);
}
});
}
});
}
function handlePatternButtonPress(buttonIndex) {
if (!acceptingInput || showingPattern) return;
var button = patternButtons[buttonIndex];
// Visual feedback for button press
tween(button, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(button, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
playerSequence.push(buttonIndex);
// Check if this button matches the pattern
if (buttonIndex !== patternSequence[playerSequence.length - 1]) {
// Wrong button - game over
handlePatternGameOver();
return;
}
// Check if pattern is complete
if (playerSequence.length === patternSequence.length) {
// Level complete!
patternLevel++;
patternScore += patternLevel * 10;
// Update score display
var scoreElement = patternGameElements[1];
if (scoreElement && scoreElement.setText) {
scoreElement.setText('Level: ' + patternLevel + ' | Score: ' + patternScore);
}
// Update instruction
var instructionElement = patternGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Great! Get ready for level ' + patternLevel + '...');
}
// Start next level after delay
LK.setTimeout(function () {
generateNewPattern();
}, 1500);
}
}
function handlePatternGameOver() {
acceptingInput = false;
showingPattern = false;
// Update instruction to show game over
var instructionElement = patternGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Game Over! Final Score: ' + patternScore);
}
// Flash all buttons red
for (var i = 0; i < patternButtons.length; i++) {
var button = patternButtons[i];
tween(button, {
tint: 0xFF0000
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function () {
tween(this, {
tint: this.originalTint
}, {
duration: 200,
easing: tween.easeIn
});
}.bind(button)
});
}
// Allow restart after delay
LK.setTimeout(function () {
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Click any button to play again!');
}
// Reset game state for restart
patternLevel = 1;
patternScore = 0;
patternSequence = [];
playerSequence = [];
acceptingInput = true;
// Update score display
var scoreElement = patternGameElements[1];
if (scoreElement && scoreElement.setText) {
scoreElement.setText('Level: 1 | Score: 0');
}
}, 2000);
}
function startStackerGame() {
// Clean up mini games menu
for (var i = 0; i < miniGamesMenuElements.length; i++) {
miniGamesMenuElements[i].destroy();
}
miniGamesMenuElements = [];
// Initialize stacker game with simplified variables
stackerGameActive = true;
stackerScore = 0;
stackerCurrentLevel = 1;
stackerBlocks = []; // Array to store stationary blocks for each level
stackerMovingBlocks = []; // Current moving blocks
stackerDirection = 1;
stackerSpeed = 3;
stackerIsMoving = false;
gameState = 'stacker';
// Create game title
var stackerTitle = new Text2('STACKER', {
size: 100,
fill: 0xFF4500
});
stackerTitle.anchor.set(0.5, 0.5);
stackerTitle.x = 1024;
stackerTitle.y = 300;
game.addChild(stackerTitle);
stackerGameElements.push(stackerTitle);
// Create score and level display
var scoreText = new Text2('Level: 1 | Score: 0', {
size: 60,
fill: 0x333333
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 1024;
scoreText.y = 450;
game.addChild(scoreText);
stackerGameElements.push(scoreText);
// Create instruction text
var instructionText = new Text2('Tap to stop the moving blocks!', {
size: 50,
fill: 0x666666
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 550;
game.addChild(instructionText);
stackerGameElements.push(instructionText);
// Create back button
var backButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
backButton.width = 200;
backButton.height = 80;
backButton.x = 1024;
backButton.y = 2500;
backButton.tint = 0x757575;
stackerGameElements.push(backButton);
var backButtonText = new Text2('BACK', {
size: 50,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = backButton.x;
backButtonText.y = backButton.y;
game.addChild(backButtonText);
stackerGameElements.push(backButtonText);
// Create the base foundation row
createStackerFoundation();
// Start first level
startStackerLevel();
}
function createStackerFoundation() {
// Create base foundation with 7 blocks
var baseY = 2200;
var baseBlocks = [];
var baseWidth = 7;
var blockWidth = 80;
var startX = 1024 - baseWidth * blockWidth / 2 + blockWidth / 2;
var _loop2 = function _loop2() {
function startPopLockGame() {
// Clean up mini games menu
for (var i = 0; i < miniGamesMenuElements.length; i++) {
miniGamesMenuElements[i].destroy();
}
miniGamesMenuElements = [];
// Initialize pop lock game
popLockGameActive = true;
popLockScore = 0;
popLockLevel = 1;
currentLockIndex = 0;
lockIndicators = [];
lockTargetZones = [];
lockMovingIndicator = null;
lockDirection = 1;
lockSpeed = 3;
isLockMoving = false;
locksCompleted = 0;
totalLocks = 3;
gameState = 'poplock';
// Create game title
var popLockTitle = new Text2('POP LOCK', {
size: 100,
fill: 0x9C27B0
});
popLockTitle.anchor.set(0.5, 0.5);
popLockTitle.x = 1024;
popLockTitle.y = 300;
game.addChild(popLockTitle);
popLockGameElements.push(popLockTitle);
// Create score and level display
var scoreText = new Text2('Level: 1 | Score: 0', {
size: 60,
fill: 0x333333
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 1024;
scoreText.y = 450;
game.addChild(scoreText);
popLockGameElements.push(scoreText);
// Create instruction text
var instructionText = new Text2('Click when the indicator hits the target zone!', {
size: 50,
fill: 0x666666
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 550;
game.addChild(instructionText);
popLockGameElements.push(instructionText);
// Create locks display
createPopLockInterface();
// Create back button
var backButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
backButton.width = 200;
backButton.height = 80;
backButton.x = 1024;
backButton.y = 2500;
backButton.tint = 0x757575;
popLockGameElements.push(backButton);
var backButtonText = new Text2('BACK', {
size: 50,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = backButton.x;
backButtonText.y = backButton.y;
game.addChild(backButtonText);
popLockGameElements.push(backButtonText);
// Start the first lock
startNextLock();
}
block = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
block.width = blockWidth;
block.height = 40;
block.x = startX + i * blockWidth;
block.y = baseY;
block.tint = 0x4CAF50; // Green foundation
stackerGameElements.push(block);
baseBlocks.push(block);
},
block;
for (var i = 0; i < baseWidth; i++) {
_loop2();
}
stackerBlocks[0] = baseBlocks; // Store foundation as level 0
}
function startStackerLevel() {
if (stackerCurrentLevel > 10) {
// Player reached the top!
handleStackerWin();
return;
}
// Clean up any existing moving blocks
for (var i = 0; i < stackerMovingBlocks.length; i++) {
stackerMovingBlocks[i].destroy();
}
stackerMovingBlocks = [];
// Get the width of previous level to determine current level's starting width
var previousLevel = stackerCurrentLevel - 1;
var previousWidth = stackerBlocks[previousLevel] ? stackerBlocks[previousLevel].length : 7;
var currentWidth = Math.max(1, Math.min(previousWidth, 7)); // Ensure at least 1 block, max 7
// Create moving blocks for current level
var currentY = 2200 - stackerCurrentLevel * 50;
var blockWidth = 80;
var startX = 1024 - currentWidth * blockWidth / 2 + blockWidth / 2;
// Level colors
var levelColors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFA500, 0x800080, 0xFFC0CB, 0x32CD32];
for (var i = 0; i < currentWidth; i++) {
var movingBlock = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
movingBlock.width = blockWidth;
movingBlock.height = 40;
movingBlock.x = startX + i * blockWidth;
movingBlock.y = currentY;
movingBlock.tint = levelColors[(stackerCurrentLevel - 1) % levelColors.length];
stackerGameElements.push(movingBlock);
stackerMovingBlocks.push(movingBlock);
}
// Start moving
stackerIsMoving = true;
stackerDirection = 1;
stackerSpeed = 3 + stackerCurrentLevel * 0.5; // Increase speed with level
}
function stopStackerBlocks() {
if (!stackerIsMoving || stackerMovingBlocks.length === 0) return;
stackerIsMoving = false;
// Find the previous level blocks to check alignment
var previousLevel = stackerCurrentLevel - 1;
var previousBlocks = stackerBlocks[previousLevel];
if (!previousBlocks || previousBlocks.length === 0) {
handleStackerGameOver();
return;
}
// Check which moving blocks align with previous level blocks
var alignedBlocks = [];
var blockWidth = 80;
for (var i = 0; i < stackerMovingBlocks.length; i++) {
var movingBlock = stackerMovingBlocks[i];
var isAligned = false;
// Check if this moving block overlaps with any previous level block
for (var j = 0; j < previousBlocks.length; j++) {
var prevBlock = previousBlocks[j];
var overlap = Math.abs(movingBlock.x - prevBlock.x);
if (overlap < blockWidth * 0.7) {
// 70% overlap required
isAligned = true;
break;
}
}
if (isAligned) {
alignedBlocks.push(movingBlock);
// Success animation
tween(movingBlock, {
scaleY: 1.3
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(movingBlock, {
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
} else {
// Block not aligned - animate it falling
tween(movingBlock, {
y: movingBlock.y + 400,
alpha: 0,
rotation: (Math.random() - 0.5) * Math.PI
}, {
duration: 1000,
easing: tween.easeIn,
onFinish: function onFinish() {
movingBlock.destroy();
}
});
}
}
// Store aligned blocks for this level
stackerBlocks[stackerCurrentLevel] = alignedBlocks;
// Check if any blocks remain
if (alignedBlocks.length === 0) {
// Game over - no blocks aligned
handleStackerGameOver();
return;
}
// Update score
stackerScore += alignedBlocks.length * stackerCurrentLevel * 10;
updateStackerScore();
// Move to next level after delay
LK.setTimeout(function () {
stackerCurrentLevel++;
startStackerLevel();
}, 1000);
}
function handleStackerGameOver() {
stackerGameActive = false;
var instructionElement = stackerGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Game Over! Final Score: ' + stackerScore + ' - Tap to restart');
}
// Flash remaining blocks red
for (var i = 0; i < stackerMovingBlocks.length; i++) {
var block = stackerMovingBlocks[i];
tween(block, {
tint: 0xFF0000
}, {
duration: 300,
easing: tween.easeOut
});
}
}
function handleStackerWin() {
stackerGameActive = false;
var instructionElement = stackerGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('YOU WIN! Perfect Stack! Score: ' + stackerScore + ' - Tap to restart');
}
// Celebration animation - make all blocks pulse with gold color
for (var level = 0; level < stackerBlocks.length; level++) {
if (stackerBlocks[level]) {
for (var i = 0; i < stackerBlocks[level].length; i++) {
var block = stackerBlocks[level][i];
if (block) {
tween(block, {
tint: 0xFFD700,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function () {
tween(this, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 500,
easing: tween.easeIn
});
}.bind(block)
});
}
}
}
}
}
function resetStackerGame() {
// Clean up all existing blocks
for (var level = 0; level < stackerBlocks.length; level++) {
if (stackerBlocks[level]) {
for (var i = 0; i < stackerBlocks[level].length; i++) {
if (stackerBlocks[level][i]) {
stackerBlocks[level][i].destroy();
}
}
}
}
for (var i = 0; i < stackerMovingBlocks.length; i++) {
stackerMovingBlocks[i].destroy();
}
// Reset game variables
stackerScore = 0;
stackerCurrentLevel = 1;
stackerBlocks = [];
stackerMovingBlocks = [];
stackerDirection = 1;
stackerSpeed = 3;
stackerIsMoving = false;
stackerGameActive = true;
// Update score display
updateStackerScore();
// Recreate foundation
createStackerFoundation();
// Reset instruction
var instructionElement = stackerGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Tap to stop the moving blocks!');
}
}
function updateStackerScore() {
var scoreElement = stackerGameElements[1];
if (scoreElement && scoreElement.setText) {
scoreElement.setText('Level: ' + stackerCurrentLevel + ' | Score: ' + stackerScore);
}
}
function createPopLockInterface() {
// Create 3 lock cylinders vertically arranged
var startY = 800;
var lockSpacing = 300;
for (var i = 0; i < totalLocks; i++) {
// Lock cylinder background (bright white circle)
var lockCylinder = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
lockCylinder.width = 600;
lockCylinder.height = 100;
lockCylinder.x = 1024;
lockCylinder.y = startY + i * lockSpacing;
lockCylinder.tint = 0xFFFFFF; // Bright white
popLockGameElements.push(lockCylinder);
// Target zone (bright red indicator area)
var targetZone = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
targetZone.width = 120;
targetZone.height = 80;
targetZone.x = 1024 + (Math.random() - 0.5) * 300; // Random position within cylinder
targetZone.y = startY + i * lockSpacing;
targetZone.tint = 0xFF0000; // Bright red
targetZone.visible = false; // Initially hidden
popLockGameElements.push(targetZone);
lockTargetZones.push(targetZone);
// Lock status indicator
var lockStatus = new Text2('LOCKED', {
size: 40,
fill: 0xFF0000
});
lockStatus.anchor.set(0.5, 0.5);
lockStatus.x = 1024;
lockStatus.y = startY + i * lockSpacing + 70;
game.addChild(lockStatus);
popLockGameElements.push(lockStatus);
lockIndicators.push(lockStatus);
}
}
function startNextLock() {
if (currentLockIndex >= totalLocks) {
// All locks completed - level complete!
handleLevelComplete();
return;
}
// Show target zone for current lock
lockTargetZones[currentLockIndex].visible = true;
// Create moving indicator for current lock
var startY = 800;
var lockSpacing = 300;
lockMovingIndicator = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
lockMovingIndicator.width = 20;
lockMovingIndicator.height = 80;
lockMovingIndicator.x = 1024 - 280; // Start at left edge
lockMovingIndicator.y = startY + currentLockIndex * lockSpacing;
lockMovingIndicator.tint = 0x00FF00; // Bright green
popLockGameElements.push(lockMovingIndicator);
// Start moving
isLockMoving = true;
lockDirection = 1;
lockSpeed = 3 + popLockLevel; // Increase speed with level
}
function handleLockSuccess() {
// Lock picked successfully!
popLockScore += 10 * popLockLevel;
lockIndicators[currentLockIndex].setText('UNLOCKED');
lockIndicators[currentLockIndex].tint = 0x4CAF50;
// Hide target zone
lockTargetZones[currentLockIndex].visible = false;
// Destroy moving indicator
if (lockMovingIndicator) {
lockMovingIndicator.destroy();
lockMovingIndicator = null;
}
isLockMoving = false;
locksCompleted++;
currentLockIndex++;
// Update score display
var scoreElement = popLockGameElements[1];
if (scoreElement && scoreElement.setText) {
scoreElement.setText('Level: ' + popLockLevel + ' | Score: ' + popLockScore);
}
// Animation for successful lock
tween(lockIndicators[currentLockIndex - 1], {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(lockIndicators[currentLockIndex - 1], {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// Start next lock after brief delay
LK.setTimeout(function () {
startNextLock();
}, 500);
}
function handleLockFailure() {
// Lock picking failed!
var instructionElement = popLockGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Missed! Try again!');
}
// Flash red
if (lockMovingIndicator) {
tween(lockMovingIndicator, {
tint: 0xFF0000
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
if (lockMovingIndicator) {
tween(lockMovingIndicator, {
tint: 0xFFFF00
}, {
duration: 200,
easing: tween.easeIn
});
}
}
});
}
// Reset instruction after delay
LK.setTimeout(function () {
var instructionElement = popLockGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Click when the indicator hits the target zone!');
}
}, 1500);
}
function handleLevelComplete() {
// All locks completed!
popLockLevel++;
currentLockIndex = 0;
locksCompleted = 0;
totalLocks = Math.min(5, 3 + Math.floor(popLockLevel / 2)); // Increase locks with level
// Update instruction
var instructionElement = popLockGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Level ' + popLockLevel + ' - Get ready!');
}
// Reset all lock indicators
for (var i = 0; i < lockIndicators.length; i++) {
lockIndicators[i].setText('LOCKED');
lockIndicators[i].tint = 0xFF0000;
}
// Start next level after delay
LK.setTimeout(function () {
// Clear old interface if we need more locks
if (totalLocks > lockIndicators.length) {
// Clean up old interface
for (var i = 0; i < popLockGameElements.length; i++) {
if (popLockGameElements[i] !== popLockGameElements[0] && popLockGameElements[i] !== popLockGameElements[1] && popLockGameElements[i] !== popLockGameElements[2] && popLockGameElements[i] !== popLockGameElements[popLockGameElements.length - 1] && popLockGameElements[i] !== popLockGameElements[popLockGameElements.length - 2]) {
popLockGameElements[i].destroy();
}
}
lockIndicators = [];
lockTargetZones = [];
// Recreate interface with more locks
createPopLockInterface();
}
var instructionElement = popLockGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Click when the indicator hits the target zone!');
}
startNextLock();
}, 2000);
}
function checkLockTiming() {
if (!isLockMoving || !lockMovingIndicator) return;
// Check if indicator is within target zone
var targetZone = lockTargetZones[currentLockIndex];
var indicatorX = lockMovingIndicator.x;
var targetLeft = targetZone.x - targetZone.width / 2;
var targetRight = targetZone.x + targetZone.width / 2;
if (indicatorX >= targetLeft && indicatorX <= targetRight) {
handleLockSuccess();
} else {
handleLockFailure();
}
}
function spawnTreat() {
var treat = game.addChild(LK.getAsset('food', {
anchorX: 0.5,
anchorY: 0.5
}));
treat.x = Math.random() * 1600 + 224; // Keep treats within screen bounds
treat.y = 200;
treat.fallSpeed = 3 + Math.random() * 4; // Random fall speed between 3-7
treat.caught = false;
// Make treats brighter with random bright colors
var brightColors = [0xFF6600, 0xFF0066, 0x66FF00, 0x0066FF, 0xFFFF00, 0xFF0000];
treat.tint = brightColors[Math.floor(Math.random() * brightColors.length)];
fallingTreats.push(treat);
catchGameElements.push(treat);
// Add spawning animation
treat.scaleX = 0;
treat.scaleY = 0;
tween(treat, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.bounceOut
});
}
function updateCityBuilderUI() {
// Update money display
if (cityBuilderElements[1] && cityBuilderElements[1].setText) {
cityBuilderElements[1].setText('Money: $' + cityMoney);
}
// Update population display
if (cityBuilderElements[2] && cityBuilderElements[2].setText) {
cityBuilderElements[2].setText('Population: ' + cityPopulation);
}
// Update happiness display
if (cityBuilderElements[3] && cityBuilderElements[3].setText) {
cityBuilderElements[3].setText('Happiness: ' + cityHappiness + '%');
}
// Add income based on buildings every few seconds
if (LK.ticks % 300 === 0) {
// Every 5 seconds
var income = 0;
for (var i = 0; i < cityBuildings.length; i++) {
var building = cityBuildings[i];
if (building.buildingType === 'shop') {
income += 10;
} else if (building.buildingType === 'office') {
income += 15;
} else if (building.buildingType === 'house') {
income += 5;
}
}
cityMoney += income;
if (income > 0) {
// Show income notification
var incomeText = new Text2('+$' + income, {
size: 40,
fill: 0x2E8B57
});
incomeText.anchor.set(0, 0.5);
incomeText.x = 400;
incomeText.y = 400;
game.addChild(incomeText);
tween(incomeText, {
alpha: 0,
y: incomeText.y - 50
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
incomeText.destroy();
}
});
}
}
}
function updateCatchGameScore() {
var scoreElement = catchGameElements[1];
if (scoreElement && scoreElement.setText) {
scoreElement.setText('Score: ' + catchScore + ' | Time: ' + catchTimeLeft);
}
}
function handleCatchGameOver() {
catchGameActive = false;
// Update instruction to show game over
var instructionElement = catchGameElements[2];
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Game Over! Final Score: ' + catchScore + ' treats caught!');
}
// Flash Summer for game over effect
if (summerCatcher) {
tween(summerCatcher, {
tint: 0xFF0000
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(summerCatcher, {
tint: 0xFFFFFF
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
// Allow restart after delay
LK.setTimeout(function () {
if (instructionElement && instructionElement.setText) {
instructionElement.setText('Click BACK to return to menu');
}
}, 2000);
}
function startBossFight() {
// Store previous game state
var previousState = gameState;
// Remove menu elements if coming from menu
if (previousState === 'menu') {
for (var i = 0; i < gamePlayElements.length; i++) {
gamePlayElements[i].destroy();
}
gamePlayElements = [];
// Remove all floating summers
if (menuSummer) {
var children = game.children.slice();
for (var i = 0; i < children.length; i++) {
if (children[i] instanceof Summer) {
children[i].destroy();
}
}
menuSummer = null;
}
}
// Create boss fight elements
createBossFight();
gameState = 'bossfight';
}
function createBossFight() {
bossFightActive = true;
playerHealth = 100;
playerBullets = [];
lanaBullets = [];
shootCooldown = 0;
// Create title
var bossTitle = new Text2('LANA BOSS FIGHT', {
size: 100,
fill: 0x8B0000
});
bossTitle.anchor.set(0.5, 0.5);
bossTitle.x = 1024;
bossTitle.y = 200;
game.addChild(bossTitle);
bossFightElements.push(bossTitle);
// Create boss health bar
var bossHealthBg = game.addChild(LK.getAsset('barBackground', {
anchorX: 0,
anchorY: 0
}));
bossHealthBg.x = 624;
bossHealthBg.y = 300;
bossHealthBg.width = 800;
bossHealthBg.height = 50;
bossFightElements.push(bossHealthBg);
bossHealthBar = game.addChild(LK.getAsset('bossHealthBar', {
anchorX: 0,
anchorY: 0
}));
bossHealthBar.x = 624;
bossHealthBar.y = 300;
bossFightElements.push(bossHealthBar);
var bossHealthText = new Text2('LANA HEALTH', {
size: 40,
fill: 0xFFFFFF
});
bossHealthText.anchor.set(0.5, 0.5);
bossHealthText.x = 1024;
bossHealthText.y = 280;
game.addChild(bossHealthText);
bossFightElements.push(bossHealthText);
// Create player health bar
var playerHealthBg = game.addChild(LK.getAsset('barBackground', {
anchorX: 0,
anchorY: 0
}));
playerHealthBg.x = 200;
playerHealthBg.y = 150;
playerHealthBg.width = 400;
playerHealthBg.height = 40;
bossFightElements.push(playerHealthBg);
playerHealthBar = game.addChild(LK.getAsset('playerHealthBar', {
anchorX: 0,
anchorY: 0
}));
playerHealthBar.x = 200;
playerHealthBar.y = 150;
bossFightElements.push(playerHealthBar);
var playerHealthText = new Text2('PLAYER HEALTH', {
size: 40,
fill: 0xFFFFFF
});
playerHealthText.anchor.set(0, 0.5);
playerHealthText.x = 650;
playerHealthText.y = 170;
game.addChild(playerHealthText);
bossFightElements.push(playerHealthText);
// Create Lana boss
lanaBoss = new LanaBoss();
lanaBoss.x = 1024;
lanaBoss.y = 600;
game.addChild(lanaBoss);
bossFightElements.push(lanaBoss);
// Create player fighter (Summer)
playerFighter = new Summer();
playerFighter.x = 1024;
playerFighter.y = 2300;
playerFighter.scaleX = 0.8;
playerFighter.scaleY = 0.8;
game.addChild(playerFighter);
bossFightElements.push(playerFighter);
// Create instructions
var instructions = new Text2('Move with touch/drag, tap to shoot!', {
size: 50,
fill: 0x333333
});
instructions.anchor.set(0.5, 0.5);
instructions.x = 1024;
instructions.y = 2600;
game.addChild(instructions);
bossFightElements.push(instructions);
// Create shoot button in bottom right corner
var shootButton = game.addChild(LK.getAsset('shootButton', {
anchorX: 0.5,
anchorY: 0.5
}));
shootButton.x = 1900;
shootButton.y = 2500;
bossFightElements.push(shootButton);
var shootButtonText = new Text2('SHOOT', {
size: 40,
fill: 0xFFFFFF
});
shootButtonText.anchor.set(0.5, 0.5);
shootButtonText.x = shootButton.x;
shootButtonText.y = shootButton.y;
game.addChild(shootButtonText);
bossFightElements.push(shootButtonText);
// Add pulsing animation to shoot button
function animateShootButton() {
tween(shootButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(shootButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'bossfight') {
animateShootButton();
}
}
});
}
});
}
animateShootButton();
// Create back button
var backButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
backButton.width = 200;
backButton.height = 80;
backButton.x = 150;
backButton.y = 2650;
backButton.tint = 0x757575;
bossFightElements.push(backButton);
var backButtonText = new Text2('BACK', {
size: 50,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = backButton.x;
backButtonText.y = backButton.y;
game.addChild(backButtonText);
bossFightElements.push(backButtonText);
}
function startCityBuilder() {
// Store previous game state
var previousState = gameState;
// Remove menu elements if coming from menu
if (previousState === 'menu') {
for (var i = 0; i < gamePlayElements.length; i++) {
gamePlayElements[i].destroy();
}
gamePlayElements = [];
// Remove all floating summers
if (menuSummer) {
var children = game.children.slice();
for (var i = 0; i < children.length; i++) {
if (children[i] instanceof Summer) {
children[i].destroy();
}
}
menuSummer = null;
}
}
// Create city builder elements
createCityBuilder();
gameState = 'citybuilder';
}
function createCityBuilder() {
cityBuilderActive = true;
// Create title
var cityTitle = new Text2('CITY BUILDER', {
size: 100,
fill: 0x4A90E2
});
cityTitle.anchor.set(0.5, 0.5);
cityTitle.x = 1024;
cityTitle.y = 200;
game.addChild(cityTitle);
cityBuilderElements.push(cityTitle);
// Create resource display
var moneyText = new Text2('Money: $' + cityMoney, {
size: 60,
fill: 0x2E8B57
});
moneyText.anchor.set(0, 0.5);
moneyText.x = 100;
moneyText.y = 400;
game.addChild(moneyText);
cityBuilderElements.push(moneyText);
var popText = new Text2('Population: ' + cityPopulation, {
size: 60,
fill: 0x4169E1
});
popText.anchor.set(0, 0.5);
popText.x = 100;
popText.y = 500;
game.addChild(popText);
cityBuilderElements.push(popText);
var happyText = new Text2('Happiness: ' + cityHappiness + '%', {
size: 60,
fill: 0xFF6347
});
happyText.anchor.set(0, 0.5);
happyText.x = 100;
happyText.y = 600;
game.addChild(happyText);
cityBuilderElements.push(happyText);
// Create building selection buttons
var buildingNames = ['house', 'shop', 'park', 'office', 'street'];
var buildingLabels = ['HOUSE ($100)', 'SHOP ($200)', 'PARK ($150)', 'OFFICE ($300)', 'STREET ($50)'];
for (var i = 0; i < buildingNames.length; i++) {
var button = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
button.width = 175; // Slightly smaller to fit 5 buttons
button.height = 80;
button.x = 150 + i * 175; // Adjusted spacing
button.y = 800;
button.tint = buildingTypes[buildingNames[i]].color;
button.buildingType = buildingNames[i];
cityBuilderElements.push(button);
var buttonText = new Text2(buildingLabels[i], {
size: 30,
// Slightly smaller text
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = button.x;
buttonText.y = button.y;
game.addChild(buttonText);
cityBuilderElements.push(buttonText);
}
// Create building area
var buildingArea = game.addChild(LK.getAsset('canvas', {
anchorX: 0.5,
anchorY: 0.5
}));
buildingArea.x = 1024;
buildingArea.y = 1600;
buildingArea.alpha = 0.3;
buildingArea.width = 1400;
buildingArea.height = 1000;
cityBuilderElements.push(buildingArea);
// Create instructions
var instructions = new Text2('Select a building type above, then click in the city area to build!', {
size: 50,
fill: 0x333333
});
instructions.anchor.set(0.5, 0.5);
instructions.x = 1024;
instructions.y = 950;
game.addChild(instructions);
cityBuilderElements.push(instructions);
// Create back button
var backButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
backButton.width = 200;
backButton.height = 80;
backButton.x = 1024;
backButton.y = 2600;
backButton.tint = 0x757575;
cityBuilderElements.push(backButton);
var backButtonText = new Text2('BACK', {
size: 50,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = backButton.x;
backButtonText.y = backButton.y;
game.addChild(backButtonText);
cityBuilderElements.push(backButtonText);
}
function createArtStudio() {
// Create title
var artTitle = new Text2('ART STUDIO', {
size: 100,
fill: 0x4B0082
});
artTitle.anchor.set(0.5, 0.5);
artTitle.x = 1024;
artTitle.y = 200;
game.addChild(artTitle);
artModeElements.push(artTitle);
// Create canvas
artCanvas = game.addChild(new ArtCanvas());
artCanvas.x = 1024;
artCanvas.y = 1200;
artModeElements.push(artCanvas);
// Create color palette
colorPalette = game.addChild(new ColorPalette());
colorPalette.x = 200;
colorPalette.y = 600;
artModeElements.push(colorPalette);
// Create brush
artBrush = game.addChild(new ArtBrush());
if (artBrush) {
artBrush.x = 200;
artBrush.y = 400;
artBrush.activate();
artModeElements.push(artBrush);
}
// Create or reposition Summer in art mode
if (!summer) {
summer = game.addChild(new Summer());
artModeElements.push(summer);
}
summer.x = 1800;
summer.y = 800;
summer.scaleX = 0.8;
summer.scaleY = 0.8;
summer.visible = true;
// Ensure Summer appears in front of canvas
game.removeChild(summer);
game.addChild(summer);
// Add art studio buttons
var backButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
backButton.width = 200;
backButton.height = 80;
backButton.x = 150;
backButton.y = 2600;
backButton.tint = 0x808080;
artModeElements.push(backButton);
var backButtonText = new Text2('BACK', {
size: 40,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = backButton.x;
backButtonText.y = backButton.y;
game.addChild(backButtonText);
artModeElements.push(backButtonText);
var clearButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
clearButton.width = 200;
clearButton.height = 80;
clearButton.x = 400;
clearButton.y = 2600;
clearButton.tint = 0xff4444;
artModeElements.push(clearButton);
var clearButtonText = new Text2('CLEAR', {
size: 40,
fill: 0xFFFFFF
});
clearButtonText.anchor.set(0.5, 0.5);
clearButtonText.x = clearButton.x;
clearButtonText.y = clearButton.y;
game.addChild(clearButtonText);
artModeElements.push(clearButtonText);
// Add instructions
var instructions = new Text2('Tap colors to change brush, draw on canvas!', {
size: 45,
fill: 0x333333
});
instructions.anchor.set(0.5, 0.5);
instructions.x = 1024;
instructions.y = 2650;
game.addChild(instructions);
artModeElements.push(instructions);
}
function startGame() {
// Music already playing - no transition needed
// Remove menu elements
for (var i = 0; i < gamePlayElements.length; i++) {
gamePlayElements[i].destroy();
}
gamePlayElements = [];
// Remove all floating summers
if (menuSummer) {
// Find and destroy all Summer instances in the game
var children = game.children.slice(); // Create a copy to iterate safely
for (var i = 0; i < children.length; i++) {
if (children[i] instanceof Summer) {
children[i].destroy();
}
}
menuSummer = null;
}
// Create game Summer
summer = game.addChild(new Summer());
summer.x = 1024;
summer.y = 2200;
// Create game UI and elements
createGameUI();
gameState = 'playing';
}
function createGameUI() {
// Create UI bars
var happinessBarBg = game.addChild(LK.getAsset('barBackground', {
anchorX: 0,
anchorY: 0
}));
happinessBarBg.x = 200;
happinessBarBg.y = 150;
happinessBarFill = game.addChild(LK.getAsset('happinessBar', {
anchorX: 0,
anchorY: 0
}));
happinessBarFill.x = 200;
happinessBarFill.y = 150;
var hungerBarBg = game.addChild(LK.getAsset('barBackground', {
anchorX: 0,
anchorY: 0
}));
hungerBarBg.x = 200;
hungerBarBg.y = 250;
hungerBarFill = game.addChild(LK.getAsset('hungerBar', {
anchorX: 0,
anchorY: 0
}));
hungerBarFill.x = 200;
hungerBarFill.y = 250;
// Create UI text
happinessText = new Text2('Happiness: 100', {
size: 50,
fill: 0x000000
});
happinessText.anchor.set(0, 0.5);
happinessText.x = 650;
happinessText.y = 170;
game.addChild(happinessText);
hungerText = new Text2('Hunger: 100', {
size: 50,
fill: 0x000000
});
hungerText.anchor.set(0, 0.5);
hungerText.x = 650;
hungerText.y = 270;
game.addChild(hungerText);
var instructionText = new Text2('Use buttons below to care for Summer!', {
size: 40,
fill: 0x333333
});
instructionText.anchor.set(0.5, 1);
instructionText.x = 1024;
instructionText.y = 2680;
game.addChild(instructionText);
// Create command buttons
var buttonWidth = 300;
var buttonHeight = 120;
var buttonY = 2400;
var buttonSpacing = 400;
// Store button references globally
window.petButton = null;
window.feedButton = null;
window.playButton = null;
window.groomButton = null;
// Pet button
var petButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
petButton.width = buttonWidth;
petButton.height = buttonHeight;
petButton.x = 300;
petButton.y = buttonY;
petButton.tint = 0xFF69B4;
window.petButton = petButton;
// Add gentle pulsing animation to pet button
function animatePetButton() {
tween(petButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(petButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'playing') {
animatePetButton();
}
}
});
}
});
}
animatePetButton();
var petButtonText = new Text2('PET', {
size: 50,
fill: 0xFFFFFF
});
petButtonText.anchor.set(0.5, 0.5);
petButtonText.x = petButton.x;
petButtonText.y = petButton.y;
game.addChild(petButtonText);
// Feed button
var feedButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
feedButton.width = buttonWidth;
feedButton.height = buttonHeight;
feedButton.x = 700;
feedButton.y = buttonY;
feedButton.tint = 0x32CD32;
window.feedButton = feedButton;
// Add floating animation to feed button
function animateFeedButton() {
tween(feedButton, {
y: buttonY - 10,
rotation: 0.05
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(feedButton, {
y: buttonY,
rotation: -0.05
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'playing') {
animateFeedButton();
}
}
});
}
});
}
animateFeedButton();
var feedButtonText = new Text2('FEED', {
size: 50,
fill: 0xFFFFFF
});
feedButtonText.anchor.set(0.5, 0.5);
feedButtonText.x = feedButton.x;
feedButtonText.y = feedButton.y;
game.addChild(feedButtonText);
// Play button
var playButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
playButton.width = buttonWidth;
playButton.height = buttonHeight;
playButton.x = 1100;
playButton.y = buttonY;
playButton.tint = 0x4169E1;
window.playButton = playButton;
var playButtonText = new Text2('PLAY', {
size: 50,
fill: 0xFFFFFF
});
playButtonText.anchor.set(0.5, 0.5);
playButtonText.x = playButton.x;
playButtonText.y = playButton.y;
game.addChild(playButtonText);
// Groom button
var groomButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
groomButton.width = buttonWidth;
groomButton.height = buttonHeight;
groomButton.x = 1500;
groomButton.y = buttonY;
groomButton.tint = 0x9370DB;
window.groomButton = groomButton;
// Add wobble animation to play button
var _animatePlayButton = function animatePlayButton() {
tween(playButton, {
rotation: 0.1,
scaleX: 1.02,
scaleY: 1.02
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(playButton, {
rotation: -0.1,
scaleX: 0.98,
scaleY: 0.98
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'playing') {
_animatePlayButton();
}
}
});
}
});
};
_animatePlayButton();
var groomButtonText = new Text2('GROOM', {
size: 50,
fill: 0xFFFFFF
});
groomButtonText.anchor.set(0.5, 0.5);
groomButtonText.x = groomButton.x;
groomButtonText.y = groomButton.y;
game.addChild(groomButtonText);
// Add gentle shake animation to groom button
function animateGroomButton() {
tween(groomButton, {
x: 1500 + 5,
rotation: 0.08
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(groomButton, {
x: 1500 - 5,
rotation: -0.08
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(groomButton, {
x: 1500,
rotation: 0
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'playing') {
LK.setTimeout(function () {
animateGroomButton();
}, 2000);
}
}
});
}
});
}
});
}
animateGroomButton();
// Back to Menu button
var backToMenuButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
backToMenuButton.width = 200;
backToMenuButton.height = 80;
backToMenuButton.x = 800;
backToMenuButton.y = 2580;
backToMenuButton.tint = 0x757575;
window.backToMenuButton = backToMenuButton;
var backToMenuButtonText = new Text2('MENU', {
size: 40,
fill: 0xFFFFFF
});
backToMenuButtonText.anchor.set(0.5, 0.5);
backToMenuButtonText.x = backToMenuButton.x;
backToMenuButtonText.y = backToMenuButton.y;
game.addChild(backToMenuButtonText);
// Art Studio button
var artStudioButton = game.addChild(LK.getAsset('barBackground', {
anchorX: 0.5,
anchorY: 0.5
}));
artStudioButton.width = 200;
artStudioButton.height = 80;
artStudioButton.x = 1250;
artStudioButton.y = 2580;
artStudioButton.tint = 0x9370DB;
window.artStudioButton = artStudioButton;
var artStudioButtonText = new Text2('ART', {
size: 40,
fill: 0xFFFFFF
});
artStudioButtonText.anchor.set(0.5, 0.5);
artStudioButtonText.x = artStudioButton.x;
artStudioButtonText.y = artStudioButton.y;
game.addChild(artStudioButtonText);
// Add gentle pulse animation to back to menu button
function animateBackToMenuButton() {
tween(backToMenuButton, {
scaleX: 1.03,
scaleY: 1.03
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(backToMenuButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'playing') {
animateBackToMenuButton();
}
}
});
}
});
tween(backToMenuButtonText, {
scaleX: 1.03,
scaleY: 1.03
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(backToMenuButtonText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2000,
easing: tween.easeInOut
});
}
});
}
animateBackToMenuButton();
// Add floating animation to art studio button
function animateArtStudioButton() {
tween(artStudioButton, {
y: 2570,
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 1400,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(artStudioButton, {
y: 2580,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1400,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'playing') {
animateArtStudioButton();
}
}
});
}
});
tween(artStudioButtonText, {
y: 2570
}, {
duration: 1400,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(artStudioButtonText, {
y: 2580
}, {
duration: 1400,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'playing') {
animateArtStudioButton();
}
}
});
}
});
}
animateArtStudioButton();
// Initial spawn
spawnFood();
spawnToy();
}
// Timers
var hungerTimer = 0;
var happinessTimer = 0;
var foodSpawnTimer = 0;
var toySpawnTimer = 0;
// City Builder mode variables
var cityBuilderActive = false;
var cityBuilderElements = [];
var cityBuildings = [];
var cityMoney = 1000;
var cityPopulation = 0;
var cityHappiness = 50;
var selectedBuildingType = 'house';
var buildingTypes = {
house: {
cost: 100,
color: 0x8B4513,
population: 4,
happiness: 2
},
shop: {
cost: 200,
color: 0x32CD32,
population: 0,
happiness: 5
},
park: {
cost: 150,
color: 0x228B22,
population: 0,
happiness: 8
},
office: {
cost: 300,
color: 0x708090,
population: 0,
happiness: 1
},
street: {
cost: 50,
color: 0x2F2F2F,
population: 0,
happiness: 1
}
};
// City people and cars
var cityPeople = [];
var cityCars = [];
var cityStreets = [];
// Initialize splash screen
createSplashScreen();
// Background music already playing
function updateHappinessBar() {
var percentage = happiness / 100;
if (happinessBarFill) {
// Stop any existing tween on the bar
tween.stop(happinessBarFill, {
width: true
});
// Animate the bar width change
tween(happinessBarFill, {
width: 400 * percentage
}, {
duration: 500,
easing: tween.easeOut
});
// Add a brief pulse effect
tween(happinessBarFill, {
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(happinessBarFill, {
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
if (happiness > 60) {
happinessBarFill.tint = 0x00FF00;
} else if (happiness > 30) {
happinessBarFill.tint = 0xFFFF00;
} else {
happinessBarFill.tint = 0xFF0000;
}
}
if (happinessText) {
happinessText.setText('Happiness: ' + happiness);
// Add text bounce effect
tween(happinessText, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(happinessText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
}
function updateHungerBar() {
var percentage = hunger / 100;
if (hungerBarFill) {
// Stop any existing tween on the bar
tween.stop(hungerBarFill, {
width: true
});
// Animate the bar width change
tween(hungerBarFill, {
width: 400 * percentage
}, {
duration: 500,
easing: tween.easeOut
});
// Add a brief pulse effect
tween(hungerBarFill, {
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(hungerBarFill, {
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
if (hunger > 60) {
hungerBarFill.tint = 0x00FF00;
} else if (hunger > 30) {
hungerBarFill.tint = 0xFFFF00;
} else {
hungerBarFill.tint = 0xFF0000;
}
}
if (hungerText) {
hungerText.setText('Hunger: ' + hunger);
// Add text bounce effect
tween(hungerText, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(hungerText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
}
function spawnFood() {
if (foods.length < 4) {
var food = new Food();
food.x = Math.random() * 1800 + 124;
food.y = Math.random() * 1000 + 400;
foods.push(food);
game.addChild(food);
// Start with food invisible and small
food.alpha = 0;
food.scaleX = 0;
food.scaleY = 0;
// Animate food appearing with bounce effect
tween(food, {
alpha: 1,
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(food, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
}
function spawnToy() {
if (toys.length < 2) {
var toy = new Toy();
toy.x = Math.random() * 1800 + 124;
toy.y = Math.random() * 1000 + 400;
toys.push(toy);
game.addChild(toy);
// Start with toy invisible and small
toy.alpha = 0;
toy.scaleX = 0;
toy.scaleY = 0;
// Animate toy appearing with elastic effect
tween(toy, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 400,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(toy, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
}
game.move = function (x, y, obj) {
if (gameState === 'art' && isDrawing && artCanvas) {
// Continue drawing on canvas
if (x >= 224 && x <= 1824 && y >= 600 && y <= 1800) {
var localX = x - artCanvas.x;
var localY = y - artCanvas.y;
artCanvas.addStroke(localX, localY);
// Play brush sound occasionally while drawing
if (Math.random() < 0.3) {
LK.getSound('paintbrush').play();
}
}
}
if (gameState === 'catch' && summerCatcher) {
// Move Summer catcher horizontally only, keep at bottom
summerCatcher.x = Math.max(100, Math.min(1948, x)); // Keep Summer within screen bounds
}
if (gameState === 'bossfight' && playerFighter) {
// Move player fighter horizontally only, keep at bottom
playerFighter.x = Math.max(100, Math.min(1948, x));
}
if (draggedToy) {
draggedToy.x = x;
draggedToy.y = y;
}
};
game.down = function (x, y, obj) {
// Handle menu state
if (gameState === 'menu') {
// Check for play button click (centered at 1024, 1300)
if (x >= 824 && x <= 1224 && y >= 1225 && y <= 1375) {
startGame();
return;
}
// Check for art studio button click (centered at 1024, 1500)
if (x >= 824 && x <= 1224 && y >= 1425 && y <= 1575) {
startArtStudio();
return;
}
// Check for mini games button click (centered at 1024, 1700)
if (x >= 824 && x <= 1224 && y >= 1625 && y <= 1775) {
createMiniGamesMenu();
return;
}
// Check for city builder button click (centered at 1024, 1900)
if (x >= 824 && x <= 1224 && y >= 1825 && y <= 1975) {
startCityBuilder();
return;
}
// Check for boss fight button click (centered at 1024, 2100)
if (x >= 824 && x <= 1224 && y >= 2025 && y <= 2175) {
startBossFight();
return;
}
return;
}
// Handle mini games menu state
if (gameState === 'minigames') {
// Check back button (1024, 1800)
if (x >= 874 && x <= 1174 && y >= 1750 && y <= 1850) {
// Clean up mini games menu
for (var i = 0; i < miniGamesMenuElements.length; i++) {
miniGamesMenuElements[i].destroy();
}
miniGamesMenuElements = [];
// Return to main menu
gameState = 'menu';
createMainMenu();
return;
}
// Check Memory Game button (1024, 800)
if (x >= 774 && x <= 1274 && y >= 725 && y <= 875) {
// Add click animation
tween(memoryGameButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(memoryGameButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
// Start Memory Game
LK.setTimeout(function () {
startMemoryGame();
}, 200);
return;
}
// Check Pattern Game button (1024, 1000)
if (x >= 774 && x <= 1274 && y >= 925 && y <= 1075) {
// Add click animation
tween(patternGameButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(patternGameButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
// Start Pattern Game
LK.setTimeout(function () {
startPatternGame();
}, 200);
return;
}
// Check Catch Game button (1024, 1200)
if (x >= 774 && x <= 1274 && y >= 1125 && y <= 1275) {
// Add click animation
tween(catchGameButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(catchGameButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
// Start Catch Game
LK.setTimeout(function () {
startCatchGame();
}, 200);
return;
}
// Check Pop Lock Game button (1024, 1400)
if (x >= 774 && x <= 1274 && y >= 1325 && y <= 1475) {
// Add click animation
tween(popLockGameButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(popLockGameButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
// Start Pop Lock Game
LK.setTimeout(function () {
startPopLockGame();
}, 200);
return;
}
// Check Stacker Game button (1024, 1600)
if (x >= 774 && x <= 1274 && y >= 1525 && y <= 1675) {
// Add click animation
tween(stackerGameButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(stackerGameButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
// Start Stacker Game
LK.setTimeout(function () {
startStackerGame();
}, 200);
return;
}
return;
}
// Handle memory game state
if (gameState === 'memory') {
// Check back button (1024, 2500)
if (x >= 924 && x <= 1124 && y >= 2460 && y <= 2540) {
// Clean up memory game
for (var i = 0; i < memoryGameElements.length; i++) {
memoryGameElements[i].destroy();
}
memoryGameElements = [];
memoryCards = [];
flippedCards = [];
memoryGameActive = false;
// Return to mini games menu
createMiniGamesMenu();
return;
}
return;
}
// Handle pattern game state
if (gameState === 'pattern') {
// Check back button (1024, 2500)
if (x >= 924 && x <= 1124 && y >= 2460 && y <= 2540) {
// Clean up pattern game
for (var i = 0; i < patternGameElements.length; i++) {
patternGameElements[i].destroy();
}
patternGameElements = [];
patternButtons = [];
patternGameActive = false;
// Return to mini games menu
createMiniGamesMenu();
return;
}
// Check pattern button clicks
if (patternButtons && patternButtons.length > 0) {
var buttonSize = 200;
var spacing = 250;
var startX = 1024 - spacing / 2;
var startY = 1200;
for (var i = 0; i < 4; i++) {
var buttonX = startX + i % 2 * spacing;
var buttonY = startY + Math.floor(i / 2) * spacing;
if (x >= buttonX - buttonSize / 2 && x <= buttonX + buttonSize / 2 && y >= buttonY - buttonSize / 2 && y <= buttonY + buttonSize / 2) {
if (acceptingInput && !showingPattern) {
handlePatternButtonPress(i);
} else if (!patternGameActive || patternSequence.length === 0) {
// Restart game
generateNewPattern();
}
return;
}
}
}
return;
}
// Handle catch game state
if (gameState === 'catch') {
// Check back button (1024, 2500)
if (x >= 924 && x <= 1124 && y >= 2460 && y <= 2540) {
// Clean up catch game
for (var i = 0; i < catchGameElements.length; i++) {
catchGameElements[i].destroy();
}
catchGameElements = [];
fallingTreats = [];
summerCatcher = null;
catchGameActive = false;
// Return to mini games menu
createMiniGamesMenu();
return;
}
return;
}
// Handle pop lock game state
if (gameState === 'poplock') {
// Check back button (1024, 2500)
if (x >= 924 && x <= 1124 && y >= 2460 && y <= 2540) {
// Clean up pop lock game
for (var i = 0; i < popLockGameElements.length; i++) {
popLockGameElements[i].destroy();
}
popLockGameElements = [];
lockIndicators = [];
lockTargetZones = [];
if (lockMovingIndicator) {
lockMovingIndicator.destroy();
lockMovingIndicator = null;
}
popLockGameActive = false;
isLockMoving = false;
// Return to mini games menu
createMiniGamesMenu();
return;
}
// Check for lock timing click
if (isLockMoving) {
checkLockTiming();
}
return;
}
// Handle stacker game state
if (gameState === 'stacker') {
// Check back button (1024, 2500)
if (x >= 924 && x <= 1124 && y >= 2460 && y <= 2540) {
// Clean up stacker game
for (var i = 0; i < stackerGameElements.length; i++) {
stackerGameElements[i].destroy();
}
stackerGameElements = [];
// Clean up blocks
for (var level = 0; level < stackerBlocks.length; level++) {
for (var j = 0; j < stackerBlocks[level].length; j++) {
if (stackerBlocks[level][j]) {
stackerBlocks[level][j].destroy();
}
}
}
for (var i = 0; i < stackerMovingBlocks.length; i++) {
stackerMovingBlocks[i].destroy();
}
stackerBlocks = [];
stackerMovingBlocks = [];
stackerGameActive = false;
stackerIsMoving = false;
// Return to mini games menu
createMiniGamesMenu();
return;
}
// Check for stacker click (stop blocks)
if (stackerIsMoving) {
stopStackerBlocks();
} else if (!stackerGameActive) {
// Restart game
resetStackerGame();
startStackerLevel();
}
return;
}
// Handle boss fight updates
if (gameState === 'bossfight' && bossFightActive) {
// Update shoot cooldown
if (shootCooldown > 0) {
shootCooldown--;
}
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
if (bullet.y < 0) {
// Bullet went off screen
bullet.destroy();
playerBullets.splice(i, 1);
var elementIndex = bossFightElements.indexOf(bullet);
if (elementIndex > -1) {
bossFightElements.splice(elementIndex, 1);
}
continue;
}
// Check collision with Lana boss
if (lanaBoss && bullet.intersects(lanaBoss)) {
// Hit the boss
lanaBoss.takeDamage(10);
bullet.destroy();
playerBullets.splice(i, 1);
var elementIndex = bossFightElements.indexOf(bullet);
if (elementIndex > -1) {
bossFightElements.splice(elementIndex, 1);
}
// Update boss health bar
if (bossHealthBar) {
var healthPercentage = lanaBoss.health / lanaBoss.maxHealth;
bossHealthBar.width = 800 * healthPercentage;
}
// Check if boss is defeated
if (lanaBoss.health <= 0) {
LK.showYouWin();
}
continue;
}
// Check collision with Lana bullets
for (var j = lanaBullets.length - 1; j >= 0; j--) {
var lanaBullet = lanaBullets[j];
if (bullet.intersects(lanaBullet)) {
// Bullets collide and destroy each other
bullet.destroy();
lanaBullet.destroy();
playerBullets.splice(i, 1);
lanaBullets.splice(j, 1);
// Remove from boss fight elements
var bulletIndex = bossFightElements.indexOf(bullet);
if (bulletIndex > -1) {
bossFightElements.splice(bulletIndex, 1);
}
var lanaBulletIndex = bossFightElements.indexOf(lanaBullet);
if (lanaBulletIndex > -1) {
bossFightElements.splice(lanaBulletIndex, 1);
}
break;
}
}
}
// Update Lana bullets
for (var i = lanaBullets.length - 1; i >= 0; i--) {
var bullet = lanaBullets[i];
if (bullet.y > 2732) {
// Bullet went off screen
bullet.destroy();
lanaBullets.splice(i, 1);
var elementIndex = bossFightElements.indexOf(bullet);
if (elementIndex > -1) {
bossFightElements.splice(elementIndex, 1);
}
continue;
}
// Check collision with player
if (playerFighter && bullet.intersects(playerFighter)) {
// Hit the player
playerHealth -= 15;
bullet.destroy();
lanaBullets.splice(i, 1);
var elementIndex = bossFightElements.indexOf(bullet);
if (elementIndex > -1) {
bossFightElements.splice(elementIndex, 1);
}
// Update player health bar
if (playerHealthBar) {
var healthPercentage = playerHealth / 100;
playerHealthBar.width = 400 * healthPercentage;
}
// Check if player is defeated
if (playerHealth <= 0) {
LK.showGameOver();
}
// Flash screen red briefly
LK.effects.flashScreen(0xff0000, 300);
}
}
return;
}
// Handle boss fight state
if (gameState === 'bossfight') {
// Check back button (150, 2650)
if (x >= 50 && x <= 250 && y >= 2610 && y <= 2690) {
// Clean up boss fight elements
for (var i = 0; i < bossFightElements.length; i++) {
bossFightElements[i].destroy();
}
bossFightElements = [];
playerBullets = [];
lanaBullets = [];
lanaBoss = null;
playerFighter = null;
bossFightActive = false;
// Return to menu
gameState = 'menu';
createMainMenu();
return;
}
// Check shoot button (1900, 2500)
if (x >= 1840 && x <= 1960 && y >= 2440 && y <= 2560) {
// Shoot button clicked - add visual feedback
var shootButton = bossFightElements.find(function (element) {
return element.x === 1900 && element.y === 250;
});
if (shootButton) {
tween(shootButton, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(shootButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
}
// Shoot player bullet if not in cooldown
if (shootCooldown <= 0) {
var bullet = new PlayerBullet();
bullet.x = playerFighter.x;
bullet.y = playerFighter.y - 50;
game.addChild(bullet);
playerBullets.push(bullet);
bossFightElements.push(bullet);
shootCooldown = 15; // Cooldown frames
LK.getSound('playerShoot').play();
}
return;
}
// General screen tap for shooting (keep as backup)
if (shootCooldown <= 0) {
var bullet = new PlayerBullet();
bullet.x = playerFighter.x;
bullet.y = playerFighter.y - 50;
game.addChild(bullet);
playerBullets.push(bullet);
bossFightElements.push(bullet);
shootCooldown = 15; // Cooldown frames
LK.getSound('playerShoot').play();
}
return;
}
// Handle city builder state
if (gameState === 'citybuilder') {
// Check back button (1024, 2600)
if (x >= 924 && x <= 1124 && y >= 2560 && y <= 2640) {
// Clean up city builder elements
for (var i = 0; i < cityBuilderElements.length; i++) {
cityBuilderElements[i].destroy();
}
cityBuilderElements = [];
for (var i = 0; i < cityBuildings.length; i++) {
cityBuildings[i].destroy();
}
cityBuildings = [];
// Clean up people and cars
for (var i = 0; i < cityPeople.length; i++) {
cityPeople[i].destroy();
}
cityPeople = [];
for (var i = 0; i < cityCars.length; i++) {
cityCars[i].destroy();
}
cityCars = [];
for (var i = 0; i < cityStreets.length; i++) {
cityStreets[i].destroy();
}
cityStreets = [];
cityBuilderActive = false;
// Reset city stats
cityMoney = 1000;
cityPopulation = 0;
cityHappiness = 50;
selectedBuildingType = 'house';
// Return to menu
gameState = 'menu';
createMainMenu();
return;
}
// Check building selection buttons (y = 800)
if (y >= 760 && y <= 840) {
var buildingNames = ['house', 'shop', 'park', 'office', 'street'];
for (var i = 0; i < buildingNames.length; i++) {
var buttonX = 150 + i * 175; // Adjusted spacing for 5 buttons
if (x >= buttonX - 87 && x <= buttonX + 87) {
selectedBuildingType = buildingNames[i];
// Visual feedback for selection
var button = cityBuilderElements[4 + i * 2]; // Get button element
if (button) {
tween(button, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(button, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
return;
}
}
}
// Check building area (1400x1000 centered at 1024, 1600)
if (x >= 324 && x <= 1724 && y >= 1100 && y <= 2100) {
// Try to build
var buildingCost = buildingTypes[selectedBuildingType].cost;
if (cityMoney >= buildingCost) {
// Create new building or street
if (selectedBuildingType === 'street') {
var newStreet = new Street();
newStreet.x = x;
newStreet.y = y;
game.addChild(newStreet);
cityStreets.push(newStreet);
cityBuilderElements.push(newStreet);
// Spawn cars on this street
if (Math.random() < 0.7) {
var newCar = new Car();
newCar.x = x + (Math.random() - 0.5) * 300;
newCar.y = y + (newCar.lane === 0 ? -15 : 15);
game.addChild(newCar);
cityCars.push(newCar);
cityBuilderElements.push(newCar);
}
} else {
var newBuilding = new CityBuilding(selectedBuildingType);
newBuilding.x = x;
newBuilding.y = y;
game.addChild(newBuilding);
cityBuildings.push(newBuilding);
newBuilding.constructBuilding();
// Spawn people near buildings with population
if (buildingTypes[selectedBuildingType].population > 0) {
var peopleToSpawn = Math.floor(buildingTypes[selectedBuildingType].population / 2);
for (var p = 0; p < peopleToSpawn; p++) {
var newPerson = new Person();
newPerson.x = x + (Math.random() - 0.5) * 100;
newPerson.y = y + 60;
game.addChild(newPerson);
cityPeople.push(newPerson);
cityBuilderElements.push(newPerson);
newPerson.startWalking();
}
}
}
// Update resources
cityMoney -= buildingCost;
cityPopulation += buildingTypes[selectedBuildingType].population;
cityHappiness = Math.min(100, cityHappiness + buildingTypes[selectedBuildingType].happiness);
// Update displays
updateCityBuilderUI();
// Play build sound
LK.getSound('play').play();
} else {
// Not enough money - show error
var errorText = new Text2('Not enough money!', {
size: 50,
fill: 0xFF0000
});
errorText.anchor.set(0.5, 0.5);
errorText.x = x;
errorText.y = y - 50;
game.addChild(errorText);
tween(errorText, {
alpha: 0,
y: errorText.y - 100
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
errorText.destroy();
}
});
}
return;
}
return;
}
// Handle art studio state
if (gameState === 'art') {
// Check back button (150, 2600)
if (x >= 50 && x <= 250 && y >= 2560 && y <= 2640) {
// Check if there are hidden game elements (indicating we came from gameplay)
var hasHiddenGameElements = false;
var gameChildren = game.children.slice();
for (var i = 0; i < gameChildren.length; i++) {
if (!gameChildren[i].visible && !(gameChildren[i] instanceof Summer) && !(gameChildren[i] instanceof Heart)) {
hasHiddenGameElements = true;
break;
}
}
// Clean up art studio elements
for (var i = 0; i < artModeElements.length; i++) {
// Don't destroy Summer if returning to gameplay
if (hasHiddenGameElements && artModeElements[i] instanceof Summer) {
continue;
}
artModeElements[i].destroy();
}
artModeElements = [];
artCanvas = null;
colorPalette = null;
artBrush = null;
if (hasHiddenGameElements) {
// Return to gameplay - restore UI visibility
for (var i = 0; i < gameChildren.length; i++) {
gameChildren[i].visible = true;
}
gameState = 'playing';
// Reposition Summer back to gameplay position
if (summer) {
summer.x = 1024;
summer.y = 2200;
summer.scaleX = 1.0;
summer.scaleY = 1.0;
}
} else {
// Return to menu
summer = null;
gameState = 'menu';
createMainMenu();
}
return;
}
// Check clear button (400, 2600)
if (x >= 300 && x <= 500 && y >= 2560 && y <= 2640) {
if (artCanvas) {
artCanvas.clearCanvas();
if (summer) {
summer.showSpeechBubble("Fresh canvas!");
}
}
return;
}
// Check color palette clicks
if (colorPalette && x >= 150 && x <= 450 && y >= 550 && y <= 750) {
for (var i = 0; i < colorPalette.colorButtons.length; i++) {
var colorButton = colorPalette.colorButtons[i];
var buttonX = colorPalette.x + colorButton.x;
var buttonY = colorPalette.y + colorButton.y;
if (x >= buttonX - 40 && x <= buttonX + 40 && y >= buttonY - 40 && y <= buttonY + 40) {
if (artCanvas) {
artCanvas.setColor(colorButton.colorValue);
// Visual feedback - make selected color button pulse
tween(colorButton, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(colorButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// Change brush color to match selected color
if (artBrush) {
artBrush.children[0].tint = colorButton.colorValue;
}
if (summer) {
var colorNames = ["red", "green", "blue", "cyan", "black", "white"];
summer.showSpeechBubble("Nice " + colorNames[i] + " color!");
}
}
return;
}
}
}
// Check canvas drawing area
if (artCanvas && x >= 224 && x <= 1824 && y >= 600 && y <= 1800) {
isDrawing = true;
lastDrawX = x;
lastDrawY = y;
var localX = x - artCanvas.x;
var localY = y - artCanvas.y;
artCanvas.addStroke(localX, localY);
LK.getSound('paintbrush').play();
return;
}
return;
}
// Handle gameplay state
if (gameState === 'playing') {
// Check button clicks
var buttonY = 2400;
var buttonHeight = 120;
var buttonWidth = 300;
// Check if clicking in button area
if (y >= buttonY - buttonHeight / 2 && y <= buttonY + buttonHeight / 2) {
// Pet button
if (x >= 300 - buttonWidth / 2 && x <= 300 + buttonWidth / 2) {
// Add button press animation
if (window.petButton) {
tween(window.petButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(window.petButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
}
summer.pet();
return;
}
// Feed button
if (x >= 700 - buttonWidth / 2 && x <= 700 + buttonWidth / 2) {
// Add button press animation
if (window.feedButton) {
tween(window.feedButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(window.feedButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
}
// Create food next to Summer
var foodToEat = new Food();
foodToEat.x = summer.x + 60;
foodToEat.y = summer.y - 50;
game.addChild(foodToEat);
// Animate food moving to Summer's mouth and shrinking
tween(foodToEat, {
x: summer.x,
y: summer.y - 80,
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Make food disappear with eating animation
tween(foodToEat, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
foodToEat.destroy();
}
});
}
});
hunger = Math.min(100, hunger + 20);
happiness = Math.min(100, happiness + 10);
updateHungerBar();
updateHappinessBar();
LK.getSound('eat').play();
LK.setTimeout(function () {
LK.getSound('yummy').play();
summer.showSpeechBubble("Yummy!");
}, 500);
return;
}
// Play button
if (x >= 1100 - buttonWidth / 2 && x <= 1100 + buttonWidth / 2) {
// Add button press animation
if (window.playButton) {
tween(window.playButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(window.playButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
}
happiness = Math.min(100, happiness + 15);
updateHappinessBar();
LK.getSound('play').play();
// Find nearest toy to chase
var nearestToy = null;
var nearestDistance = Infinity;
if (toys && toys.length > 0) {
for (var i = 0; i < toys.length; i++) {
var toy = toys[i];
if (toy && toy.x !== undefined && toy.y !== undefined) {
var distance = Math.sqrt(Math.pow(summer.x - toy.x, 2) + Math.pow(summer.y - toy.y, 2));
if (distance < nearestDistance) {
nearestDistance = distance;
nearestToy = toy;
}
}
}
}
// Chase the nearest toy if one exists
if (nearestToy && !summer.isAnimating) {
summer.isAnimating = true;
// Store original position
var originalX = summer.x;
var originalY = summer.y;
// Chase animation - move Summer towards the toy
tween(summer, {
x: nearestToy.x,
y: nearestToy.y
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Play animation when reaching the toy
summer.playAnimation();
// Return to original position after play animation
LK.setTimeout(function () {
tween(summer, {
x: originalX,
y: originalY
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
summer.isAnimating = false;
}
});
}, 900); // Wait for play animation to finish
}
});
} else {
summer.playAnimation();
}
return;
}
// Groom button
if (x >= 1500 - buttonWidth / 2 && x <= 1500 + buttonWidth / 2) {
// Add button press animation
if (window.groomButton) {
tween(window.groomButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(window.groomButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
}
happiness = Math.min(100, happiness + 8);
updateHappinessBar();
LK.getSound('groom').play();
summer.bounce();
summer.showSpeechBubble("So fresh!");
// Spawn grooming brush near Summer
var groomBrush = new GroomBrush();
groomBrush.x = summer.x - 80;
groomBrush.y = summer.y - 100;
game.addChild(groomBrush);
groomBrush.performGrooming();
return;
}
}
// Check for back to menu button click (centered at 800, 2580)
if (y >= 2540 && y <= 2620 && x >= 700 && x <= 900) {
// Add button press animation
if (window.backToMenuButton) {
tween(window.backToMenuButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(window.backToMenuButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
}
// Clean up game elements
var gameChildren = game.children.slice();
for (var i = 0; i < gameChildren.length; i++) {
if (!(gameChildren[i] instanceof Summer) && !(gameChildren[i] instanceof Heart)) {
gameChildren[i].destroy();
}
}
// Clean up arrays
foods = [];
toys = [];
hearts = [];
// Reset game variables
happiness = 100;
hunger = 100;
summer = null;
happinessBarFill = null;
hungerBarFill = null;
happinessText = null;
hungerText = null;
// Return to main menu
gameState = 'menu';
createMainMenu();
return;
}
// Check for art studio button click (centered at 1250, 2580)
if (y >= 2540 && y <= 2620 && x >= 1150 && x <= 1350) {
// Add button press animation
if (window.artStudioButton) {
tween(window.artStudioButton, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(window.artStudioButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
}
// Transition to art studio
startArtStudio();
return;
}
// Check if clicking on a toy
if (toys && toys.length > 0) {
for (var i = 0; i < toys.length; i++) {
var toy = toys[i];
if (toy && toy.x !== undefined && toy.y !== undefined) {
var distance = Math.sqrt(Math.pow(x - toy.x, 2) + Math.pow(y - toy.y, 2));
if (distance < 50) {
draggedToy = toy;
break;
}
}
}
}
}
};
game.up = function (x, y, obj) {
if (gameState === 'art') {
isDrawing = false;
if (summer && Math.random() < 0.4) {
var encouragements = ["Beautiful!", "Amazing art!", "So creative!", "I love it!"];
var randomEncouragement = encouragements[Math.floor(Math.random() * encouragements.length)];
summer.showSpeechBubble(randomEncouragement);
}
}
if (draggedToy) {
draggedToy.checkPlayInteraction();
draggedToy = null;
}
};
game.update = function () {
// Handle mini games menu mode
if (gameState === 'minigames') {
// Add gentle floating animation to title
if (LK.ticks % 300 === 0) {
var titleElement = miniGamesMenuElements[0]; // The title
if (titleElement) {
tween(titleElement, {
y: titleElement.y - 10
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(titleElement, {
y: titleElement.y + 10
}, {
duration: 1500,
easing: tween.easeInOut
});
}
});
}
}
return;
}
// Handle memory game mode
if (gameState === 'memory' && memoryGameActive) {
// Check for flipped cards
var currentFlipped = [];
for (var i = 0; i < memoryCards.length; i++) {
if (memoryCards[i].isFlipped && !memoryCards[i].matched) {
currentFlipped.push(memoryCards[i]);
}
}
// If two cards are flipped, check for match
if (currentFlipped.length === 2 && flippedCards.length < 2) {
flippedCards = currentFlipped.slice();
memoryMovesCount++;
// Update score display
var scoreElement = memoryGameElements[1];
if (scoreElement && scoreElement.setText) {
scoreElement.setText('Score: ' + memoryScore + ' | Moves: ' + memoryMovesCount);
}
LK.setTimeout(function () {
if (flippedCards[0].cardValue === flippedCards[1].cardValue) {
// Match found
flippedCards[0].setMatched();
flippedCards[1].setMatched();
memoryScore += 10;
// Check if game is complete
var allMatched = true;
for (var i = 0; i < memoryCards.length; i++) {
if (!memoryCards[i].matched) {
allMatched = false;
break;
}
}
if (allMatched) {
LK.setTimeout(function () {
// Game complete - show victory message
var victoryText = new Text2('YOU WIN!', {
size: 120,
fill: 0xFFD700
});
victoryText.anchor.set(0.5, 0.5);
victoryText.x = 1024;
victoryText.y = 1366;
game.addChild(victoryText);
memoryGameElements.push(victoryText);
// Animate victory text
tween(victoryText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.bounceOut
});
}, 500);
}
} else {
// No match - flip cards back
flippedCards[0].flipBack();
flippedCards[1].flipBack();
}
flippedCards = [];
}, 1000);
}
return;
}
// Handle pattern game mode
if (gameState === 'pattern' && patternGameActive) {
// Add gentle pulsing animation to pattern buttons when waiting for input
if (acceptingInput && !showingPattern && LK.ticks % 120 === 0) {
for (var i = 0; i < patternButtons.length; i++) {
var button = patternButtons[i];
if (button && !button.isAnimating) {
button.isAnimating = true;
tween(button, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function () {
tween(this, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function () {
this.isAnimating = false;
}.bind(this)
});
}.bind(button)
});
}
}
}
return;
}
// Handle pop lock game mode
if (gameState === 'poplock' && popLockGameActive) {
// Move the indicator back and forth
if (isLockMoving && lockMovingIndicator) {
lockMovingIndicator.x += lockSpeed * lockDirection;
// Bounce off edges
var leftEdge = 1024 - 280;
var rightEdge = 1024 + 280;
if (lockMovingIndicator.x >= rightEdge) {
lockMovingIndicator.x = rightEdge;
lockDirection = -1;
} else if (lockMovingIndicator.x <= leftEdge) {
lockMovingIndicator.x = leftEdge;
lockDirection = 1;
}
}
return;
}
// Handle stacker game mode
if (gameState === 'stacker' && stackerGameActive) {
// Move the blocks back and forth
if (stackerIsMoving && stackerMovingBlocks.length > 0) {
var blockWidth = 80;
var gameAreaWidth = 600; // Total area for movement
var leftBound = 1024 - gameAreaWidth / 2;
var rightBound = 1024 + gameAreaWidth / 2;
// Move all blocks in the current row together
for (var i = 0; i < stackerMovingBlocks.length; i++) {
stackerMovingBlocks[i].x += stackerSpeed * stackerDirection;
}
// Check boundaries using first and last blocks
if (stackerMovingBlocks.length > 0) {
var firstBlock = stackerMovingBlocks[0];
var lastBlock = stackerMovingBlocks[stackerMovingBlocks.length - 1];
var groupWidth = (stackerMovingBlocks.length - 1) * blockWidth;
// Check if hitting right boundary
if (lastBlock.x + blockWidth / 2 >= rightBound) {
// Adjust position and reverse direction
var adjustment = lastBlock.x + blockWidth / 2 - rightBound;
for (var i = 0; i < stackerMovingBlocks.length; i++) {
stackerMovingBlocks[i].x -= adjustment;
}
stackerDirection = -1;
}
// Check if hitting left boundary
else if (firstBlock.x - blockWidth / 2 <= leftBound) {
// Adjust position and reverse direction
var adjustment = leftBound - (firstBlock.x - blockWidth / 2);
for (var i = 0; i < stackerMovingBlocks.length; i++) {
stackerMovingBlocks[i].x += adjustment;
}
stackerDirection = 1;
}
}
}
return;
}
// Handle catch game mode
if (gameState === 'catch' && catchGameActive) {
catchGameTimer++;
// Decrease time every second (60 ticks)
if (catchGameTimer >= 60) {
catchTimeLeft--;
updateCatchGameScore();
catchGameTimer = 0;
// Check if time is up
if (catchTimeLeft <= 0) {
handleCatchGameOver();
}
}
// Spawn treats periodically
if (LK.ticks % 90 === 0 && catchTimeLeft > 0) {
// Spawn every 1.5 seconds
spawnTreat();
}
// Update falling treats
for (var i = fallingTreats.length - 1; i >= 0; i--) {
var treat = fallingTreats[i];
if (!treat || treat.caught) continue;
// Move treat down
treat.y += treat.fallSpeed;
// Check collision with Summer
if (summerCatcher && !treat.caught) {
var distance = Math.sqrt(Math.pow(treat.x - summerCatcher.x, 2) + Math.pow(treat.y - summerCatcher.y, 2));
if (distance < 80) {
// Treat caught!
treat.caught = true;
catchScore++;
updateCatchGameScore();
// Animate treat being caught
tween(treat, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0,
y: treat.y - 50
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
treat.destroy();
}
});
// Remove from array
fallingTreats.splice(i, 1);
catchGameElements.splice(catchGameElements.indexOf(treat), 1);
// Summer celebration
if (summerCatcher) {
tween(summerCatcher, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(summerCatcher, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
}
continue;
}
}
// Remove treats that fell off screen
if (treat.y > 2732) {
treat.destroy();
fallingTreats.splice(i, 1);
var elementIndex = catchGameElements.indexOf(treat);
if (elementIndex > -1) {
catchGameElements.splice(elementIndex, 1);
}
}
}
return;
}
// Handle city builder mode
if (gameState === 'citybuilder' && cityBuilderActive) {
// Update city economics and happiness
updateCityBuilderUI();
// Update people walking
for (var i = 0; i < cityPeople.length; i++) {
if (cityPeople[i] && typeof cityPeople[i].update === 'function') {
cityPeople[i].update();
}
}
// Update cars driving
for (var i = 0; i < cityCars.length; i++) {
if (cityCars[i] && typeof cityCars[i].update === 'function') {
cityCars[i].update();
}
}
// Randomly spawn more people and cars
if (LK.ticks % 900 === 0 && cityBuildings.length > 0) {
// Every 15 seconds
// Spawn a person near a random building
if (cityPeople.length < cityPopulation / 2) {
var randomBuilding = cityBuildings[Math.floor(Math.random() * cityBuildings.length)];
if (randomBuilding) {
var newPerson = new Person();
newPerson.x = randomBuilding.x + (Math.random() - 0.5) * 100;
newPerson.y = randomBuilding.y + 60;
game.addChild(newPerson);
cityPeople.push(newPerson);
cityBuilderElements.push(newPerson);
newPerson.startWalking();
}
}
}
if (LK.ticks % 600 === 0 && cityStreets.length > 0) {
// Every 10 seconds
// Spawn a car on a random street
if (cityCars.length < cityStreets.length * 2) {
var randomStreet = cityStreets[Math.floor(Math.random() * cityStreets.length)];
if (randomStreet) {
var newCar = new Car();
newCar.x = randomStreet.x + (Math.random() - 0.5) * 300;
newCar.y = randomStreet.y + (newCar.lane === 0 ? -15 : 15);
game.addChild(newCar);
cityCars.push(newCar);
cityBuilderElements.push(newCar);
}
}
}
// Add gentle building animations
if (LK.ticks % 240 === 0 && cityBuildings.length > 0) {
var randomBuilding = cityBuildings[Math.floor(Math.random() * cityBuildings.length)];
if (randomBuilding && !randomBuilding.isAnimating) {
randomBuilding.isAnimating = true;
tween(randomBuilding, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(randomBuilding, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
randomBuilding.isAnimating = false;
}
});
}
});
}
}
return;
}
// Handle art studio mode
if (gameState === 'art') {
// Add gentle swaying animation to Summer in art mode
if (summer && !summer.isAnimating && LK.ticks % 200 === 0) {
tween(summer, {
rotation: (Math.random() - 0.5) * 0.1
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(summer, {
rotation: 0
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
}
// Animate art brush
if (artBrush && artBrush.rotation !== undefined && LK.ticks % 120 === 0) {
tween(artBrush, {
rotation: artBrush.rotation + 0.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (artBrush && artBrush.rotation !== undefined) {
tween(artBrush, {
rotation: artBrush.rotation - 0.2
}, {
duration: 500,
easing: tween.easeInOut
});
}
}
});
}
return;
}
// Only run game logic during gameplay
if (gameState === 'playing') {
// Add idle breathing animation to Summer
if (summer && !summer.isAnimating && LK.ticks % 180 === 0) {
tween(summer, {
scaleY: 1.02
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(summer, {
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
}
// Update timers
hungerTimer++;
happinessTimer++;
foodSpawnTimer++;
toySpawnTimer++;
// Hunger decreases every 5 seconds (300 ticks)
if (hungerTimer >= 300) {
hunger = Math.max(0, hunger - 1);
updateHungerBar();
hungerTimer = 0;
}
// Happiness decreases every 10 seconds (600 ticks) or faster when hungry
var happinessDecayRate = hunger < 30 ? 300 : 600;
if (happinessTimer >= happinessDecayRate) {
happiness = Math.max(0, happiness - 1);
updateHappinessBar();
happinessTimer = 0;
}
// Spawn food every 30 seconds (1800 ticks)
if (foodSpawnTimer >= 1800) {
spawnFood();
foodSpawnTimer = 0;
}
// Spawn toys every 45 seconds (2700 ticks)
if (toySpawnTimer >= 2700) {
spawnToy();
toySpawnTimer = 0;
}
// Update floating hearts
if (hearts && hearts.length > 0) {
for (var i = hearts.length - 1; i >= 0; i--) {
var heart = hearts[i];
if (heart && heart.alpha !== undefined && heart.alpha === 1 && typeof heart.floatUp === 'function') {
heart.floatUp();
}
}
}
// Check game over condition
if (happiness <= 0 && hunger <= 0) {
LK.showGameOver();
}
}
};
Pink heart no outline or shine. In-Game asset. 2d. High contrast. No shadows
Dog food. In-Game asset. 2d. High contrast. No shadows
Dog groom brush. In-Game asset. 2d. High contrast. No shadows
Pink tennis ball. In-Game asset. 2d. High contrast. No shadows
Car. In-Game asset. 2d. High contrast. No shadows
Full body person. In-Game asset. 2d. High contrast. No shadows