/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var DirectionalButton = Container.expand(function (direction) { var self = Container.call(this); var buttonGraphics = self.attachAsset(direction + 'button', { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2(direction.toUpperCase(), { size: 30, fill: 0x000000 }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.direction = direction; self.down = function (x, y, obj) { if (selectedPuppy && selectedPuppy.isSelected) { var moveDistance = 60; switch (self.direction) { case 'up': selectedPuppy.y -= moveDistance; break; case 'down': selectedPuppy.y += moveDistance; break; case 'left': selectedPuppy.x -= moveDistance; break; case 'right': selectedPuppy.x += moveDistance; break; } // Keep puppy within bounds selectedPuppy.x = Math.max(60, Math.min(1988, selectedPuppy.x)); selectedPuppy.y = Math.max(60, Math.min(2400, selectedPuppy.y)); } }; return self; }); var DragonPuppy = Container.expand(function () { var self = Container.call(this); var puppyGraphics = self.attachAsset('dragonpuppy', { anchorX: 0.5, anchorY: 0.5 }); puppyGraphics.tint = 0xff4444; // Red tint for dragon var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley']; self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)]; self.isSelected = false; self.moveSpeed = 8; self.lastX = 0; self.lastY = 0; self.type = 'dragon'; var nameText = new Text2(self.name + ' [Dragon]', { size: 35, fill: 0xff4444 }); nameText.anchor.set(0.5, 0.5); nameText.y = -80; self.addChild(nameText); self.down = function (x, y, obj) { selectedPuppy = self; // Clear all selections for (var i = 0; i < puppies.length; i++) { puppies[i].isSelected = false; puppies[i].tint = 0xFFFFFF; } for (var i = 0; i < ghostPuppies.length; i++) { ghostPuppies[i].isSelected = false; ghostPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < dragonPuppies.length; i++) { dragonPuppies[i].isSelected = false; dragonPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < sirenPuppies.length; i++) { sirenPuppies[i].isSelected = false; sirenPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < vampirePuppies.length; i++) { vampirePuppies[i].isSelected = false; vampirePuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < legendaryPuppies.length; i++) { legendaryPuppies[i].isSelected = false; legendaryPuppies[i].tint = 0xFFFFFF; } self.isSelected = true; self.tint = 0xFFFF00; }; self.moveTowards = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.moveSpeed) { self.x += dx / distance * self.moveSpeed; self.y += dy / distance * self.moveSpeed; } else { self.x = targetX; self.y = targetY; } }; return self; }); var Eva = Container.expand(function () { var self = Container.call(this); var evaGraphics = self.attachAsset('eva', { anchorX: 0.5, anchorY: 0.5 }); var nameText = new Text2('Eva', { size: 40, fill: 0x9932CC }); nameText.anchor.set(0.5, 0.5); nameText.y = -100; self.addChild(nameText); return self; }); var Gabriel = Container.expand(function () { var self = Container.call(this); var gabrielGraphics = self.attachAsset('gabriel', { anchorX: 0.5, anchorY: 0.5 }); var nameText = new Text2('Gabriel', { size: 40, fill: 0x8B0000 }); nameText.anchor.set(0.5, 0.5); nameText.y = -100; self.addChild(nameText); self.moveSpeed = 4; self.targetPuppy = null; self.update = function () { if (selectedPuppy && selectedPuppy.isSelected) { self.targetPuppy = selectedPuppy; } if (self.targetPuppy) { var dx = self.targetPuppy.x - self.x; var dy = self.targetPuppy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.moveSpeed) { self.x += dx / distance * self.moveSpeed; self.y += dy / distance * self.moveSpeed; } } }; return self; }); var GhostPuppy = Container.expand(function () { var self = Container.call(this); var puppyGraphics = self.attachAsset('ghostpuppy', { anchorX: 0.5, anchorY: 0.5 }); puppyGraphics.alpha = 0.7; // Semi-transparent for ghost effect var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley']; self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)]; self.age = Math.floor(Math.random() * 20) + 1; // Random age between 1-20 months self.isSelected = false; self.moveSpeed = 8; self.lastX = 0; self.lastY = 0; self.type = 'ghost'; var nameText = new Text2(self.name + ' (' + self.age + ' mois) [Fantôme]', { size: 35, fill: 0x9999ff }); nameText.anchor.set(0.5, 0.5); nameText.y = -80; self.addChild(nameText); self.down = function (x, y, obj) { selectedPuppy = self; // Clear all selections for (var i = 0; i < puppies.length; i++) { puppies[i].isSelected = false; puppies[i].tint = 0xFFFFFF; } for (var i = 0; i < ghostPuppies.length; i++) { ghostPuppies[i].isSelected = false; ghostPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < dragonPuppies.length; i++) { dragonPuppies[i].isSelected = false; dragonPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < sirenPuppies.length; i++) { sirenPuppies[i].isSelected = false; sirenPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < vampirePuppies.length; i++) { vampirePuppies[i].isSelected = false; vampirePuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < legendaryPuppies.length; i++) { legendaryPuppies[i].isSelected = false; legendaryPuppies[i].tint = 0xFFFFFF; } self.isSelected = true; self.tint = 0xFFFF00; }; self.moveTowards = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.moveSpeed) { self.x += dx / distance * self.moveSpeed; self.y += dy / distance * self.moveSpeed; } else { self.x = targetX; self.y = targetY; } }; return self; }); var LegendaryPuppy = Container.expand(function () { var self = Container.call(this); var puppyGraphics = self.attachAsset('legendarypuppy', { anchorX: 0.5, anchorY: 0.5 }); puppyGraphics.tint = 0xFFD700; // Gold tint for legendary var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley']; self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)]; self.isSelected = false; self.moveSpeed = 8; self.lastX = 0; self.lastY = 0; self.type = 'legendary'; var nameText = new Text2(self.name + ' [LÉGENDAIRE]', { size: 35, fill: 0xFFD700 }); nameText.anchor.set(0.5, 0.5); nameText.y = -80; self.addChild(nameText); self.down = function (x, y, obj) { selectedPuppy = self; // Clear all selections for (var i = 0; i < puppies.length; i++) { puppies[i].isSelected = false; puppies[i].tint = 0xFFFFFF; } for (var i = 0; i < ghostPuppies.length; i++) { ghostPuppies[i].isSelected = false; ghostPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < dragonPuppies.length; i++) { dragonPuppies[i].isSelected = false; dragonPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < sirenPuppies.length; i++) { sirenPuppies[i].isSelected = false; sirenPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < vampirePuppies.length; i++) { vampirePuppies[i].isSelected = false; vampirePuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < legendaryPuppies.length; i++) { legendaryPuppies[i].isSelected = false; legendaryPuppies[i].tint = 0xFFFFFF; } self.isSelected = true; self.tint = 0xFFFF00; }; self.moveTowards = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.moveSpeed) { self.x += dx / distance * self.moveSpeed; self.y += dy / distance * self.moveSpeed; } else { self.x = targetX; self.y = targetY; } }; return self; }); var Lucie = Container.expand(function () { var self = Container.call(this); var lucieGraphics = self.attachAsset('lucie', { anchorX: 0.5, anchorY: 0.5 }); var nameText = new Text2('Lucie', { size: 40, fill: 0x00CED1 }); nameText.anchor.set(0.5, 0.5); nameText.y = -100; self.addChild(nameText); return self; }); var MrPervers = Container.expand(function () { var self = Container.call(this); var chefGraphics = self.attachAsset('mrpervers', { anchorX: 0.5, anchorY: 0.5 }); var nameText = new Text2('Mr. Pervers', { size: 50, fill: 0xFF0000 }); nameText.anchor.set(0.5, 0.5); nameText.y = -100; self.addChild(nameText); self.moveSpeed = 3; self.targetPuppy = null; self.lastTargetX = 0; self.lastTargetY = 0; self.update = function () { // Don't move if Samantha made Mr. Pervers sleep if (samanthaActive) { return; } if (selectedPuppy && selectedPuppy.isSelected) { self.targetPuppy = selectedPuppy; } if (self.targetPuppy) { var dx = self.targetPuppy.x - self.x; var dy = self.targetPuppy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.moveSpeed) { self.x += dx / distance * self.moveSpeed; self.y += dy / distance * self.moveSpeed; } } }; return self; }); var Puppy = Container.expand(function () { var self = Container.call(this); var puppyGraphics = self.attachAsset('puppy', { anchorX: 0.5, anchorY: 0.5 }); var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley']; self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)]; self.age = Math.floor(Math.random() * 20) + 1; // Random age between 1-20 months self.isSelected = false; self.moveSpeed = 8; self.lastX = 0; self.lastY = 0; var nameText = new Text2(self.name + ' (' + self.age + ' mois)', { size: 40, fill: 0x000000 }); nameText.anchor.set(0.5, 0.5); nameText.y = -80; self.addChild(nameText); self.down = function (x, y, obj) { selectedPuppy = self; // Clear all selections for (var i = 0; i < puppies.length; i++) { puppies[i].isSelected = false; puppies[i].tint = 0xFFFFFF; } for (var i = 0; i < ghostPuppies.length; i++) { ghostPuppies[i].isSelected = false; ghostPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < dragonPuppies.length; i++) { dragonPuppies[i].isSelected = false; dragonPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < sirenPuppies.length; i++) { sirenPuppies[i].isSelected = false; sirenPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < vampirePuppies.length; i++) { vampirePuppies[i].isSelected = false; vampirePuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < legendaryPuppies.length; i++) { legendaryPuppies[i].isSelected = false; legendaryPuppies[i].tint = 0xFFFFFF; } self.isSelected = true; self.tint = 0xFFFF00; }; self.moveTowards = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.moveSpeed) { self.x += dx / distance * self.moveSpeed; self.y += dy / distance * self.moveSpeed; } else { self.x = targetX; self.y = targetY; } }; return self; }); var Samantha = Container.expand(function () { var self = Container.call(this); // Use dedicated Samantha asset var samanthaGraphics = self.attachAsset('samantha', { anchorX: 0.5, anchorY: 0.5 }); var nameText = new Text2('Samantha', { size: 40, fill: 0xFF1493 }); nameText.anchor.set(0.5, 0.5); nameText.y = -100; self.addChild(nameText); self.moveSpeed = 5; self.moveTowards = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.moveSpeed) { self.x += dx / distance * self.moveSpeed; self.y += dy / distance * self.moveSpeed; } else { self.x = targetX; self.y = targetY; } }; return self; }); var SirenPuppy = Container.expand(function () { var self = Container.call(this); var puppyGraphics = self.attachAsset('sirenpuppy', { anchorX: 0.5, anchorY: 0.5 }); puppyGraphics.tint = 0x44ffff; // Cyan tint for siren var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley']; self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)]; self.isSelected = false; self.moveSpeed = 8; self.lastX = 0; self.lastY = 0; self.type = 'siren'; var nameText = new Text2(self.name + ' [Sirène]', { size: 35, fill: 0x44ffff }); nameText.anchor.set(0.5, 0.5); nameText.y = -80; self.addChild(nameText); self.down = function (x, y, obj) { selectedPuppy = self; // Clear all selections for (var i = 0; i < puppies.length; i++) { puppies[i].isSelected = false; puppies[i].tint = 0xFFFFFF; } for (var i = 0; i < ghostPuppies.length; i++) { ghostPuppies[i].isSelected = false; ghostPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < dragonPuppies.length; i++) { dragonPuppies[i].isSelected = false; dragonPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < sirenPuppies.length; i++) { sirenPuppies[i].isSelected = false; sirenPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < vampirePuppies.length; i++) { vampirePuppies[i].isSelected = false; vampirePuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < legendaryPuppies.length; i++) { legendaryPuppies[i].isSelected = false; legendaryPuppies[i].tint = 0xFFFFFF; } self.isSelected = true; self.tint = 0xFFFF00; }; self.moveTowards = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.moveSpeed) { self.x += dx / distance * self.moveSpeed; self.y += dy / distance * self.moveSpeed; } else { self.x = targetX; self.y = targetY; } }; return self; }); var VampirePuppy = Container.expand(function () { var self = Container.call(this); var puppyGraphics = self.attachAsset('vampirepuppy', { anchorX: 0.5, anchorY: 0.5 }); puppyGraphics.tint = 0x800080; // Purple tint for vampire var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley']; self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)]; self.isSelected = false; self.moveSpeed = 8; self.lastX = 0; self.lastY = 0; self.type = 'vampire'; var nameText = new Text2(self.name + ' [Vampire]', { size: 35, fill: 0x800080 }); nameText.anchor.set(0.5, 0.5); nameText.y = -80; self.addChild(nameText); self.down = function (x, y, obj) { selectedPuppy = self; // Clear all selections for (var i = 0; i < puppies.length; i++) { puppies[i].isSelected = false; puppies[i].tint = 0xFFFFFF; } for (var i = 0; i < ghostPuppies.length; i++) { ghostPuppies[i].isSelected = false; ghostPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < dragonPuppies.length; i++) { dragonPuppies[i].isSelected = false; dragonPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < sirenPuppies.length; i++) { sirenPuppies[i].isSelected = false; sirenPuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < vampirePuppies.length; i++) { vampirePuppies[i].isSelected = false; vampirePuppies[i].tint = 0xFFFFFF; } for (var i = 0; i < legendaryPuppies.length; i++) { legendaryPuppies[i].isSelected = false; legendaryPuppies[i].tint = 0xFFFFFF; } self.isSelected = true; self.tint = 0xFFFF00; }; self.moveTowards = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.moveSpeed) { self.x += dx / distance * self.moveSpeed; self.y += dy / distance * self.moveSpeed; } else { self.x = targetX; self.y = targetY; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xF5DEB3 }); /**** * Game Code ****/ // Game variables var currentLevel = storage.currentLevel || 1; var puppiesSaved = 0; var puppiesRequired = currentLevel === 1 ? 3 : Math.pow(2, currentLevel - 1) * 3; var puppies = []; var selectedPuppy = null; var mrPervers = null; var exitDoor = null; var pot = null; var upButton = null; var downButton = null; var leftButton = null; var rightButton = null; // SM currency system var playerSM = storage.playerSM || 0; var samanthaCost = storage.samanthaCost || 5; var originalSamanthaCost = samanthaCost; var samanthaActive = false; var samanthaEndTime = 0; var samanthaCharacter = null; // Eva tracking var puppiesSavedForEva = 0; var evaCharacter = null; var evaEndTime = 0; // Gabriel tracking var puppiesSavedForGabriel = 0; var gabrielCharacter = null; // Lucie tracking var samanthaInvocations = 0; var lucieCharacter = null; var lucieActive = false; var lucieEndTime = 0; var lucieDiscountActive = false; var lucieDiscountEndTime = 0; // Special puppy shop system var specialPuppyShop = { isOpen: false, selectedType: null }; // Special puppy types and costs var PUPPY_TYPES = { GHOST: { name: 'Fantômes', cost: 6, multiplier: 1, hasAge: true }, DRAGON: { name: 'Dragons', cost: 15, multiplier: 3, hasAge: false }, SIREN: { name: 'Sirènes', cost: 25, multiplier: 4, hasAge: false }, VAMPIRE: { name: 'Vampires', cost: 50, multiplier: 5, hasAge: false }, LEGENDARY: { name: 'Légendaires', cost: 1000, multiplier: 20, hasAge: false } }; // Special puppies arrays var ghostPuppies = []; var dragonPuppies = []; var sirenPuppies = []; var vampirePuppies = []; var legendaryPuppies = []; // Mr. Pervers mean messages var perversMessages = ["NON! Mes hot dogs de chiot!", "Ce chiot était parfait pour ma saucisse!", "Tu ruines mon menu hot dog!", "J'avais prévu de le servir grillé!", "Mes clients voulaient ce hot dog!", "Cette viande de chiot était premium!", "Tu gâches ma spécialité hot dog!", "Ce chiot aurait fait un délicieux hot dog!", "Mes hot dogs de chiot sont célèbres!", "Tu m'empêches de cuisiner mes hot dogs!", "Ce chiot était destiné à ma marmite!", "Mes hot dogs seront moins savoureux!", "Tu voles mes ingrédients à hot dog!", "Ce chiot était ma recette secrète!", "Mes clients adorent mes hot dogs de chiot!", "Tu sabotes ma production de hot dogs!", "Cette viande était parfaite pour griller!", "Mes hot dogs de chiot sont uniques!", "Tu détruis mon business de hot dogs!", "Ce chiot aurait nourri mes clients!", "Ma spécialité hot dog est ruinée!", "Tu m'empêches de servir mes hot dogs!", "Cette viande de chiot était fraîche!", "Mes hot dogs perdent leur goût!", "Tu voles ma matière première!", "Ce chiot était mon meilleur ingrédient!", "Mes hot dogs de chiot sont ma fierté!", "Tu ruines ma réputation de hot dogs!", "Cette viande était prête à cuire!", "Mes clients vont être déçus!", "Tu gâches ma recette de hot dog!", "Ce chiot était parfait pour les saucisses!", "Mes hot dogs de chiot sont artistiques!", "Tu m'empêches de nourrir mes clients!", "Cette viande aurait été délicieuse!", "Mes hot dogs perdent leur originalité!", "Tu sabotes ma cuisine de hot dogs!", "Ce chiot était ma fortune culinaire!", "Mes hot dogs de chiot sont légendaires!", "Tu détruis mon art du hot dog!", "Cette viande était mon inspiration!", "Mes hot dogs ne seront plus pareils!", "Tu voles mes profits de hot dogs!", "Ce chiot était destiné au grill!", "Mes hot dogs de chiot sont ma passion!", "Tu ruines mes ventes de hot dogs!", "Cette viande était exceptionnelle!", "Mes hot dogs perdent leur magie!", "Tu gâches ma tradition culinaire!", "Ce chiot était mon chef-d'œuvre!", "Mes hot dogs de chiot sont irremplaçables!", "Tu m'empêches de régaler mes clients!", "Cette viande était ma signature!", "Mes hot dogs perdent leur authenticité!", "Tu sabotes mon empire hot dog!", "Ce chiot était mon trésor culinaire!", "Mes hot dogs de chiot sont mon héritage!", "Tu détruis ma chaîne de restaurants!", "Cette viande était ma spécialité!", "Mes hot dogs ne seront plus uniques!", "Tu voles mon succès culinaire!", "Ce chiot était parfait pour mes saucisses!", "Mes hot dogs de chiot sont ma vie!", "Tu ruines mes rêves de restaurateur!", "Cette viande était mon avenir!", "Mes hot dogs perdent leur saveur!", "Tu gâches ma réputation mondiale!", "Ce chiot était destiné à mes clients!", "Mes hot dogs de chiot sont mon génie!", "Tu m'empêches de devenir riche!", "Cette viande était ma révolution!", "Mes hot dogs ne seront plus parfaits!", "Tu sabotes mon innovation culinaire!", "Ce chiot était mon diamant brut!", "Mes hot dogs de chiot sont mon destin!", "Tu détruis mon rêve américain!"]; var messageText = null; // UI elements var levelText = new Text2('Level: ' + currentLevel, { size: 60, fill: 0x000000 }); levelText.anchor.set(0, 0); levelText.x = 120; levelText.y = 50; LK.gui.topLeft.addChild(levelText); var savedText = new Text2('Saved: 0/' + puppiesRequired, { size: 60, fill: 0x000000 }); savedText.anchor.set(0.5, 0); savedText.x = 0; savedText.y = 50; LK.gui.top.addChild(savedText); var scoreText = new Text2('Score: ' + LK.getScore(), { size: 60, fill: 0x000000 }); scoreText.anchor.set(1, 0); scoreText.x = 0; scoreText.y = 50; LK.gui.topRight.addChild(scoreText); var smText = new Text2('SM: ' + playerSM, { size: 50, fill: 0x000000 }); smText.anchor.set(1, 0); smText.x = 0; smText.y = 120; LK.gui.topRight.addChild(smText); // Background var background = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); // Exit door exitDoor = game.addChild(LK.getAsset('exitdoor', { anchorX: 0.5, anchorY: 1, x: 1024, y: 2700 })); var exitText = new Text2('EXIT', { size: 40, fill: 0xFFFFFF }); exitText.anchor.set(0.5, 0.5); exitText.y = -150; exitDoor.addChild(exitText); // Cooking pot pot = game.addChild(LK.getAsset('pot', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 400 })); // Mr. Pervers mrPervers = game.addChild(new MrPervers()); mrPervers.x = 1024; mrPervers.y = 500; // Directional buttons upButton = game.addChild(new DirectionalButton('up')); upButton.x = 1700; upButton.y = 2200; downButton = game.addChild(new DirectionalButton('down')); downButton.x = 1700; downButton.y = 2400; leftButton = game.addChild(new DirectionalButton('left')); leftButton.x = 1600; leftButton.y = 2300; rightButton = game.addChild(new DirectionalButton('right')); rightButton.x = 1800; rightButton.y = 2300; // Invoke Samantha button var invokeSamButton = new Container(); var invokeSamGraphics = invokeSamButton.attachAsset('downbutton', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 1.5 }); invokeSamGraphics.tint = 0xFF69B4; // Pink color var invokeSamText = new Text2('Invoque Sam\n(' + samanthaCost + ' SM)', { size: 30, fill: 0xFFFFFF }); invokeSamText.anchor.set(0.5, 0.5); invokeSamButton.addChild(invokeSamText); invokeSamButton.x = 300; invokeSamButton.y = 2300; invokeSamButton.down = function (x, y, obj) { var currentCost = lucieDiscountActive ? Math.ceil(samanthaCost * 0.4) : samanthaCost; if (playerSM >= currentCost && !samanthaActive) { invokeSamantha(); } }; game.addChild(invokeSamButton); // Shop button var shopButton = new Container(); var shopGraphics = shopButton.attachAsset('shopButton', { anchorX: 0.5, anchorY: 0.5 }); var shopText = new Text2('Boutique', { size: 30, fill: 0x000000 }); shopText.anchor.set(0.5, 0.5); shopButton.addChild(shopText); shopButton.x = 500; shopButton.y = 2300; shopButton.down = function (x, y, obj) { if (!specialPuppyShop.isOpen) { openShop(); } }; game.addChild(shopButton); // Functions function spawnPuppies() { var numPuppies = 1; if (currentLevel >= 11) { numPuppies = Math.floor(Math.random() * 6) + 5; // 5-10 puppies } else if (currentLevel >= 5) { numPuppies = Math.floor(Math.random() * 4) + 2; // 2-5 puppies } for (var i = 0; i < numPuppies; i++) { var puppy = new Puppy(); puppy.x = Math.random() * 1500 + 300; puppy.y = Math.random() * 1000 + 800; puppy.lastX = puppy.x; puppy.lastY = puppy.y; puppies.push(puppy); game.addChild(puppy); } } function checkCollisions() { // Check normal puppies for (var i = puppies.length - 1; i >= 0; i--) { var puppy = puppies[i]; // Check if puppy reached exit if (puppy.intersects(exitDoor)) { // Puppies over 10 months count as 2 saved puppies var puppyValue = puppy.age > 10 ? 2 : 1; puppiesSaved += puppyValue; puppiesSavedForEva += puppyValue; puppiesSavedForGabriel += puppyValue; LK.setScore(LK.getScore() + puppyValue); // Give SM reward playerSM += 3; storage.playerSM = playerSM; LK.getSound('puppysaved').play(); // Show Mr. Pervers angry message (only if Mr. Pervers is awake) if (!samanthaActive) { showPerversMessage(); } // Check Eva appearance (level 5+, every 6 puppies saved, 50% chance) if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) { puppiesSavedForEva = 0; if (Math.random() < 0.5) { spawnEva(); } } // Check Gabriel appearance (every 3 puppies saved, random chance) if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) { puppiesSavedForGabriel = 0; if (Math.random() < 0.5) { spawnGabriel(); } } puppy.destroy(); puppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } updateUI(); if (puppiesSaved >= puppiesRequired) { nextLevel(); } continue; } // Check if puppy caught by Mr. Pervers (only if Mr. Pervers is not sleeping) if (puppy.intersects(mrPervers) && !samanthaActive && LK.ticks >= vampireSleepEndTime) { LK.setScore(LK.getScore() - 1); LK.getSound('puppycaught').play(); puppy.destroy(); puppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } updateUI(); if (puppies.length === 0 && puppiesSaved < puppiesRequired) { LK.showGameOver(); } } // Check if puppy caught by Gabriel (no game over, just remove puppy) if (gabrielCharacter && puppy.intersects(gabrielCharacter)) { puppy.destroy(); puppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } continue; } } // Check ghost puppies (ignored by Mr. Pervers and Gabriel) for (var i = ghostPuppies.length - 1; i >= 0; i--) { var puppy = ghostPuppies[i]; if (puppy.intersects(exitDoor)) { var puppyValue = puppy.age > 10 ? 2 : 1; puppiesSaved += puppyValue; puppiesSavedForEva += puppyValue; puppiesSavedForGabriel += puppyValue; LK.setScore(LK.getScore() + puppyValue); playerSM += 3; storage.playerSM = playerSM; LK.getSound('puppysaved').play(); if (!samanthaActive) { showPerversMessage(); } // Check Eva and Gabriel appearances if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) { puppiesSavedForEva = 0; if (Math.random() < 0.5) { spawnEva(); } } if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) { puppiesSavedForGabriel = 0; if (Math.random() < 0.5) { spawnGabriel(); } } puppy.destroy(); ghostPuppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } updateUI(); if (puppiesSaved >= puppiesRequired) { nextLevel(); } } } // Check dragon puppies (only catchable by Mr. Pervers, ignored by Gabriel) for (var i = dragonPuppies.length - 1; i >= 0; i--) { var puppy = dragonPuppies[i]; if (puppy.intersects(exitDoor)) { var puppyValue = 3; // Dragons count triple puppiesSaved += puppyValue; puppiesSavedForEva += puppyValue; puppiesSavedForGabriel += puppyValue; LK.setScore(LK.getScore() + puppyValue); playerSM += 9; // 3x reward storage.playerSM = playerSM; LK.getSound('puppysaved').play(); if (!samanthaActive) { showPerversMessage(); } // Check Eva and Gabriel appearances if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) { puppiesSavedForEva = 0; if (Math.random() < 0.5) { spawnEva(); } } if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) { puppiesSavedForGabriel = 0; if (Math.random() < 0.5) { spawnGabriel(); } } puppy.destroy(); dragonPuppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } updateUI(); if (puppiesSaved >= puppiesRequired) { nextLevel(); } continue; } // Dragons can be caught by Mr. Pervers if (puppy.intersects(mrPervers) && !samanthaActive && LK.ticks >= vampireSleepEndTime) { LK.setScore(LK.getScore() - 3); LK.getSound('puppycaught').play(); puppy.destroy(); dragonPuppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } updateUI(); } } // Check siren puppies (only catchable by Gabriel, ignored by Mr. Pervers) for (var i = sirenPuppies.length - 1; i >= 0; i--) { var puppy = sirenPuppies[i]; if (puppy.intersects(exitDoor)) { var puppyValue = 4; // Sirens count quadruple puppiesSaved += puppyValue; puppiesSavedForEva += puppyValue; puppiesSavedForGabriel += puppyValue; LK.setScore(LK.getScore() + puppyValue); playerSM += 12; // 4x reward storage.playerSM = playerSM; LK.getSound('puppysaved').play(); if (!samanthaActive) { showPerversMessage(); } // Check Eva and Gabriel appearances if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) { puppiesSavedForEva = 0; if (Math.random() < 0.5) { spawnEva(); } } if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) { puppiesSavedForGabriel = 0; if (Math.random() < 0.5) { spawnGabriel(); } } puppy.destroy(); sirenPuppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } updateUI(); if (puppiesSaved >= puppiesRequired) { nextLevel(); } continue; } // Sirens can be caught by Gabriel if (gabrielCharacter && puppy.intersects(gabrielCharacter)) { puppy.destroy(); sirenPuppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } continue; } } // Check vampire puppies (catchable by both, but put Mr. Pervers to sleep) for (var i = vampirePuppies.length - 1; i >= 0; i--) { var puppy = vampirePuppies[i]; if (puppy.intersects(exitDoor)) { var puppyValue = 5; // Vampires count quintuple puppiesSaved += puppyValue; puppiesSavedForEva += puppyValue; puppiesSavedForGabriel += puppyValue; LK.setScore(LK.getScore() + puppyValue); playerSM += 15; // 5x reward storage.playerSM = playerSM; LK.getSound('puppysaved').play(); if (!samanthaActive) { showPerversMessage(); } // Check Eva and Gabriel appearances if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) { puppiesSavedForEva = 0; if (Math.random() < 0.5) { spawnEva(); } } if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) { puppiesSavedForGabriel = 0; if (Math.random() < 0.5) { spawnGabriel(); } } puppy.destroy(); vampirePuppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } updateUI(); if (puppiesSaved >= puppiesRequired) { nextLevel(); } continue; } // Vampires can be caught by Mr. Pervers but put him to sleep if (puppy.intersects(mrPervers) && !samanthaActive && LK.ticks >= vampireSleepEndTime) { LK.setScore(LK.getScore() - 5); LK.getSound('puppycaught').play(); // Put Mr. Pervers to sleep for 2 minutes vampireSleepEndTime = LK.ticks + 2 * 60 * 60; // 2 minutes at 60 FPS mrPervers.tint = 0x808080; // Gray tint to show sleeping puppy.destroy(); vampirePuppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } updateUI(); continue; } // Vampires can be caught by Gabriel if (gabrielCharacter && puppy.intersects(gabrielCharacter)) { puppy.destroy(); vampirePuppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } continue; } } // Check legendary puppies (ignored by both, put them to sleep on collision) for (var i = legendaryPuppies.length - 1; i >= 0; i--) { var puppy = legendaryPuppies[i]; if (puppy.intersects(exitDoor)) { var puppyValue = 20; // Legendaries count as 20 puppiesSaved += puppyValue; puppiesSavedForEva += puppyValue; puppiesSavedForGabriel += puppyValue; LK.setScore(LK.getScore() + puppyValue); playerSM += 60; // 20x reward storage.playerSM = playerSM; LK.getSound('puppysaved').play(); if (!samanthaActive) { showPerversMessage(); } // Check Eva and Gabriel appearances if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) { puppiesSavedForEva = 0; if (Math.random() < 0.5) { spawnEva(); } } if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) { puppiesSavedForGabriel = 0; if (Math.random() < 0.5) { spawnGabriel(); } } puppy.destroy(); legendaryPuppies.splice(i, 1); if (selectedPuppy === puppy) { selectedPuppy = null; } updateUI(); if (puppiesSaved >= puppiesRequired) { nextLevel(); } continue; } // Legendary puppies put Mr. Pervers to sleep on collision if (puppy.intersects(mrPervers)) { vampireSleepEndTime = LK.ticks + 10 * 60 * 60; // 10 minutes at 60 FPS mrPervers.tint = 0x808080; // Gray tint to show sleeping } // Legendary puppies put Gabriel to sleep on collision if (gabrielCharacter && puppy.intersects(gabrielCharacter)) { gabrielCharacter.destroy(); gabrielCharacter = null; } } } function updateUI() { savedText.setText('Saved: ' + puppiesSaved + '/' + puppiesRequired); scoreText.setText('Score: ' + LK.getScore()); smText.setText('SM: ' + playerSM); var displayCost = lucieDiscountActive ? Math.ceil(samanthaCost * 0.4) : samanthaCost; var costText = lucieDiscountActive ? displayCost + ' SM (60% OFF!)' : displayCost + ' SM'; invokeSamText.setText('Invoque Sam\n(' + costText + ')'); } function showPerversMessage() { // Remove existing message if any if (messageText) { messageText.destroy(); messageText = null; } // Get random message var randomMessage = perversMessages[Math.floor(Math.random() * perversMessages.length)]; // Create message text messageText = new Text2(randomMessage, { size: 80, fill: 0xFF0000 }); messageText.anchor.set(0.5, 0.5); messageText.x = 1024; messageText.y = 1200; messageText.alpha = 1; // Add to game game.addChild(messageText); // Animate message appearing with scale and fade tween(messageText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.bounceOut }); // Fade out and remove after 15 seconds LK.setTimeout(function () { if (messageText) { tween(messageText, { alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { if (messageText) { messageText.destroy(); messageText = null; } } }); } }, 15000); } function invokeSamantha() { // Apply Lucie discount if active var currentCost = lucieDiscountActive ? Math.ceil(samanthaCost * 0.4) : samanthaCost; // Deduct SM cost playerSM -= currentCost; storage.playerSM = playerSM; // Increase cost for next invocation (30% increase) samanthaCost = Math.ceil(samanthaCost * 1.3); storage.samanthaCost = samanthaCost; // Track invocations for Lucie samanthaInvocations++; // Create Samantha samanthaCharacter = game.addChild(new Samantha()); samanthaCharacter.x = 100; samanthaCharacter.y = 1000; // Set Mr. Pervers to sleep and Samantha active samanthaActive = true; samanthaEndTime = LK.ticks + 6 * 60 * 60; // 6 minutes at 60 FPS // Make Mr. Pervers sleep (stop moving and change tint) mrPervers.tint = 0x808080; // Gray tint to show sleeping // Check Lucie appearance (every 2 invocations) if (samanthaInvocations >= 2 && !lucieCharacter) { samanthaInvocations = 0; spawnLucie(); } updateUI(); } function wakeMrPervers() { samanthaActive = false; mrPervers.tint = 0xFFFFFF; // Reset tint // Remove Samantha if (samanthaCharacter) { samanthaCharacter.destroy(); samanthaCharacter = null; } } function spawnEva() { evaCharacter = game.addChild(new Eva()); evaCharacter.x = 200; evaCharacter.y = 1500; evaEndTime = LK.ticks + 15 * 60; // 15 seconds at 60 FPS // 50% chance Eva will invoke Samantha if (Math.random() < 0.5) { // Eva invokes Samantha after 2 seconds LK.setTimeout(function () { if (evaCharacter && !samanthaActive) { // Create Samantha for free samanthaCharacter = game.addChild(new Samantha()); samanthaCharacter.x = 100; samanthaCharacter.y = 1000; samanthaActive = true; samanthaEndTime = LK.ticks + 6 * 60 * 60; // 6 minutes at 60 FPS mrPervers.tint = 0x808080; // Gray tint to show sleeping // Remove Eva immediately when Samantha arrives if (evaCharacter) { evaCharacter.destroy(); evaCharacter = null; } } }, 2000); } } function spawnGabriel() { gabrielCharacter = game.addChild(new Gabriel()); gabrielCharacter.x = 1800; gabrielCharacter.y = 1000; } function spawnLucie() { lucieCharacter = game.addChild(new Lucie()); lucieCharacter.x = 1024; lucieCharacter.y = 1500; lucieActive = true; lucieEndTime = LK.ticks + 20 * 60; // 20 seconds at 60 FPS // After Lucie appears, activate 60% discount for 2 minutes LK.setTimeout(function () { if (lucieCharacter) { lucieCharacter.destroy(); lucieCharacter = null; lucieActive = false; // Activate discount lucieDiscountActive = true; lucieDiscountEndTime = LK.ticks + 2 * 60 * 60; // 2 minutes at 60 FPS updateUI(); } }, 20000); } // Vampire sleep tracking var vampireSleepEndTime = 0; function getMaxPuppiesForType(type) { switch (type) { case 'GHOST': if (currentLevel < 10) return currentLevel < 10 ? 5 : 0; return currentLevel > 10 ? 13 : 5; case 'DRAGON': if (currentLevel < 7) return 0; return currentLevel < 20 ? 6 : 15; case 'SIREN': if (currentLevel < 10) return 0; return currentLevel < 30 ? 7 : 20; case 'VAMPIRE': if (currentLevel < 15) return 0; return currentLevel < 40 ? 9 : 25; case 'LEGENDARY': if (currentLevel < 90) return 0; if (currentLevel <= 150) return 3; return 7; default: return 0; } } function isTypeAvailable(type) { switch (type) { case 'GHOST': return true; case 'DRAGON': return currentLevel >= 7; case 'SIREN': return currentLevel >= 10; case 'VAMPIRE': return currentLevel >= 15; case 'LEGENDARY': return currentLevel >= 90; default: return false; } } function openShop() { specialPuppyShop.isOpen = true; // Create shop background var shopBg = game.addChild(LK.getAsset('shopBackground', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, alpha: 0.9 })); shopBg.shopElement = true; // Shop title var shopTitle = new Text2('Boutique de Chiots Spéciaux', { size: 60, fill: 0xFFFFFF }); shopTitle.anchor.set(0.5, 0.5); shopTitle.x = 1024; shopTitle.y = 800; shopTitle.shopElement = true; game.addChild(shopTitle); // Create type buttons var yPos = 1000; var buttonIndex = 0; for (var typeKey in PUPPY_TYPES) { var type = PUPPY_TYPES[typeKey]; var available = isTypeAvailable(typeKey); var maxPuppies = getMaxPuppiesForType(typeKey); var typeButton = new Container(); var buttonGraphics = typeButton.attachAsset('typeButton', { anchorX: 0.5, anchorY: 0.5 }); if (!available) { buttonGraphics.tint = 0x666666; // Gray out unavailable types } var buttonText = new Text2(type.name + '\n' + type.cost + ' SM\nMax: ' + maxPuppies, { size: 25, fill: available ? 0xFFFFFF : 0x999999 }); buttonText.anchor.set(0.5, 0.5); typeButton.addChild(buttonText); typeButton.x = 1024; typeButton.y = yPos; typeButton.shopElement = true; typeButton.typeKey = typeKey; if (available && maxPuppies > 0) { typeButton.down = function (x, y, obj) { selectPuppyType(this.typeKey); }; } game.addChild(typeButton); yPos += 120; buttonIndex++; } // Close button var closeButton = new Container(); var closeGraphics = closeButton.attachAsset('typeButton', { anchorX: 0.5, anchorY: 0.5 }); closeGraphics.tint = 0xff0000; var closeText = new Text2('Fermer', { size: 30, fill: 0xFFFFFF }); closeText.anchor.set(0.5, 0.5); closeButton.addChild(closeText); closeButton.x = 1024; closeButton.y = 1800; closeButton.shopElement = true; closeButton.down = function (x, y, obj) { closeShop(); }; game.addChild(closeButton); } function selectPuppyType(typeKey) { specialPuppyShop.selectedType = typeKey; closeShop(); openNumberSelector(typeKey); } function openNumberSelector(typeKey) { var type = PUPPY_TYPES[typeKey]; if (!type) { console.log('Invalid puppy type:', typeKey); return; } var maxPuppies = getMaxPuppiesForType(typeKey); if (!isTypeAvailable(typeKey) || maxPuppies === 0) { console.log('Type not available or max reached:', typeKey); return; } // Define colors and special text for each type var typeColors = { GHOST: 0x9999ff, DRAGON: 0xff4444, SIREN: 0x44ffff, VAMPIRE: 0x800080, LEGENDARY: 0xFFD700 }; var typeDescriptions = { GHOST: 'Ignorés par Mr. Pervers et Gabriel\nSystème d\'âge appliqué', DRAGON: 'Visibles par Mr. Pervers seulement\nComptent triple au sauvetage', SIREN: 'Attrapables par Gabriel seulement\nComptent quadruple au sauvetage', VAMPIRE: 'Endorment Mr. Pervers 2 minutes\nComptent quintuple au sauvetage', LEGENDARY: 'Ignorent tout, endorment 10 min\nComptent comme 20 chiots!' }; var bgColor = typeColors[typeKey] || 0x4444ff; // Create number selector background with type-specific color var selectorBg = game.addChild(LK.getAsset('shopBackground', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, alpha: 0.9 })); selectorBg.tint = bgColor; selectorBg.selectorElement = true; // Title with type-specific styling var selectorTitle = new Text2('Achat de Chiots ' + type.name, { size: 50, fill: 0xFFFFFF }); selectorTitle.anchor.set(0.5, 0.5); selectorTitle.x = 1024; selectorTitle.y = 800; selectorTitle.selectorElement = true; game.addChild(selectorTitle); // Type description var descriptionText = new Text2(typeDescriptions[typeKey], { size: 30, fill: 0xFFFFFF }); descriptionText.anchor.set(0.5, 0.5); descriptionText.x = 1024; descriptionText.y = 900; descriptionText.selectorElement = true; game.addChild(descriptionText); // Level requirement and max display var requirementText = ''; switch (typeKey) { case 'GHOST': requirementText = 'Disponible dès le niveau 1'; break; case 'DRAGON': requirementText = 'Requis niveau 7+'; break; case 'SIREN': requirementText = 'Requis niveau 10+'; break; case 'VAMPIRE': requirementText = 'Requis niveau 15+'; break; case 'LEGENDARY': requirementText = 'Requis niveau 90+'; break; } var reqText = new Text2(requirementText + ' | Maximum: ' + maxPuppies, { size: 25, fill: 0xFFFFFF }); reqText.anchor.set(0.5, 0.5); reqText.x = 1024; reqText.y = 980; reqText.selectorElement = true; game.addChild(reqText); // Current number display var currentNumber = 1; var numberDisplay = new Text2(currentNumber.toString(), { size: 80, fill: 0xFFFFFF }); numberDisplay.anchor.set(0.5, 0.5); numberDisplay.x = 1024; numberDisplay.y = 1100; numberDisplay.selectorElement = true; game.addChild(numberDisplay); // Cost display with type-specific styling var costDisplay = new Text2('Coût: ' + currentNumber * type.cost + ' SM', { size: 40, fill: 0xFFFFFF }); costDisplay.anchor.set(0.5, 0.5); costDisplay.x = 1024; costDisplay.y = 1200; costDisplay.selectorElement = true; game.addChild(costDisplay); // Number buttons with type-specific color var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; var startX = 1024 - 200; var startY = 1300; for (var i = 0; i < numbers.length; i++) { var num = numbers[i]; var numberButton = new Container(); var numberGraphics = numberButton.attachAsset('numberButton', { anchorX: 0.5, anchorY: 0.5 }); numberGraphics.tint = bgColor; var numText = new Text2(num.toString(), { size: 30, fill: 0xFFFFFF }); numText.anchor.set(0.5, 0.5); numberButton.addChild(numText); numberButton.x = startX + i % 5 * 100; numberButton.y = startY + Math.floor(i / 5) * 100; numberButton.selectorElement = true; numberButton.number = num; numberButton.down = function (x, y, obj) { var digit = obj.parent.number; if (currentNumber === 0 || currentNumber.toString().length >= 2) { currentNumber = digit; } else { currentNumber = currentNumber * 10 + digit; } if (currentNumber > maxPuppies) { currentNumber = maxPuppies; } numberDisplay.setText(currentNumber.toString()); costDisplay.setText('Coût: ' + currentNumber * type.cost + ' SM'); }; game.addChild(numberButton); } // Validate button with type-specific color var validateButton = new Container(); var validateGraphics = validateButton.attachAsset('typeButton', { anchorX: 0.5, anchorY: 0.5 }); validateGraphics.tint = 0x00ff00; var validateText = new Text2('Acheter ' + type.name, { size: 25, fill: 0xFFFFFF }); validateText.anchor.set(0.5, 0.5); validateButton.addChild(validateText); validateButton.x = 924; validateButton.y = 1600; validateButton.selectorElement = true; validateButton.down = function (x, y, obj) { var totalCost = currentNumber * type.cost; if (playerSM >= totalCost && currentNumber > 0) { purchasePuppies(typeKey, currentNumber, totalCost); } closeNumberSelector(); }; game.addChild(validateButton); // Cancel button var cancelButton = new Container(); var cancelGraphics = cancelButton.attachAsset('typeButton', { anchorX: 0.5, anchorY: 0.5 }); cancelGraphics.tint = 0xff0000; var cancelText = new Text2('Annuler', { size: 30, fill: 0xFFFFFF }); cancelText.anchor.set(0.5, 0.5); cancelButton.addChild(cancelText); cancelButton.x = 1124; cancelButton.y = 1600; cancelButton.selectorElement = true; cancelButton.down = function (x, y, obj) { closeNumberSelector(); }; game.addChild(cancelButton); } function closeShop() { specialPuppyShop.isOpen = false; // Remove all shop elements for (var i = game.children.length - 1; i >= 0; i--) { var child = game.children[i]; if (child.shopElement) { child.destroy(); } } } function closeNumberSelector() { // Remove all selector elements for (var i = game.children.length - 1; i >= 0; i--) { var child = game.children[i]; if (child.selectorElement) { child.destroy(); } } } function purchasePuppies(typeKey, count, totalCost) { playerSM -= totalCost; storage.playerSM = playerSM; for (var i = 0; i < count; i++) { var puppy; switch (typeKey) { case 'GHOST': puppy = new GhostPuppy(); ghostPuppies.push(puppy); break; case 'DRAGON': puppy = new DragonPuppy(); dragonPuppies.push(puppy); break; case 'SIREN': puppy = new SirenPuppy(); sirenPuppies.push(puppy); break; case 'VAMPIRE': puppy = new VampirePuppy(); vampirePuppies.push(puppy); break; case 'LEGENDARY': puppy = new LegendaryPuppy(); legendaryPuppies.push(puppy); break; } puppy.x = Math.random() * 1500 + 300; puppy.y = Math.random() * 1000 + 800; puppy.lastX = puppy.x; puppy.lastY = puppy.y; game.addChild(puppy); } updateUI(); } function nextLevel() { currentLevel++; // Reset to level 1 if we've completed level 200 if (currentLevel > 200) { currentLevel = 1; } storage.currentLevel = currentLevel; puppiesSaved = 0; puppiesSavedForEva = 0; puppiesSavedForGabriel = 0; puppiesRequired = currentLevel === 1 ? 3 : Math.pow(2, currentLevel - 1) * 3; // Clear existing puppies for (var i = 0; i < puppies.length; i++) { puppies[i].destroy(); } puppies = []; // Clear special puppies for (var i = 0; i < ghostPuppies.length; i++) { ghostPuppies[i].destroy(); } ghostPuppies = []; for (var i = 0; i < dragonPuppies.length; i++) { dragonPuppies[i].destroy(); } dragonPuppies = []; for (var i = 0; i < sirenPuppies.length; i++) { sirenPuppies[i].destroy(); } sirenPuppies = []; for (var i = 0; i < vampirePuppies.length; i++) { vampirePuppies[i].destroy(); } vampirePuppies = []; for (var i = 0; i < legendaryPuppies.length; i++) { legendaryPuppies[i].destroy(); } legendaryPuppies = []; selectedPuppy = null; // Reset vampire sleep vampireSleepEndTime = 0; // Reset Mr. Pervers tint and position mrPervers.tint = 0xFFFFFF; mrPervers.x = 1024; mrPervers.y = 500; mrPervers.targetPuppy = null; // Clear all active characters if (evaCharacter) { evaCharacter.destroy(); evaCharacter = null; } if (gabrielCharacter) { gabrielCharacter.destroy(); gabrielCharacter = null; } if (lucieCharacter) { lucieCharacter.destroy(); lucieCharacter = null; lucieActive = false; } if (samanthaCharacter && !samanthaActive) { samanthaCharacter.destroy(); samanthaCharacter = null; } // Update UI levelText.setText('Level: ' + currentLevel); updateUI(); // Spawn new puppies spawnPuppies(); } // Initialize first level spawnPuppies(); // Start background music LK.playMusic('bgmusic'); game.update = function () { checkCollisions(); // Handle Samantha timer if (samanthaActive && LK.ticks >= samanthaEndTime) { wakeMrPervers(); } // Move Samantha towards Mr. Pervers if active if (samanthaActive && samanthaCharacter) { samanthaCharacter.moveTowards(mrPervers.x, mrPervers.y); } // Handle Eva timer if (evaCharacter && LK.ticks >= evaEndTime) { evaCharacter.destroy(); evaCharacter = null; } // Handle Lucie discount timer if (lucieDiscountActive && LK.ticks >= lucieDiscountEndTime) { lucieDiscountActive = false; updateUI(); } // Handle vampire sleep timer if (LK.ticks >= vampireSleepEndTime && vampireSleepEndTime > 0) { mrPervers.tint = 0xFFFFFF; // Reset tint when waking up } // Spawn new puppies if screen is empty and we haven't completed the level var totalPuppies = puppies.length + ghostPuppies.length + dragonPuppies.length + sirenPuppies.length + vampirePuppies.length + legendaryPuppies.length; if (totalPuppies === 0 && puppiesSaved < puppiesRequired) { spawnPuppies(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var DirectionalButton = Container.expand(function (direction) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset(direction + 'button', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(direction.toUpperCase(), {
size: 30,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.direction = direction;
self.down = function (x, y, obj) {
if (selectedPuppy && selectedPuppy.isSelected) {
var moveDistance = 60;
switch (self.direction) {
case 'up':
selectedPuppy.y -= moveDistance;
break;
case 'down':
selectedPuppy.y += moveDistance;
break;
case 'left':
selectedPuppy.x -= moveDistance;
break;
case 'right':
selectedPuppy.x += moveDistance;
break;
}
// Keep puppy within bounds
selectedPuppy.x = Math.max(60, Math.min(1988, selectedPuppy.x));
selectedPuppy.y = Math.max(60, Math.min(2400, selectedPuppy.y));
}
};
return self;
});
var DragonPuppy = Container.expand(function () {
var self = Container.call(this);
var puppyGraphics = self.attachAsset('dragonpuppy', {
anchorX: 0.5,
anchorY: 0.5
});
puppyGraphics.tint = 0xff4444; // Red tint for dragon
var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley'];
self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)];
self.isSelected = false;
self.moveSpeed = 8;
self.lastX = 0;
self.lastY = 0;
self.type = 'dragon';
var nameText = new Text2(self.name + ' [Dragon]', {
size: 35,
fill: 0xff4444
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -80;
self.addChild(nameText);
self.down = function (x, y, obj) {
selectedPuppy = self;
// Clear all selections
for (var i = 0; i < puppies.length; i++) {
puppies[i].isSelected = false;
puppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < ghostPuppies.length; i++) {
ghostPuppies[i].isSelected = false;
ghostPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < dragonPuppies.length; i++) {
dragonPuppies[i].isSelected = false;
dragonPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < sirenPuppies.length; i++) {
sirenPuppies[i].isSelected = false;
sirenPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < vampirePuppies.length; i++) {
vampirePuppies[i].isSelected = false;
vampirePuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < legendaryPuppies.length; i++) {
legendaryPuppies[i].isSelected = false;
legendaryPuppies[i].tint = 0xFFFFFF;
}
self.isSelected = true;
self.tint = 0xFFFF00;
};
self.moveTowards = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
} else {
self.x = targetX;
self.y = targetY;
}
};
return self;
});
var Eva = Container.expand(function () {
var self = Container.call(this);
var evaGraphics = self.attachAsset('eva', {
anchorX: 0.5,
anchorY: 0.5
});
var nameText = new Text2('Eva', {
size: 40,
fill: 0x9932CC
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -100;
self.addChild(nameText);
return self;
});
var Gabriel = Container.expand(function () {
var self = Container.call(this);
var gabrielGraphics = self.attachAsset('gabriel', {
anchorX: 0.5,
anchorY: 0.5
});
var nameText = new Text2('Gabriel', {
size: 40,
fill: 0x8B0000
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -100;
self.addChild(nameText);
self.moveSpeed = 4;
self.targetPuppy = null;
self.update = function () {
if (selectedPuppy && selectedPuppy.isSelected) {
self.targetPuppy = selectedPuppy;
}
if (self.targetPuppy) {
var dx = self.targetPuppy.x - self.x;
var dy = self.targetPuppy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
}
}
};
return self;
});
var GhostPuppy = Container.expand(function () {
var self = Container.call(this);
var puppyGraphics = self.attachAsset('ghostpuppy', {
anchorX: 0.5,
anchorY: 0.5
});
puppyGraphics.alpha = 0.7; // Semi-transparent for ghost effect
var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley'];
self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)];
self.age = Math.floor(Math.random() * 20) + 1; // Random age between 1-20 months
self.isSelected = false;
self.moveSpeed = 8;
self.lastX = 0;
self.lastY = 0;
self.type = 'ghost';
var nameText = new Text2(self.name + ' (' + self.age + ' mois) [Fantôme]', {
size: 35,
fill: 0x9999ff
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -80;
self.addChild(nameText);
self.down = function (x, y, obj) {
selectedPuppy = self;
// Clear all selections
for (var i = 0; i < puppies.length; i++) {
puppies[i].isSelected = false;
puppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < ghostPuppies.length; i++) {
ghostPuppies[i].isSelected = false;
ghostPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < dragonPuppies.length; i++) {
dragonPuppies[i].isSelected = false;
dragonPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < sirenPuppies.length; i++) {
sirenPuppies[i].isSelected = false;
sirenPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < vampirePuppies.length; i++) {
vampirePuppies[i].isSelected = false;
vampirePuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < legendaryPuppies.length; i++) {
legendaryPuppies[i].isSelected = false;
legendaryPuppies[i].tint = 0xFFFFFF;
}
self.isSelected = true;
self.tint = 0xFFFF00;
};
self.moveTowards = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
} else {
self.x = targetX;
self.y = targetY;
}
};
return self;
});
var LegendaryPuppy = Container.expand(function () {
var self = Container.call(this);
var puppyGraphics = self.attachAsset('legendarypuppy', {
anchorX: 0.5,
anchorY: 0.5
});
puppyGraphics.tint = 0xFFD700; // Gold tint for legendary
var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley'];
self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)];
self.isSelected = false;
self.moveSpeed = 8;
self.lastX = 0;
self.lastY = 0;
self.type = 'legendary';
var nameText = new Text2(self.name + ' [LÉGENDAIRE]', {
size: 35,
fill: 0xFFD700
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -80;
self.addChild(nameText);
self.down = function (x, y, obj) {
selectedPuppy = self;
// Clear all selections
for (var i = 0; i < puppies.length; i++) {
puppies[i].isSelected = false;
puppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < ghostPuppies.length; i++) {
ghostPuppies[i].isSelected = false;
ghostPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < dragonPuppies.length; i++) {
dragonPuppies[i].isSelected = false;
dragonPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < sirenPuppies.length; i++) {
sirenPuppies[i].isSelected = false;
sirenPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < vampirePuppies.length; i++) {
vampirePuppies[i].isSelected = false;
vampirePuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < legendaryPuppies.length; i++) {
legendaryPuppies[i].isSelected = false;
legendaryPuppies[i].tint = 0xFFFFFF;
}
self.isSelected = true;
self.tint = 0xFFFF00;
};
self.moveTowards = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
} else {
self.x = targetX;
self.y = targetY;
}
};
return self;
});
var Lucie = Container.expand(function () {
var self = Container.call(this);
var lucieGraphics = self.attachAsset('lucie', {
anchorX: 0.5,
anchorY: 0.5
});
var nameText = new Text2('Lucie', {
size: 40,
fill: 0x00CED1
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -100;
self.addChild(nameText);
return self;
});
var MrPervers = Container.expand(function () {
var self = Container.call(this);
var chefGraphics = self.attachAsset('mrpervers', {
anchorX: 0.5,
anchorY: 0.5
});
var nameText = new Text2('Mr. Pervers', {
size: 50,
fill: 0xFF0000
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -100;
self.addChild(nameText);
self.moveSpeed = 3;
self.targetPuppy = null;
self.lastTargetX = 0;
self.lastTargetY = 0;
self.update = function () {
// Don't move if Samantha made Mr. Pervers sleep
if (samanthaActive) {
return;
}
if (selectedPuppy && selectedPuppy.isSelected) {
self.targetPuppy = selectedPuppy;
}
if (self.targetPuppy) {
var dx = self.targetPuppy.x - self.x;
var dy = self.targetPuppy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
}
}
};
return self;
});
var Puppy = Container.expand(function () {
var self = Container.call(this);
var puppyGraphics = self.attachAsset('puppy', {
anchorX: 0.5,
anchorY: 0.5
});
var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley'];
self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)];
self.age = Math.floor(Math.random() * 20) + 1; // Random age between 1-20 months
self.isSelected = false;
self.moveSpeed = 8;
self.lastX = 0;
self.lastY = 0;
var nameText = new Text2(self.name + ' (' + self.age + ' mois)', {
size: 40,
fill: 0x000000
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -80;
self.addChild(nameText);
self.down = function (x, y, obj) {
selectedPuppy = self;
// Clear all selections
for (var i = 0; i < puppies.length; i++) {
puppies[i].isSelected = false;
puppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < ghostPuppies.length; i++) {
ghostPuppies[i].isSelected = false;
ghostPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < dragonPuppies.length; i++) {
dragonPuppies[i].isSelected = false;
dragonPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < sirenPuppies.length; i++) {
sirenPuppies[i].isSelected = false;
sirenPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < vampirePuppies.length; i++) {
vampirePuppies[i].isSelected = false;
vampirePuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < legendaryPuppies.length; i++) {
legendaryPuppies[i].isSelected = false;
legendaryPuppies[i].tint = 0xFFFFFF;
}
self.isSelected = true;
self.tint = 0xFFFF00;
};
self.moveTowards = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
} else {
self.x = targetX;
self.y = targetY;
}
};
return self;
});
var Samantha = Container.expand(function () {
var self = Container.call(this);
// Use dedicated Samantha asset
var samanthaGraphics = self.attachAsset('samantha', {
anchorX: 0.5,
anchorY: 0.5
});
var nameText = new Text2('Samantha', {
size: 40,
fill: 0xFF1493
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -100;
self.addChild(nameText);
self.moveSpeed = 5;
self.moveTowards = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
} else {
self.x = targetX;
self.y = targetY;
}
};
return self;
});
var SirenPuppy = Container.expand(function () {
var self = Container.call(this);
var puppyGraphics = self.attachAsset('sirenpuppy', {
anchorX: 0.5,
anchorY: 0.5
});
puppyGraphics.tint = 0x44ffff; // Cyan tint for siren
var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley'];
self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)];
self.isSelected = false;
self.moveSpeed = 8;
self.lastX = 0;
self.lastY = 0;
self.type = 'siren';
var nameText = new Text2(self.name + ' [Sirène]', {
size: 35,
fill: 0x44ffff
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -80;
self.addChild(nameText);
self.down = function (x, y, obj) {
selectedPuppy = self;
// Clear all selections
for (var i = 0; i < puppies.length; i++) {
puppies[i].isSelected = false;
puppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < ghostPuppies.length; i++) {
ghostPuppies[i].isSelected = false;
ghostPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < dragonPuppies.length; i++) {
dragonPuppies[i].isSelected = false;
dragonPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < sirenPuppies.length; i++) {
sirenPuppies[i].isSelected = false;
sirenPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < vampirePuppies.length; i++) {
vampirePuppies[i].isSelected = false;
vampirePuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < legendaryPuppies.length; i++) {
legendaryPuppies[i].isSelected = false;
legendaryPuppies[i].tint = 0xFFFFFF;
}
self.isSelected = true;
self.tint = 0xFFFF00;
};
self.moveTowards = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
} else {
self.x = targetX;
self.y = targetY;
}
};
return self;
});
var VampirePuppy = Container.expand(function () {
var self = Container.call(this);
var puppyGraphics = self.attachAsset('vampirepuppy', {
anchorX: 0.5,
anchorY: 0.5
});
puppyGraphics.tint = 0x800080; // Purple tint for vampire
var puppyNames = ['Buddy', 'Max', 'Bella', 'Charlie', 'Lucy', 'Cooper', 'Luna', 'Bailey', 'Daisy', 'Rocky', 'Molly', 'Jack', 'Lola', 'Duke', 'Sadie', 'Tucker', 'Chloe', 'Bear', 'Sophie', 'Teddy', 'Roxy', 'Buster', 'Coco', 'Gus', 'Penny', 'Oscar', 'Nala', 'Milo', 'Rosie', 'Leo', 'Zoey', 'Zeus', 'Lily', 'Finn', 'Ruby', 'Ollie', 'Stella', 'Jasper', 'Ellie', 'Murphy', 'Maggie', 'Toby', 'Gracie', 'Oliver', 'Abby', 'Winston', 'Zoe', 'Bentley', 'Mia', 'Harley'];
self.name = puppyNames[Math.floor(Math.random() * puppyNames.length)];
self.isSelected = false;
self.moveSpeed = 8;
self.lastX = 0;
self.lastY = 0;
self.type = 'vampire';
var nameText = new Text2(self.name + ' [Vampire]', {
size: 35,
fill: 0x800080
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -80;
self.addChild(nameText);
self.down = function (x, y, obj) {
selectedPuppy = self;
// Clear all selections
for (var i = 0; i < puppies.length; i++) {
puppies[i].isSelected = false;
puppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < ghostPuppies.length; i++) {
ghostPuppies[i].isSelected = false;
ghostPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < dragonPuppies.length; i++) {
dragonPuppies[i].isSelected = false;
dragonPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < sirenPuppies.length; i++) {
sirenPuppies[i].isSelected = false;
sirenPuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < vampirePuppies.length; i++) {
vampirePuppies[i].isSelected = false;
vampirePuppies[i].tint = 0xFFFFFF;
}
for (var i = 0; i < legendaryPuppies.length; i++) {
legendaryPuppies[i].isSelected = false;
legendaryPuppies[i].tint = 0xFFFFFF;
}
self.isSelected = true;
self.tint = 0xFFFF00;
};
self.moveTowards = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
} else {
self.x = targetX;
self.y = targetY;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xF5DEB3
});
/****
* Game Code
****/
// Game variables
var currentLevel = storage.currentLevel || 1;
var puppiesSaved = 0;
var puppiesRequired = currentLevel === 1 ? 3 : Math.pow(2, currentLevel - 1) * 3;
var puppies = [];
var selectedPuppy = null;
var mrPervers = null;
var exitDoor = null;
var pot = null;
var upButton = null;
var downButton = null;
var leftButton = null;
var rightButton = null;
// SM currency system
var playerSM = storage.playerSM || 0;
var samanthaCost = storage.samanthaCost || 5;
var originalSamanthaCost = samanthaCost;
var samanthaActive = false;
var samanthaEndTime = 0;
var samanthaCharacter = null;
// Eva tracking
var puppiesSavedForEva = 0;
var evaCharacter = null;
var evaEndTime = 0;
// Gabriel tracking
var puppiesSavedForGabriel = 0;
var gabrielCharacter = null;
// Lucie tracking
var samanthaInvocations = 0;
var lucieCharacter = null;
var lucieActive = false;
var lucieEndTime = 0;
var lucieDiscountActive = false;
var lucieDiscountEndTime = 0;
// Special puppy shop system
var specialPuppyShop = {
isOpen: false,
selectedType: null
};
// Special puppy types and costs
var PUPPY_TYPES = {
GHOST: {
name: 'Fantômes',
cost: 6,
multiplier: 1,
hasAge: true
},
DRAGON: {
name: 'Dragons',
cost: 15,
multiplier: 3,
hasAge: false
},
SIREN: {
name: 'Sirènes',
cost: 25,
multiplier: 4,
hasAge: false
},
VAMPIRE: {
name: 'Vampires',
cost: 50,
multiplier: 5,
hasAge: false
},
LEGENDARY: {
name: 'Légendaires',
cost: 1000,
multiplier: 20,
hasAge: false
}
};
// Special puppies arrays
var ghostPuppies = [];
var dragonPuppies = [];
var sirenPuppies = [];
var vampirePuppies = [];
var legendaryPuppies = [];
// Mr. Pervers mean messages
var perversMessages = ["NON! Mes hot dogs de chiot!", "Ce chiot était parfait pour ma saucisse!", "Tu ruines mon menu hot dog!", "J'avais prévu de le servir grillé!", "Mes clients voulaient ce hot dog!", "Cette viande de chiot était premium!", "Tu gâches ma spécialité hot dog!", "Ce chiot aurait fait un délicieux hot dog!", "Mes hot dogs de chiot sont célèbres!", "Tu m'empêches de cuisiner mes hot dogs!", "Ce chiot était destiné à ma marmite!", "Mes hot dogs seront moins savoureux!", "Tu voles mes ingrédients à hot dog!", "Ce chiot était ma recette secrète!", "Mes clients adorent mes hot dogs de chiot!", "Tu sabotes ma production de hot dogs!", "Cette viande était parfaite pour griller!", "Mes hot dogs de chiot sont uniques!", "Tu détruis mon business de hot dogs!", "Ce chiot aurait nourri mes clients!", "Ma spécialité hot dog est ruinée!", "Tu m'empêches de servir mes hot dogs!", "Cette viande de chiot était fraîche!", "Mes hot dogs perdent leur goût!", "Tu voles ma matière première!", "Ce chiot était mon meilleur ingrédient!", "Mes hot dogs de chiot sont ma fierté!", "Tu ruines ma réputation de hot dogs!", "Cette viande était prête à cuire!", "Mes clients vont être déçus!", "Tu gâches ma recette de hot dog!", "Ce chiot était parfait pour les saucisses!", "Mes hot dogs de chiot sont artistiques!", "Tu m'empêches de nourrir mes clients!", "Cette viande aurait été délicieuse!", "Mes hot dogs perdent leur originalité!", "Tu sabotes ma cuisine de hot dogs!", "Ce chiot était ma fortune culinaire!", "Mes hot dogs de chiot sont légendaires!", "Tu détruis mon art du hot dog!", "Cette viande était mon inspiration!", "Mes hot dogs ne seront plus pareils!", "Tu voles mes profits de hot dogs!", "Ce chiot était destiné au grill!", "Mes hot dogs de chiot sont ma passion!", "Tu ruines mes ventes de hot dogs!", "Cette viande était exceptionnelle!", "Mes hot dogs perdent leur magie!", "Tu gâches ma tradition culinaire!", "Ce chiot était mon chef-d'œuvre!", "Mes hot dogs de chiot sont irremplaçables!", "Tu m'empêches de régaler mes clients!", "Cette viande était ma signature!", "Mes hot dogs perdent leur authenticité!", "Tu sabotes mon empire hot dog!", "Ce chiot était mon trésor culinaire!", "Mes hot dogs de chiot sont mon héritage!", "Tu détruis ma chaîne de restaurants!", "Cette viande était ma spécialité!", "Mes hot dogs ne seront plus uniques!", "Tu voles mon succès culinaire!", "Ce chiot était parfait pour mes saucisses!", "Mes hot dogs de chiot sont ma vie!", "Tu ruines mes rêves de restaurateur!", "Cette viande était mon avenir!", "Mes hot dogs perdent leur saveur!", "Tu gâches ma réputation mondiale!", "Ce chiot était destiné à mes clients!", "Mes hot dogs de chiot sont mon génie!", "Tu m'empêches de devenir riche!", "Cette viande était ma révolution!", "Mes hot dogs ne seront plus parfaits!", "Tu sabotes mon innovation culinaire!", "Ce chiot était mon diamant brut!", "Mes hot dogs de chiot sont mon destin!", "Tu détruis mon rêve américain!"];
var messageText = null;
// UI elements
var levelText = new Text2('Level: ' + currentLevel, {
size: 60,
fill: 0x000000
});
levelText.anchor.set(0, 0);
levelText.x = 120;
levelText.y = 50;
LK.gui.topLeft.addChild(levelText);
var savedText = new Text2('Saved: 0/' + puppiesRequired, {
size: 60,
fill: 0x000000
});
savedText.anchor.set(0.5, 0);
savedText.x = 0;
savedText.y = 50;
LK.gui.top.addChild(savedText);
var scoreText = new Text2('Score: ' + LK.getScore(), {
size: 60,
fill: 0x000000
});
scoreText.anchor.set(1, 0);
scoreText.x = 0;
scoreText.y = 50;
LK.gui.topRight.addChild(scoreText);
var smText = new Text2('SM: ' + playerSM, {
size: 50,
fill: 0x000000
});
smText.anchor.set(1, 0);
smText.x = 0;
smText.y = 120;
LK.gui.topRight.addChild(smText);
// Background
var background = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
// Exit door
exitDoor = game.addChild(LK.getAsset('exitdoor', {
anchorX: 0.5,
anchorY: 1,
x: 1024,
y: 2700
}));
var exitText = new Text2('EXIT', {
size: 40,
fill: 0xFFFFFF
});
exitText.anchor.set(0.5, 0.5);
exitText.y = -150;
exitDoor.addChild(exitText);
// Cooking pot
pot = game.addChild(LK.getAsset('pot', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 400
}));
// Mr. Pervers
mrPervers = game.addChild(new MrPervers());
mrPervers.x = 1024;
mrPervers.y = 500;
// Directional buttons
upButton = game.addChild(new DirectionalButton('up'));
upButton.x = 1700;
upButton.y = 2200;
downButton = game.addChild(new DirectionalButton('down'));
downButton.x = 1700;
downButton.y = 2400;
leftButton = game.addChild(new DirectionalButton('left'));
leftButton.x = 1600;
leftButton.y = 2300;
rightButton = game.addChild(new DirectionalButton('right'));
rightButton.x = 1800;
rightButton.y = 2300;
// Invoke Samantha button
var invokeSamButton = new Container();
var invokeSamGraphics = invokeSamButton.attachAsset('downbutton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1.5
});
invokeSamGraphics.tint = 0xFF69B4; // Pink color
var invokeSamText = new Text2('Invoque Sam\n(' + samanthaCost + ' SM)', {
size: 30,
fill: 0xFFFFFF
});
invokeSamText.anchor.set(0.5, 0.5);
invokeSamButton.addChild(invokeSamText);
invokeSamButton.x = 300;
invokeSamButton.y = 2300;
invokeSamButton.down = function (x, y, obj) {
var currentCost = lucieDiscountActive ? Math.ceil(samanthaCost * 0.4) : samanthaCost;
if (playerSM >= currentCost && !samanthaActive) {
invokeSamantha();
}
};
game.addChild(invokeSamButton);
// Shop button
var shopButton = new Container();
var shopGraphics = shopButton.attachAsset('shopButton', {
anchorX: 0.5,
anchorY: 0.5
});
var shopText = new Text2('Boutique', {
size: 30,
fill: 0x000000
});
shopText.anchor.set(0.5, 0.5);
shopButton.addChild(shopText);
shopButton.x = 500;
shopButton.y = 2300;
shopButton.down = function (x, y, obj) {
if (!specialPuppyShop.isOpen) {
openShop();
}
};
game.addChild(shopButton);
// Functions
function spawnPuppies() {
var numPuppies = 1;
if (currentLevel >= 11) {
numPuppies = Math.floor(Math.random() * 6) + 5; // 5-10 puppies
} else if (currentLevel >= 5) {
numPuppies = Math.floor(Math.random() * 4) + 2; // 2-5 puppies
}
for (var i = 0; i < numPuppies; i++) {
var puppy = new Puppy();
puppy.x = Math.random() * 1500 + 300;
puppy.y = Math.random() * 1000 + 800;
puppy.lastX = puppy.x;
puppy.lastY = puppy.y;
puppies.push(puppy);
game.addChild(puppy);
}
}
function checkCollisions() {
// Check normal puppies
for (var i = puppies.length - 1; i >= 0; i--) {
var puppy = puppies[i];
// Check if puppy reached exit
if (puppy.intersects(exitDoor)) {
// Puppies over 10 months count as 2 saved puppies
var puppyValue = puppy.age > 10 ? 2 : 1;
puppiesSaved += puppyValue;
puppiesSavedForEva += puppyValue;
puppiesSavedForGabriel += puppyValue;
LK.setScore(LK.getScore() + puppyValue);
// Give SM reward
playerSM += 3;
storage.playerSM = playerSM;
LK.getSound('puppysaved').play();
// Show Mr. Pervers angry message (only if Mr. Pervers is awake)
if (!samanthaActive) {
showPerversMessage();
}
// Check Eva appearance (level 5+, every 6 puppies saved, 50% chance)
if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) {
puppiesSavedForEva = 0;
if (Math.random() < 0.5) {
spawnEva();
}
}
// Check Gabriel appearance (every 3 puppies saved, random chance)
if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) {
puppiesSavedForGabriel = 0;
if (Math.random() < 0.5) {
spawnGabriel();
}
}
puppy.destroy();
puppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
updateUI();
if (puppiesSaved >= puppiesRequired) {
nextLevel();
}
continue;
}
// Check if puppy caught by Mr. Pervers (only if Mr. Pervers is not sleeping)
if (puppy.intersects(mrPervers) && !samanthaActive && LK.ticks >= vampireSleepEndTime) {
LK.setScore(LK.getScore() - 1);
LK.getSound('puppycaught').play();
puppy.destroy();
puppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
updateUI();
if (puppies.length === 0 && puppiesSaved < puppiesRequired) {
LK.showGameOver();
}
}
// Check if puppy caught by Gabriel (no game over, just remove puppy)
if (gabrielCharacter && puppy.intersects(gabrielCharacter)) {
puppy.destroy();
puppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
continue;
}
}
// Check ghost puppies (ignored by Mr. Pervers and Gabriel)
for (var i = ghostPuppies.length - 1; i >= 0; i--) {
var puppy = ghostPuppies[i];
if (puppy.intersects(exitDoor)) {
var puppyValue = puppy.age > 10 ? 2 : 1;
puppiesSaved += puppyValue;
puppiesSavedForEva += puppyValue;
puppiesSavedForGabriel += puppyValue;
LK.setScore(LK.getScore() + puppyValue);
playerSM += 3;
storage.playerSM = playerSM;
LK.getSound('puppysaved').play();
if (!samanthaActive) {
showPerversMessage();
}
// Check Eva and Gabriel appearances
if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) {
puppiesSavedForEva = 0;
if (Math.random() < 0.5) {
spawnEva();
}
}
if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) {
puppiesSavedForGabriel = 0;
if (Math.random() < 0.5) {
spawnGabriel();
}
}
puppy.destroy();
ghostPuppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
updateUI();
if (puppiesSaved >= puppiesRequired) {
nextLevel();
}
}
}
// Check dragon puppies (only catchable by Mr. Pervers, ignored by Gabriel)
for (var i = dragonPuppies.length - 1; i >= 0; i--) {
var puppy = dragonPuppies[i];
if (puppy.intersects(exitDoor)) {
var puppyValue = 3; // Dragons count triple
puppiesSaved += puppyValue;
puppiesSavedForEva += puppyValue;
puppiesSavedForGabriel += puppyValue;
LK.setScore(LK.getScore() + puppyValue);
playerSM += 9; // 3x reward
storage.playerSM = playerSM;
LK.getSound('puppysaved').play();
if (!samanthaActive) {
showPerversMessage();
}
// Check Eva and Gabriel appearances
if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) {
puppiesSavedForEva = 0;
if (Math.random() < 0.5) {
spawnEva();
}
}
if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) {
puppiesSavedForGabriel = 0;
if (Math.random() < 0.5) {
spawnGabriel();
}
}
puppy.destroy();
dragonPuppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
updateUI();
if (puppiesSaved >= puppiesRequired) {
nextLevel();
}
continue;
}
// Dragons can be caught by Mr. Pervers
if (puppy.intersects(mrPervers) && !samanthaActive && LK.ticks >= vampireSleepEndTime) {
LK.setScore(LK.getScore() - 3);
LK.getSound('puppycaught').play();
puppy.destroy();
dragonPuppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
updateUI();
}
}
// Check siren puppies (only catchable by Gabriel, ignored by Mr. Pervers)
for (var i = sirenPuppies.length - 1; i >= 0; i--) {
var puppy = sirenPuppies[i];
if (puppy.intersects(exitDoor)) {
var puppyValue = 4; // Sirens count quadruple
puppiesSaved += puppyValue;
puppiesSavedForEva += puppyValue;
puppiesSavedForGabriel += puppyValue;
LK.setScore(LK.getScore() + puppyValue);
playerSM += 12; // 4x reward
storage.playerSM = playerSM;
LK.getSound('puppysaved').play();
if (!samanthaActive) {
showPerversMessage();
}
// Check Eva and Gabriel appearances
if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) {
puppiesSavedForEva = 0;
if (Math.random() < 0.5) {
spawnEva();
}
}
if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) {
puppiesSavedForGabriel = 0;
if (Math.random() < 0.5) {
spawnGabriel();
}
}
puppy.destroy();
sirenPuppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
updateUI();
if (puppiesSaved >= puppiesRequired) {
nextLevel();
}
continue;
}
// Sirens can be caught by Gabriel
if (gabrielCharacter && puppy.intersects(gabrielCharacter)) {
puppy.destroy();
sirenPuppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
continue;
}
}
// Check vampire puppies (catchable by both, but put Mr. Pervers to sleep)
for (var i = vampirePuppies.length - 1; i >= 0; i--) {
var puppy = vampirePuppies[i];
if (puppy.intersects(exitDoor)) {
var puppyValue = 5; // Vampires count quintuple
puppiesSaved += puppyValue;
puppiesSavedForEva += puppyValue;
puppiesSavedForGabriel += puppyValue;
LK.setScore(LK.getScore() + puppyValue);
playerSM += 15; // 5x reward
storage.playerSM = playerSM;
LK.getSound('puppysaved').play();
if (!samanthaActive) {
showPerversMessage();
}
// Check Eva and Gabriel appearances
if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) {
puppiesSavedForEva = 0;
if (Math.random() < 0.5) {
spawnEva();
}
}
if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) {
puppiesSavedForGabriel = 0;
if (Math.random() < 0.5) {
spawnGabriel();
}
}
puppy.destroy();
vampirePuppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
updateUI();
if (puppiesSaved >= puppiesRequired) {
nextLevel();
}
continue;
}
// Vampires can be caught by Mr. Pervers but put him to sleep
if (puppy.intersects(mrPervers) && !samanthaActive && LK.ticks >= vampireSleepEndTime) {
LK.setScore(LK.getScore() - 5);
LK.getSound('puppycaught').play();
// Put Mr. Pervers to sleep for 2 minutes
vampireSleepEndTime = LK.ticks + 2 * 60 * 60; // 2 minutes at 60 FPS
mrPervers.tint = 0x808080; // Gray tint to show sleeping
puppy.destroy();
vampirePuppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
updateUI();
continue;
}
// Vampires can be caught by Gabriel
if (gabrielCharacter && puppy.intersects(gabrielCharacter)) {
puppy.destroy();
vampirePuppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
continue;
}
}
// Check legendary puppies (ignored by both, put them to sleep on collision)
for (var i = legendaryPuppies.length - 1; i >= 0; i--) {
var puppy = legendaryPuppies[i];
if (puppy.intersects(exitDoor)) {
var puppyValue = 20; // Legendaries count as 20
puppiesSaved += puppyValue;
puppiesSavedForEva += puppyValue;
puppiesSavedForGabriel += puppyValue;
LK.setScore(LK.getScore() + puppyValue);
playerSM += 60; // 20x reward
storage.playerSM = playerSM;
LK.getSound('puppysaved').play();
if (!samanthaActive) {
showPerversMessage();
}
// Check Eva and Gabriel appearances
if (currentLevel >= 5 && puppiesSavedForEva >= 6 && !samanthaActive && !evaCharacter) {
puppiesSavedForEva = 0;
if (Math.random() < 0.5) {
spawnEva();
}
}
if (puppiesSavedForGabriel >= 3 && !gabrielCharacter) {
puppiesSavedForGabriel = 0;
if (Math.random() < 0.5) {
spawnGabriel();
}
}
puppy.destroy();
legendaryPuppies.splice(i, 1);
if (selectedPuppy === puppy) {
selectedPuppy = null;
}
updateUI();
if (puppiesSaved >= puppiesRequired) {
nextLevel();
}
continue;
}
// Legendary puppies put Mr. Pervers to sleep on collision
if (puppy.intersects(mrPervers)) {
vampireSleepEndTime = LK.ticks + 10 * 60 * 60; // 10 minutes at 60 FPS
mrPervers.tint = 0x808080; // Gray tint to show sleeping
}
// Legendary puppies put Gabriel to sleep on collision
if (gabrielCharacter && puppy.intersects(gabrielCharacter)) {
gabrielCharacter.destroy();
gabrielCharacter = null;
}
}
}
function updateUI() {
savedText.setText('Saved: ' + puppiesSaved + '/' + puppiesRequired);
scoreText.setText('Score: ' + LK.getScore());
smText.setText('SM: ' + playerSM);
var displayCost = lucieDiscountActive ? Math.ceil(samanthaCost * 0.4) : samanthaCost;
var costText = lucieDiscountActive ? displayCost + ' SM (60% OFF!)' : displayCost + ' SM';
invokeSamText.setText('Invoque Sam\n(' + costText + ')');
}
function showPerversMessage() {
// Remove existing message if any
if (messageText) {
messageText.destroy();
messageText = null;
}
// Get random message
var randomMessage = perversMessages[Math.floor(Math.random() * perversMessages.length)];
// Create message text
messageText = new Text2(randomMessage, {
size: 80,
fill: 0xFF0000
});
messageText.anchor.set(0.5, 0.5);
messageText.x = 1024;
messageText.y = 1200;
messageText.alpha = 1;
// Add to game
game.addChild(messageText);
// Animate message appearing with scale and fade
tween(messageText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.bounceOut
});
// Fade out and remove after 15 seconds
LK.setTimeout(function () {
if (messageText) {
tween(messageText, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
if (messageText) {
messageText.destroy();
messageText = null;
}
}
});
}
}, 15000);
}
function invokeSamantha() {
// Apply Lucie discount if active
var currentCost = lucieDiscountActive ? Math.ceil(samanthaCost * 0.4) : samanthaCost;
// Deduct SM cost
playerSM -= currentCost;
storage.playerSM = playerSM;
// Increase cost for next invocation (30% increase)
samanthaCost = Math.ceil(samanthaCost * 1.3);
storage.samanthaCost = samanthaCost;
// Track invocations for Lucie
samanthaInvocations++;
// Create Samantha
samanthaCharacter = game.addChild(new Samantha());
samanthaCharacter.x = 100;
samanthaCharacter.y = 1000;
// Set Mr. Pervers to sleep and Samantha active
samanthaActive = true;
samanthaEndTime = LK.ticks + 6 * 60 * 60; // 6 minutes at 60 FPS
// Make Mr. Pervers sleep (stop moving and change tint)
mrPervers.tint = 0x808080; // Gray tint to show sleeping
// Check Lucie appearance (every 2 invocations)
if (samanthaInvocations >= 2 && !lucieCharacter) {
samanthaInvocations = 0;
spawnLucie();
}
updateUI();
}
function wakeMrPervers() {
samanthaActive = false;
mrPervers.tint = 0xFFFFFF; // Reset tint
// Remove Samantha
if (samanthaCharacter) {
samanthaCharacter.destroy();
samanthaCharacter = null;
}
}
function spawnEva() {
evaCharacter = game.addChild(new Eva());
evaCharacter.x = 200;
evaCharacter.y = 1500;
evaEndTime = LK.ticks + 15 * 60; // 15 seconds at 60 FPS
// 50% chance Eva will invoke Samantha
if (Math.random() < 0.5) {
// Eva invokes Samantha after 2 seconds
LK.setTimeout(function () {
if (evaCharacter && !samanthaActive) {
// Create Samantha for free
samanthaCharacter = game.addChild(new Samantha());
samanthaCharacter.x = 100;
samanthaCharacter.y = 1000;
samanthaActive = true;
samanthaEndTime = LK.ticks + 6 * 60 * 60; // 6 minutes at 60 FPS
mrPervers.tint = 0x808080; // Gray tint to show sleeping
// Remove Eva immediately when Samantha arrives
if (evaCharacter) {
evaCharacter.destroy();
evaCharacter = null;
}
}
}, 2000);
}
}
function spawnGabriel() {
gabrielCharacter = game.addChild(new Gabriel());
gabrielCharacter.x = 1800;
gabrielCharacter.y = 1000;
}
function spawnLucie() {
lucieCharacter = game.addChild(new Lucie());
lucieCharacter.x = 1024;
lucieCharacter.y = 1500;
lucieActive = true;
lucieEndTime = LK.ticks + 20 * 60; // 20 seconds at 60 FPS
// After Lucie appears, activate 60% discount for 2 minutes
LK.setTimeout(function () {
if (lucieCharacter) {
lucieCharacter.destroy();
lucieCharacter = null;
lucieActive = false;
// Activate discount
lucieDiscountActive = true;
lucieDiscountEndTime = LK.ticks + 2 * 60 * 60; // 2 minutes at 60 FPS
updateUI();
}
}, 20000);
}
// Vampire sleep tracking
var vampireSleepEndTime = 0;
function getMaxPuppiesForType(type) {
switch (type) {
case 'GHOST':
if (currentLevel < 10) return currentLevel < 10 ? 5 : 0;
return currentLevel > 10 ? 13 : 5;
case 'DRAGON':
if (currentLevel < 7) return 0;
return currentLevel < 20 ? 6 : 15;
case 'SIREN':
if (currentLevel < 10) return 0;
return currentLevel < 30 ? 7 : 20;
case 'VAMPIRE':
if (currentLevel < 15) return 0;
return currentLevel < 40 ? 9 : 25;
case 'LEGENDARY':
if (currentLevel < 90) return 0;
if (currentLevel <= 150) return 3;
return 7;
default:
return 0;
}
}
function isTypeAvailable(type) {
switch (type) {
case 'GHOST':
return true;
case 'DRAGON':
return currentLevel >= 7;
case 'SIREN':
return currentLevel >= 10;
case 'VAMPIRE':
return currentLevel >= 15;
case 'LEGENDARY':
return currentLevel >= 90;
default:
return false;
}
}
function openShop() {
specialPuppyShop.isOpen = true;
// Create shop background
var shopBg = game.addChild(LK.getAsset('shopBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
alpha: 0.9
}));
shopBg.shopElement = true;
// Shop title
var shopTitle = new Text2('Boutique de Chiots Spéciaux', {
size: 60,
fill: 0xFFFFFF
});
shopTitle.anchor.set(0.5, 0.5);
shopTitle.x = 1024;
shopTitle.y = 800;
shopTitle.shopElement = true;
game.addChild(shopTitle);
// Create type buttons
var yPos = 1000;
var buttonIndex = 0;
for (var typeKey in PUPPY_TYPES) {
var type = PUPPY_TYPES[typeKey];
var available = isTypeAvailable(typeKey);
var maxPuppies = getMaxPuppiesForType(typeKey);
var typeButton = new Container();
var buttonGraphics = typeButton.attachAsset('typeButton', {
anchorX: 0.5,
anchorY: 0.5
});
if (!available) {
buttonGraphics.tint = 0x666666; // Gray out unavailable types
}
var buttonText = new Text2(type.name + '\n' + type.cost + ' SM\nMax: ' + maxPuppies, {
size: 25,
fill: available ? 0xFFFFFF : 0x999999
});
buttonText.anchor.set(0.5, 0.5);
typeButton.addChild(buttonText);
typeButton.x = 1024;
typeButton.y = yPos;
typeButton.shopElement = true;
typeButton.typeKey = typeKey;
if (available && maxPuppies > 0) {
typeButton.down = function (x, y, obj) {
selectPuppyType(this.typeKey);
};
}
game.addChild(typeButton);
yPos += 120;
buttonIndex++;
}
// Close button
var closeButton = new Container();
var closeGraphics = closeButton.attachAsset('typeButton', {
anchorX: 0.5,
anchorY: 0.5
});
closeGraphics.tint = 0xff0000;
var closeText = new Text2('Fermer', {
size: 30,
fill: 0xFFFFFF
});
closeText.anchor.set(0.5, 0.5);
closeButton.addChild(closeText);
closeButton.x = 1024;
closeButton.y = 1800;
closeButton.shopElement = true;
closeButton.down = function (x, y, obj) {
closeShop();
};
game.addChild(closeButton);
}
function selectPuppyType(typeKey) {
specialPuppyShop.selectedType = typeKey;
closeShop();
openNumberSelector(typeKey);
}
function openNumberSelector(typeKey) {
var type = PUPPY_TYPES[typeKey];
if (!type) {
console.log('Invalid puppy type:', typeKey);
return;
}
var maxPuppies = getMaxPuppiesForType(typeKey);
if (!isTypeAvailable(typeKey) || maxPuppies === 0) {
console.log('Type not available or max reached:', typeKey);
return;
}
// Define colors and special text for each type
var typeColors = {
GHOST: 0x9999ff,
DRAGON: 0xff4444,
SIREN: 0x44ffff,
VAMPIRE: 0x800080,
LEGENDARY: 0xFFD700
};
var typeDescriptions = {
GHOST: 'Ignorés par Mr. Pervers et Gabriel\nSystème d\'âge appliqué',
DRAGON: 'Visibles par Mr. Pervers seulement\nComptent triple au sauvetage',
SIREN: 'Attrapables par Gabriel seulement\nComptent quadruple au sauvetage',
VAMPIRE: 'Endorment Mr. Pervers 2 minutes\nComptent quintuple au sauvetage',
LEGENDARY: 'Ignorent tout, endorment 10 min\nComptent comme 20 chiots!'
};
var bgColor = typeColors[typeKey] || 0x4444ff;
// Create number selector background with type-specific color
var selectorBg = game.addChild(LK.getAsset('shopBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
alpha: 0.9
}));
selectorBg.tint = bgColor;
selectorBg.selectorElement = true;
// Title with type-specific styling
var selectorTitle = new Text2('Achat de Chiots ' + type.name, {
size: 50,
fill: 0xFFFFFF
});
selectorTitle.anchor.set(0.5, 0.5);
selectorTitle.x = 1024;
selectorTitle.y = 800;
selectorTitle.selectorElement = true;
game.addChild(selectorTitle);
// Type description
var descriptionText = new Text2(typeDescriptions[typeKey], {
size: 30,
fill: 0xFFFFFF
});
descriptionText.anchor.set(0.5, 0.5);
descriptionText.x = 1024;
descriptionText.y = 900;
descriptionText.selectorElement = true;
game.addChild(descriptionText);
// Level requirement and max display
var requirementText = '';
switch (typeKey) {
case 'GHOST':
requirementText = 'Disponible dès le niveau 1';
break;
case 'DRAGON':
requirementText = 'Requis niveau 7+';
break;
case 'SIREN':
requirementText = 'Requis niveau 10+';
break;
case 'VAMPIRE':
requirementText = 'Requis niveau 15+';
break;
case 'LEGENDARY':
requirementText = 'Requis niveau 90+';
break;
}
var reqText = new Text2(requirementText + ' | Maximum: ' + maxPuppies, {
size: 25,
fill: 0xFFFFFF
});
reqText.anchor.set(0.5, 0.5);
reqText.x = 1024;
reqText.y = 980;
reqText.selectorElement = true;
game.addChild(reqText);
// Current number display
var currentNumber = 1;
var numberDisplay = new Text2(currentNumber.toString(), {
size: 80,
fill: 0xFFFFFF
});
numberDisplay.anchor.set(0.5, 0.5);
numberDisplay.x = 1024;
numberDisplay.y = 1100;
numberDisplay.selectorElement = true;
game.addChild(numberDisplay);
// Cost display with type-specific styling
var costDisplay = new Text2('Coût: ' + currentNumber * type.cost + ' SM', {
size: 40,
fill: 0xFFFFFF
});
costDisplay.anchor.set(0.5, 0.5);
costDisplay.x = 1024;
costDisplay.y = 1200;
costDisplay.selectorElement = true;
game.addChild(costDisplay);
// Number buttons with type-specific color
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
var startX = 1024 - 200;
var startY = 1300;
for (var i = 0; i < numbers.length; i++) {
var num = numbers[i];
var numberButton = new Container();
var numberGraphics = numberButton.attachAsset('numberButton', {
anchorX: 0.5,
anchorY: 0.5
});
numberGraphics.tint = bgColor;
var numText = new Text2(num.toString(), {
size: 30,
fill: 0xFFFFFF
});
numText.anchor.set(0.5, 0.5);
numberButton.addChild(numText);
numberButton.x = startX + i % 5 * 100;
numberButton.y = startY + Math.floor(i / 5) * 100;
numberButton.selectorElement = true;
numberButton.number = num;
numberButton.down = function (x, y, obj) {
var digit = obj.parent.number;
if (currentNumber === 0 || currentNumber.toString().length >= 2) {
currentNumber = digit;
} else {
currentNumber = currentNumber * 10 + digit;
}
if (currentNumber > maxPuppies) {
currentNumber = maxPuppies;
}
numberDisplay.setText(currentNumber.toString());
costDisplay.setText('Coût: ' + currentNumber * type.cost + ' SM');
};
game.addChild(numberButton);
}
// Validate button with type-specific color
var validateButton = new Container();
var validateGraphics = validateButton.attachAsset('typeButton', {
anchorX: 0.5,
anchorY: 0.5
});
validateGraphics.tint = 0x00ff00;
var validateText = new Text2('Acheter ' + type.name, {
size: 25,
fill: 0xFFFFFF
});
validateText.anchor.set(0.5, 0.5);
validateButton.addChild(validateText);
validateButton.x = 924;
validateButton.y = 1600;
validateButton.selectorElement = true;
validateButton.down = function (x, y, obj) {
var totalCost = currentNumber * type.cost;
if (playerSM >= totalCost && currentNumber > 0) {
purchasePuppies(typeKey, currentNumber, totalCost);
}
closeNumberSelector();
};
game.addChild(validateButton);
// Cancel button
var cancelButton = new Container();
var cancelGraphics = cancelButton.attachAsset('typeButton', {
anchorX: 0.5,
anchorY: 0.5
});
cancelGraphics.tint = 0xff0000;
var cancelText = new Text2('Annuler', {
size: 30,
fill: 0xFFFFFF
});
cancelText.anchor.set(0.5, 0.5);
cancelButton.addChild(cancelText);
cancelButton.x = 1124;
cancelButton.y = 1600;
cancelButton.selectorElement = true;
cancelButton.down = function (x, y, obj) {
closeNumberSelector();
};
game.addChild(cancelButton);
}
function closeShop() {
specialPuppyShop.isOpen = false;
// Remove all shop elements
for (var i = game.children.length - 1; i >= 0; i--) {
var child = game.children[i];
if (child.shopElement) {
child.destroy();
}
}
}
function closeNumberSelector() {
// Remove all selector elements
for (var i = game.children.length - 1; i >= 0; i--) {
var child = game.children[i];
if (child.selectorElement) {
child.destroy();
}
}
}
function purchasePuppies(typeKey, count, totalCost) {
playerSM -= totalCost;
storage.playerSM = playerSM;
for (var i = 0; i < count; i++) {
var puppy;
switch (typeKey) {
case 'GHOST':
puppy = new GhostPuppy();
ghostPuppies.push(puppy);
break;
case 'DRAGON':
puppy = new DragonPuppy();
dragonPuppies.push(puppy);
break;
case 'SIREN':
puppy = new SirenPuppy();
sirenPuppies.push(puppy);
break;
case 'VAMPIRE':
puppy = new VampirePuppy();
vampirePuppies.push(puppy);
break;
case 'LEGENDARY':
puppy = new LegendaryPuppy();
legendaryPuppies.push(puppy);
break;
}
puppy.x = Math.random() * 1500 + 300;
puppy.y = Math.random() * 1000 + 800;
puppy.lastX = puppy.x;
puppy.lastY = puppy.y;
game.addChild(puppy);
}
updateUI();
}
function nextLevel() {
currentLevel++;
// Reset to level 1 if we've completed level 200
if (currentLevel > 200) {
currentLevel = 1;
}
storage.currentLevel = currentLevel;
puppiesSaved = 0;
puppiesSavedForEva = 0;
puppiesSavedForGabriel = 0;
puppiesRequired = currentLevel === 1 ? 3 : Math.pow(2, currentLevel - 1) * 3;
// Clear existing puppies
for (var i = 0; i < puppies.length; i++) {
puppies[i].destroy();
}
puppies = [];
// Clear special puppies
for (var i = 0; i < ghostPuppies.length; i++) {
ghostPuppies[i].destroy();
}
ghostPuppies = [];
for (var i = 0; i < dragonPuppies.length; i++) {
dragonPuppies[i].destroy();
}
dragonPuppies = [];
for (var i = 0; i < sirenPuppies.length; i++) {
sirenPuppies[i].destroy();
}
sirenPuppies = [];
for (var i = 0; i < vampirePuppies.length; i++) {
vampirePuppies[i].destroy();
}
vampirePuppies = [];
for (var i = 0; i < legendaryPuppies.length; i++) {
legendaryPuppies[i].destroy();
}
legendaryPuppies = [];
selectedPuppy = null;
// Reset vampire sleep
vampireSleepEndTime = 0;
// Reset Mr. Pervers tint and position
mrPervers.tint = 0xFFFFFF;
mrPervers.x = 1024;
mrPervers.y = 500;
mrPervers.targetPuppy = null;
// Clear all active characters
if (evaCharacter) {
evaCharacter.destroy();
evaCharacter = null;
}
if (gabrielCharacter) {
gabrielCharacter.destroy();
gabrielCharacter = null;
}
if (lucieCharacter) {
lucieCharacter.destroy();
lucieCharacter = null;
lucieActive = false;
}
if (samanthaCharacter && !samanthaActive) {
samanthaCharacter.destroy();
samanthaCharacter = null;
}
// Update UI
levelText.setText('Level: ' + currentLevel);
updateUI();
// Spawn new puppies
spawnPuppies();
}
// Initialize first level
spawnPuppies();
// Start background music
LK.playMusic('bgmusic');
game.update = function () {
checkCollisions();
// Handle Samantha timer
if (samanthaActive && LK.ticks >= samanthaEndTime) {
wakeMrPervers();
}
// Move Samantha towards Mr. Pervers if active
if (samanthaActive && samanthaCharacter) {
samanthaCharacter.moveTowards(mrPervers.x, mrPervers.y);
}
// Handle Eva timer
if (evaCharacter && LK.ticks >= evaEndTime) {
evaCharacter.destroy();
evaCharacter = null;
}
// Handle Lucie discount timer
if (lucieDiscountActive && LK.ticks >= lucieDiscountEndTime) {
lucieDiscountActive = false;
updateUI();
}
// Handle vampire sleep timer
if (LK.ticks >= vampireSleepEndTime && vampireSleepEndTime > 0) {
mrPervers.tint = 0xFFFFFF; // Reset tint when waking up
}
// Spawn new puppies if screen is empty and we haven't completed the level
var totalPuppies = puppies.length + ghostPuppies.length + dragonPuppies.length + sirenPuppies.length + vampirePuppies.length + legendaryPuppies.length;
if (totalPuppies === 0 && puppiesSaved < puppiesRequired) {
spawnPuppies();
}
};
Fond d'écran restaurant. In-Game asset. 2d. High contrast. No shadows
Porte de sortie. In-Game asset. 2d. High contrast. No shadows
Cuisiniere. In-Game asset. 2d. High contrast. No shadows
Homme bizzare. In-Game asset. 2d. High contrast. No shadows
Chiot (animal). In-Game asset. 2d. High contrast. No shadows
Petite fille de 10 ans. In-Game asset. 2d. High contrast. No shadows
Petit garçon de 12 ans. In-Game asset. 2d. High contrast. No shadows
Chiot fantôme (animal). In-Game asset. 2d. High contrast. No shadows
Chiot dragon (animal). In-Game asset. 2d. High contrast. No shadows
Chiot dorée (animal). In-Game asset. 2d. High contrast. No shadows
Chiot vampire. In-Game asset. 2d. High contrast. No shadows
Chiot sirène. In-Game asset. 2d. High contrast. No shadows
fond mignon kawaii rose. In-Game asset. 2d. High contrast. No shadows