/****
* 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