/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { currentLevel: 1 }); /**** * Classes ****/ var BattleUI = Container.expand(function () { var self = Container.call(this); var panel = self.attachAsset('battlePanel', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); var attackBtn = self.attachAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 200 }); self.beeHealthBar = self.attachAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: -300, y: -150 }); self.spiderHealthBar = self.attachAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: 0, y: -150 }); var beeHealthText = new Text2("Bee: 100/100", { size: 40, fill: 0xFFFFFF }); beeHealthText.anchor.set(0, 0.5); beeHealthText.x = -300; beeHealthText.y = -200; self.addChild(beeHealthText); var spiderHealthText = new Text2("Spider: 50/50", { size: 40, fill: 0xFFFFFF }); spiderHealthText.anchor.set(0, 0.5); spiderHealthText.x = 0; spiderHealthText.y = -200; self.addChild(spiderHealthText); var turnText = new Text2("Your Turn", { size: 60, fill: 0xFFFFFF }); turnText.anchor.set(0.5, 0.5); turnText.y = -300; self.addChild(turnText); var attackText = new Text2("Attack", { size: 50, fill: 0xFFFFFF }); attackText.anchor.set(0.5, 0.5); attackText.x = 0; attackText.y = 200; self.addChild(attackText); self.updateHealth = function (beeHealth, beeMaxHealth, spiderHealth, spiderMaxHealth) { // Update health bars self.beeHealthBar.scale.x = beeHealth / beeMaxHealth; self.spiderHealthBar.scale.x = spiderHealth / spiderMaxHealth; // Update text beeHealthText.setText("Bee: " + beeHealth + "/" + beeMaxHealth); spiderHealthText.setText("Spider: " + spiderHealth + "/" + spiderMaxHealth); }; self.setTurnText = function (isPlayerTurn) { turnText.setText(isPlayerTurn ? "Your Turn" : "Spider's Turn"); }; self.down = function (x, y, obj) { // Check if attack button was pressed if (x >= attackBtn.x - attackBtn.width / 2 && x <= attackBtn.x + attackBtn.width / 2 && y >= attackBtn.y - attackBtn.height / 2 && y <= attackBtn.y + attackBtn.height / 2) { if (self.onAttackPressed && game.battleState.isPlayerTurn) { self.onAttackPressed(); } } }; return self; }); var Bee = Container.expand(function () { var self = Container.call(this); var beeGraphic = self.attachAsset('bee', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.speed = 8; self.jumpForce = -20; self.gravity = 1; self.onGround = false; self.health = 100; self.maxHealth = 100; self.baseMaxHealth = 100; // Base health value self.isJumping = false; self.fallingInVoid = false; self.update = function () { // Apply gravity if (!self.onGround) { self.velocityY += self.gravity; } // Update position self.x += self.velocityX; self.y += self.velocityY; // Reset onGround flag for next frame collision detection self.onGround = false; }; self.moveUp = function () { // Only allow moving up when not jumping if (!self.isJumping) { self.velocityY = -self.speed * 0.8; // Slower than horizontal movement LK.getSound('bzz').play(); } }; self.jump = function () { if (self.onGround) { self.velocityY = self.jumpForce; self.onGround = false; self.isJumping = true; LK.getSound('jump').play(); LK.getSound('bzz').play(); } }; self.moveLeft = function () { self.velocityX = -self.speed; LK.getSound('bzz').play(); }; self.moveRight = function () { self.velocityX = self.speed; LK.getSound('bzz').play(); }; self.stopMoving = function () { self.velocityX = 0; }; self.takeDamage = function (amount) { self.health -= amount; if (self.health < 0) { self.health = 0; } LK.getSound('hurt').play(); }; self.heal = function (amount) { self.health += amount; if (self.health > self.maxHealth) { self.health = self.maxHealth; } }; return self; }); var Bird = Container.expand(function () { var self = Container.call(this); var birdGraphic = self.attachAsset('bird', { anchorX: 0.5, anchorY: 0.5, tint: 0x8B4513, scaleX: 2.0, scaleY: 2.0 }); self.baseMaxHealth = 6000 + Math.floor(Math.random() * 20001); // 6000-26000 self.maxHealth = self.baseMaxHealth; self.health = self.maxHealth; self.attackDamage = 80 + Math.floor(Math.random() * 41); // 80-120 self.defeated = false; self.currentPlatform = null; self.moving = false; self.encounteredByPlayer = false; self.isBird = true; self.moveAwayFromBee = function (bee) { if (self.moving || self.defeated) return; self.moving = true; var originalBeeY = bee.y; var originalBeeX = bee.x; var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8; var keepBeeOnPlatform = isOnSamePlatform; var nearbyPlatforms = []; for (var i = 0; i < platforms.length; i++) { if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) { nearbyPlatforms.push(platforms[i]); } } if (nearbyPlatforms.length === 0) { self.moving = false; return; } nearbyPlatforms.sort(function (a, b) { var distA = Math.abs(a.x - bee.x); var distB = Math.abs(b.x - bee.x); return distB - distA; }); var targetPlatform = nearbyPlatforms[0]; var targetX = targetPlatform.x; var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2; tween(self, { x: targetX, y: targetY }, { duration: 500, easing: tween.easeOutQuad, onFinish: function onFinish() { self.currentPlatform = targetPlatform; self.moving = false; if (keepBeeOnPlatform) { bee.x = originalBeeX; bee.y = originalBeeY; bee.onGround = true; bee.velocityY = 0; bee.isJumping = false; } } }); }; self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0) { self.health = 0; self.defeated = true; } }; self.attack = function () { return self.attackDamage; }; return self; }); var ControlsUI = Container.expand(function () { var self = Container.call(this); // Left button var leftBtn = self.attachAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, x: -800, y: 0, tint: 0x0000FF }); var leftText = new Text2("<", { size: 80, fill: 0xFFFFFF }); leftText.anchor.set(0.5, 0.5); leftText.x = -800; self.addChild(leftText); // Right button var rightBtn = self.attachAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, x: -400, y: 0, tint: 0x0000FF }); var rightText = new Text2(">", { size: 80, fill: 0xFFFFFF }); rightText.anchor.set(0.5, 0.5); rightText.x = -400; self.addChild(rightText); // Jump button var jumpBtn = self.attachAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, x: 800, y: 0, tint: 0x00FF00 }); var jumpText = new Text2("Jump", { size: 50, fill: 0xFFFFFF }); jumpText.anchor.set(0.5, 0.5); jumpText.x = 800; self.addChild(jumpText); // Up button var upBtn = self.attachAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -80, tint: 0x0099FF }); var upText = new Text2("Up", { size: 50, fill: 0xFFFFFF }); upText.anchor.set(0.5, 0.5); upText.x = 0; upText.y = -80; self.addChild(upText); self.down = function (x, y, obj) { // Check if left button was pressed if (x >= leftBtn.x - leftBtn.width / 2 && x <= leftBtn.x + leftBtn.width / 2 && y >= leftBtn.y - leftBtn.height / 2 && y <= leftBtn.y + leftBtn.height / 2) { if (self.onLeftPressed) { self.onLeftPressed(); } } // Check if right button was pressed if (x >= rightBtn.x - rightBtn.width / 2 && x <= rightBtn.x + rightBtn.width / 2 && y >= rightBtn.y - rightBtn.height / 2 && y <= rightBtn.y + rightBtn.height / 2) { if (self.onRightPressed) { self.onRightPressed(); } } // Check if jump button was pressed if (x >= jumpBtn.x - jumpBtn.width / 2 && x <= jumpBtn.x + jumpBtn.width / 2 && y >= jumpBtn.y - jumpBtn.height / 2 && y <= jumpBtn.y + jumpBtn.height / 2) { if (self.onJumpPressed) { self.onJumpPressed(); } } // Check if up button was pressed if (x >= upBtn.x - upBtn.width / 2 && x <= upBtn.x + upBtn.width / 2 && y >= upBtn.y - upBtn.height / 2 && y <= upBtn.y + upBtn.height / 2) { if (self.onUpPressed) { self.onUpPressed(); } } }; self.up = function (x, y, obj) { // When buttons are released, stop movement if (self.onControlsReleased) { self.onControlsReleased(); } }; return self; }); // DividingSpider: special spider that can split into two stronger spiders var DividingSpider = Container.expand(function () { var self = Container.call(this); self.isDividingSpider = true; self.hasDivided = false; // Ensure health properties are always initialized and valid self.baseMaxHealth = 50; self.maxHealth = typeof self.maxHealth === "number" && !isNaN(self.maxHealth) ? self.maxHealth : 50; self.health = typeof self.health === "number" && !isNaN(self.health) ? self.health : self.maxHealth; self.attackDamage = 15; self.defeated = false; self.currentPlatform = null; self.moving = false; // Override attack to deal more damage (random between 15 and 50) self.attack = function () { return 15 + Math.floor(Math.random() * 36); // 15-50 }; // Override takeDamage to allow splitting self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0 && !self.hasDivided) { // Only divide if not already divided self.health = 0; self.defeated = true; self.hasDivided = true; // Spawn two new spiders with more health var newHealth = self.maxHealth + 30 + Math.floor(Math.random() * 40); // More health for (var i = 0; i < 2; i++) { var newSpider = new Spider(); newSpider.baseMaxHealth = 50; newSpider.maxHealth = newHealth; newSpider.health = newHealth; newSpider.attackDamage = 15 + Math.floor(Math.random() * 36); // Place on same platform, offset X newSpider.x = self.x + (i === 0 ? -60 : 60); newSpider.y = self.y; newSpider.currentPlatform = self.currentPlatform; spiders.push(newSpider); game.addChild(newSpider); } } else if (self.health <= 0) { self.health = 0; self.defeated = true; } }; // Add moveAwayFromBee method (copy of Spider's) self.moveAwayFromBee = function (bee) { if (self.moving || self.defeated) { return; } self.moving = true; // Store bee's original position to ensure it doesn't fall var originalBeeY = bee.y; var originalBeeX = bee.x; var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8; var keepBeeOnPlatform = isOnSamePlatform; // Find nearby platforms to move to var nearbyPlatforms = []; for (var i = 0; i < platforms.length; i++) { if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) { nearbyPlatforms.push(platforms[i]); } } // If no nearby platforms, just return if (nearbyPlatforms.length === 0) { self.moving = false; return; } // Sort platforms by distance from bee nearbyPlatforms.sort(function (a, b) { var distA = Math.abs(a.x - bee.x); var distB = Math.abs(b.x - bee.x); return distB - distA; // Further platforms first }); // Get target platform (furthest from bee) var targetPlatform = nearbyPlatforms[0]; var targetX = targetPlatform.x; var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2; // Animate spider moving to new platform tween(self, { x: targetX, y: targetY }, { duration: 500, easing: tween.easeOutQuad, onFinish: function onFinish() { self.currentPlatform = targetPlatform; self.moving = false; // Ensure bee stays on platform if it was on the same platform as spider if (keepBeeOnPlatform) { bee.x = originalBeeX; bee.y = originalBeeY; bee.onGround = true; bee.velocityY = 0; bee.isJumping = false; } } }); }; return self; }); var Dragonfly = Container.expand(function () { var self = Container.call(this); var dragonflyGraphic = self.attachAsset('dragonfly', { anchorX: 0.5, anchorY: 0.5, tint: 0x0099FF, scaleX: 1.5, scaleY: 1.5 }); self.baseMaxHealth = 1000 + Math.floor(Math.random() * 14001); // 1000-15000 self.maxHealth = self.baseMaxHealth; self.health = self.maxHealth; self.attackDamage = 50 + Math.floor(Math.random() * 31); // 50-80 self.defeated = false; self.currentPlatform = null; self.moving = false; self.encounteredByPlayer = false; self.isDragonfly = true; self.moveAwayFromBee = function (bee) { if (self.moving || self.defeated) return; self.moving = true; var originalBeeY = bee.y; var originalBeeX = bee.x; var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8; var keepBeeOnPlatform = isOnSamePlatform; var nearbyPlatforms = []; for (var i = 0; i < platforms.length; i++) { if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) { nearbyPlatforms.push(platforms[i]); } } if (nearbyPlatforms.length === 0) { self.moving = false; return; } nearbyPlatforms.sort(function (a, b) { var distA = Math.abs(a.x - bee.x); var distB = Math.abs(b.x - bee.x); return distB - distA; }); var targetPlatform = nearbyPlatforms[0]; var targetX = targetPlatform.x; var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2; tween(self, { x: targetX, y: targetY }, { duration: 500, easing: tween.easeOutQuad, onFinish: function onFinish() { self.currentPlatform = targetPlatform; self.moving = false; if (keepBeeOnPlatform) { bee.x = originalBeeX; bee.y = originalBeeY; bee.onGround = true; bee.velocityY = 0; bee.isJumping = false; } } }); }; self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0) { self.health = 0; self.defeated = true; } }; self.attack = function () { return self.attackDamage; }; return self; }); // ExtraBee: small bee that follows the main bee and can replace it if main bee dies var ExtraBee = Container.expand(function () { var self = Container.call(this); var beeGraphic = self.attachAsset('extraBee', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0, alpha: 0.9 }); self.velocityX = 0; self.velocityY = 0; self.speed = 8; self.jumpForce = -20; self.gravity = 1; self.onGround = false; self.health = 100; self.maxHealth = 100; self.baseMaxHealth = 100; self.isJumping = false; self.fallingInVoid = false; self.isActive = false; // Only true if this bee is currently the main bee self.followTarget = null; // The bee or extra bee to follow self._index = 0; // Index in the beeQueue self.update = function () { // If not active, follow the previous bee in the queue if (!self.isActive && self.followTarget) { // Follow with a trailing effect var dx = self.followTarget.x - self.x; var dy = self.followTarget.y - self.y; self.x += dx * 0.15; self.y += dy * 0.15; // Stay on ground if followTarget is on ground self.onGround = self.followTarget.onGround; } else if (self.isActive) { // If active, behave like main bee if (!self.onGround) { self.velocityY += self.gravity; } self.x += self.velocityX; self.y += self.velocityY; self.onGround = false; } }; self.moveLeft = function () { if (self.isActive) self.velocityX = -self.speed; }; self.moveRight = function () { if (self.isActive) self.velocityX = self.speed; }; self.moveUp = function () { if (self.isActive && !self.isJumping) { self.velocityY = -self.speed * 0.8; } }; self.jump = function () { if (self.isActive && self.onGround) { self.velocityY = self.jumpForce; self.onGround = false; self.isJumping = true; LK.getSound('jump').play(); } }; self.stopMoving = function () { if (self.isActive) self.velocityX = 0; }; self.takeDamage = function (amount) { if (self.isActive) { self.health -= amount; if (self.health < 0) self.health = 0; LK.getSound('hurt').play(); } }; self.heal = function (amount) { if (self.isActive) { self.health += amount; if (self.health > self.maxHealth) self.health = self.maxHealth; } }; return self; }); var FinishLine = Container.expand(function () { var self = Container.call(this); var finishLineGraphic = self.attachAsset('finishLine', { anchorX: 0.5, anchorY: 0.5 }); self.width = finishLineGraphic.width; self.height = finishLineGraphic.height; return self; }); var Hornet = Container.expand(function () { var self = Container.call(this); var hornetGraphic = self.attachAsset('hornet', { anchorX: 0.5, anchorY: 0.5, tint: 0xFFAA00 }); self.baseMaxHealth = 300 + Math.floor(Math.random() * 301); // 300-600 self.maxHealth = self.baseMaxHealth; self.health = self.maxHealth; self.attackDamage = 25 + Math.floor(Math.random() * 16); // 25-40 self.defeated = false; self.currentPlatform = null; self.moving = false; self.encounteredByPlayer = false; self.hasRevitalized = false; self.originalMaxHealth = self.maxHealth; self.isHornet = true; self.moveAwayFromBee = function (bee) { if (self.moving || self.defeated) return; self.moving = true; var originalBeeY = bee.y; var originalBeeX = bee.x; var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8; var keepBeeOnPlatform = isOnSamePlatform; var nearbyPlatforms = []; for (var i = 0; i < platforms.length; i++) { if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) { nearbyPlatforms.push(platforms[i]); } } if (nearbyPlatforms.length === 0) { self.moving = false; return; } nearbyPlatforms.sort(function (a, b) { var distA = Math.abs(a.x - bee.x); var distB = Math.abs(b.x - bee.x); return distB - distA; }); var targetPlatform = nearbyPlatforms[0]; var targetX = targetPlatform.x; var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2; tween(self, { x: targetX, y: targetY }, { duration: 500, easing: tween.easeOutQuad, onFinish: function onFinish() { self.currentPlatform = targetPlatform; self.moving = false; if (keepBeeOnPlatform) { bee.x = originalBeeX; bee.y = originalBeeY; bee.onGround = true; bee.velocityY = 0; bee.isJumping = false; } } }); }; self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 100 && !self.hasRevitalized && Math.random() < 0.6) { var healAmount = Math.floor(self.originalMaxHealth * 0.35); self.health += healAmount; if (self.health > self.maxHealth) self.health = self.maxHealth; self.hasRevitalized = true; LK.effects.flashObject(self, 0x00FF00, 500); } if (self.health <= 0) { self.health = 0; self.defeated = true; } }; self.attack = function () { return self.attackDamage; }; return self; }); // NeighborHive: special hive that appears on platforms and allows buying extra bees var NeighborHive = Container.expand(function () { var self = Container.call(this); var hiveGraphic = self.attachAsset('neighborHive', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0, alpha: 0.95 }); self.width = hiveGraphic.width; self.height = hiveGraphic.height; self.platform = null; // The platform this hive is on self.interactive = true; self.down = function (x, y, obj) { // Only allow interaction if bee is on the same platform and close enough if (!self.platform) return; var dx = Math.abs(bee.x - self.x); var dy = Math.abs(bee.y - self.y); if (dx < self.width && dy < self.height * 2) { // Show hive purchase dialog showNeighborHiveDialog(self); } }; return self; }); var Platform = Container.expand(function () { var self = Container.call(this); var platformGraphic = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); self.width = platformGraphic.width; self.height = platformGraphic.height; // Handle touch on platform self.down = function (x, y, obj) { if (gameState === "platform" && !dragTarget) { // Move bee to this platform self.moveBeeToThisPlatform(); } }; // Function to move the bee to this platform self.moveBeeToThisPlatform = function () { // Stop current movement bee.velocityX = 0; bee.velocityY = 0; // Play jump sound LK.getSound('jump').play(); // Calculate target position on top of platform var targetX = self.x; var targetY = self.y - self.height / 2 - bee.height / 2; // Create a tween animation for bee to jump to the platform tween(bee, { x: targetX, y: targetY }, { duration: 800, easing: tween.easeOutQuad, onFinish: function onFinish() { bee.onGround = true; bee.isJumping = false; bee.fallingInVoid = false; // Ensure the bee stays on this platform by locking position bee.x = targetX; bee.y = targetY; // Make sure velocity is zero so it doesn't start moving/falling bee.velocityX = 0; bee.velocityY = 0; // Check if there's a spider on this platform and make it move away for (var i = 0; i < spiders.length; i++) { var spider = spiders[i]; if (!spider.defeated && spider.currentPlatform === self) { spider.moveAwayFromBee(bee); } } } }); }; return self; }); var Spider = Container.expand(function () { var self = Container.call(this); var spiderGraphic = self.attachAsset('spider', { anchorX: 0.5, anchorY: 0.5 }); // Defensive: always initialize health properties self.baseMaxHealth = 50; // Base health that will be scaled with level self.maxHealth = typeof self.maxHealth === "number" && !isNaN(self.maxHealth) ? self.maxHealth : 50; self.health = typeof self.health === "number" && !isNaN(self.health) ? self.health : self.maxHealth; self.attackDamage = 15; self.defeated = false; self.currentPlatform = null; self.moving = false; self.encounteredByPlayer = false; // Track if player has encountered this spider self.moveAwayFromBee = function (bee) { if (self.moving || self.defeated) { return; } self.moving = true; // Store bee's original position to ensure it doesn't fall var originalBeeY = bee.y; var originalBeeX = bee.x; var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8; var keepBeeOnPlatform = isOnSamePlatform; // Find nearby platforms to move to var nearbyPlatforms = []; for (var i = 0; i < platforms.length; i++) { // Don't include current platform or platforms too far away if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) { nearbyPlatforms.push(platforms[i]); } } // If no nearby platforms, just return if (nearbyPlatforms.length === 0) { self.moving = false; return; } // Sort platforms by distance from bee nearbyPlatforms.sort(function (a, b) { var distA = Math.abs(a.x - bee.x); var distB = Math.abs(b.x - bee.x); return distB - distA; // Further platforms first }); // Get target platform (furthest from bee) var targetPlatform = nearbyPlatforms[0]; var targetX = targetPlatform.x; var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2; // Animate spider moving to new platform tween(self, { x: targetX, y: targetY }, { duration: 500, easing: tween.easeOutQuad, onFinish: function onFinish() { self.currentPlatform = targetPlatform; self.moving = false; // Ensure bee stays on platform if it was on the same platform as spider if (keepBeeOnPlatform) { bee.x = originalBeeX; bee.y = originalBeeY; bee.onGround = true; bee.velocityY = 0; bee.isJumping = false; } } }); }; self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0) { self.health = 0; self.defeated = true; } }; self.attack = function () { return self.attackDamage; }; return self; }); var Wasp = Container.expand(function () { var self = Container.call(this); var waspGraphic = self.attachAsset('wasp', { anchorX: 0.5, anchorY: 0.5, tint: 0xFF6600, scaleX: 1.2, scaleY: 1.2 }); self.baseMaxHealth = 700 + Math.floor(Math.random() * 5301); // 700-6000 self.maxHealth = self.baseMaxHealth; self.health = self.maxHealth; self.attackDamage = 35 + Math.floor(Math.random() * 21); // 35-55 self.defeated = false; self.currentPlatform = null; self.moving = false; self.encounteredByPlayer = false; self.hasSpawnedHornet = false; self.isWasp = true; self.moveAwayFromBee = function (bee) { if (self.moving || self.defeated) return; self.moving = true; var originalBeeY = bee.y; var originalBeeX = bee.x; var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8; var keepBeeOnPlatform = isOnSamePlatform; var nearbyPlatforms = []; for (var i = 0; i < platforms.length; i++) { if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) { nearbyPlatforms.push(platforms[i]); } } if (nearbyPlatforms.length === 0) { self.moving = false; return; } nearbyPlatforms.sort(function (a, b) { var distA = Math.abs(a.x - bee.x); var distB = Math.abs(b.x - bee.x); return distB - distA; }); var targetPlatform = nearbyPlatforms[0]; var targetX = targetPlatform.x; var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2; tween(self, { x: targetX, y: targetY }, { duration: 500, easing: tween.easeOutQuad, onFinish: function onFinish() { self.currentPlatform = targetPlatform; self.moving = false; if (keepBeeOnPlatform) { bee.x = originalBeeX; bee.y = originalBeeY; bee.onGround = true; bee.velocityY = 0; bee.isJumping = false; } } }); }; self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 500 && !self.hasSpawnedHornet && Math.random() < 0.4) { var newHornet = new Hornet(); newHornet.x = self.x + 80; newHornet.y = self.y; newHornet.currentPlatform = self.currentPlatform; spiders.push(newHornet); game.addChild(newHornet); self.hasSpawnedHornet = true; } if (self.health <= 0) { self.health = 0; self.defeated = true; } }; self.attack = function () { return self.attackDamage; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB // Sky blue background }); /**** * Game Code ****/ // Show dialog to buy extra bee from neighbor hive // --- Bee Wars: Assets for neighbor hives and extra bees --- // Replace id with actual asset id if available // Replace id with actual asset id if available // Custom background images // --- Nouveaux sons pour animations --- function showNeighborHiveDialog(hive) { // Only allow up to 6 extra bees (check current stock, not total purchased) if (extraBees.length >= 6) { // Show message: max bees reached var maxPanel = new Container(); maxPanel.x = 2048 / 2; maxPanel.y = 2732 / 2; var bg = LK.getAsset('battlePanel', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.3, alpha: 0.98 }); maxPanel.addChild(bg); var txt = new Text2("Nombre maximum d'abeilles en stock atteint !", { size: 50, fill: 0x000000 }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = 0; maxPanel.addChild(txt); LK.gui.addChild(maxPanel); LK.setTimeout(function () { if (maxPanel.parent) maxPanel.parent.removeChild(maxPanel); }, 1200); return; } // Show confirmation dialog var panel = new Container(); panel.x = 2048 / 2; panel.y = 2732 / 2; var bg = LK.getAsset('battlePanel', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.4, alpha: 0.98 }); panel.addChild(bg); var txt = new Text2("Acheter une abeille supplĂ©mentaire pour 50 ML ?\nStock actuel: " + extraBees.length + "/6", { size: 48, fill: 0x000000 }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = -60; panel.addChild(txt); // Oui button var yesBtn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: -120, y: 60, tint: 0xFFBB00 }); var yesText = new Text2("Oui", { size: 40, fill: 0xFFFFFF }); yesText.anchor.set(0.5, 0.5); yesText.x = -120; yesText.y = 60; panel.addChild(yesBtn); panel.addChild(yesText); // Non button var noBtn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: 120, y: 60, tint: 0x00AA00 }); var noText = new Text2("Non", { size: 40, fill: 0xFFFFFF }); noText.anchor.set(0.5, 0.5); noText.x = 120; noText.y = 60; panel.addChild(noBtn); panel.addChild(noText); LK.gui.addChild(panel); // Oui handler yesBtn.interactive = true; yesBtn.down = function (xx, yy, obj2) { if (ml >= 50) { ml -= 50; storage.ml = ml; if (mlText) mlText.setText("ML: " + ml); // Add extra bee var newBee = new ExtraBee(); // Place it behind the last bee in the queue var lastBee = beeQueue[beeQueue.length - 1]; newBee.x = lastBee.x - 60; newBee.y = lastBee.y + 40; newBee.isActive = false; newBee.maxHealth = bee.maxHealth; newBee.health = newBee.maxHealth; newBee.followTarget = lastBee; newBee._index = beeQueue.length; extraBees.push(newBee); beeQueue.push(newBee); game.addChild(newBee); // Store in persistent storage for tracking total purchased if (typeof storage.totalBeesPurchased === "undefined") { storage.totalBeesPurchased = 0; } storage.totalBeesPurchased++; // Remove hive from game if (hive && hive.parent) hive.parent.removeChild(hive); var idx = neighborHives.indexOf(hive); if (idx >= 0) neighborHives.splice(idx, 1); // Update dialog message to show current stock txt.setText("Abeille achetĂ©e ! Stock: " + extraBees.length + "/6"); LK.setTimeout(function () { if (panel.parent) panel.parent.removeChild(panel); }, 1200); } else { txt.setText("Pas assez de ML !"); LK.setTimeout(function () { if (panel.parent) panel.parent.removeChild(panel); }, 1000); } }; // Non handler noBtn.interactive = true; noBtn.down = function (xx, yy, obj2) { if (panel.parent) panel.parent.removeChild(panel); }; } var neighborHives = []; var extraBees = []; var beeQueue = []; var neighborHiveTimer = null; // Initialize bee asset // Initialize spider assets // Initialize platform assets // Initialize finish line // Initialize battle UI elements // Initialize sounds // Initialize music var currentLevel = storage.currentLevel || 1; var maxLevels = 17500; var gameState = "platform"; // "platform" or "battle" var platforms = []; var spiders = []; var finishLine; var bee; var battleUI; var controlsUI; var levelText; var spidersDefeatedText; // Text element for displaying spiders defeated count var dragTarget = null; // Track if the bee is being dragged var levelScrolling = false; // Whether the platforms are moving var scrollSpeed = -3; // Horizontal scroll speed var platformGenerationTimer = null; // Timer for platform generation var spiderGenerationTimer = null; // Timer for spider generation var lastPlatformX = 0; // Track last platform position for generation // ML (monnaie du jeu) system var ml = typeof storage.ml === "number" ? storage.ml : 0; var mlText = null; var platformsPassed = 0; var platformsPassedSinceLastML = 0; var lastBeePlatform = null; var boutiqueButton = null; var boutiquePanel = null; var boutiqueItems = []; var boutiqueOpen = false; // Battle state game.battleState = { currentSpider: null, isPlayerTurn: true, turnDelay: 1000 // ms }; // Initialize level function initLevel(level) { // Reset level scrolling levelScrolling = false; if (platformGenerationTimer) { LK.clearInterval(platformGenerationTimer); platformGenerationTimer = null; } if (spiderGenerationTimer) { LK.clearInterval(spiderGenerationTimer); spiderGenerationTimer = null; } // Clear existing elements platforms = []; spiders = []; // Remove neighbor hives and extra bees if (!neighborHives) neighborHives = []; for (var i = 0; i < neighborHives.length; i++) { if (neighborHives[i].parent) neighborHives[i].parent.removeChild(neighborHives[i]); } neighborHives = []; if (!extraBees) extraBees = []; for (var i = 0; i < extraBees.length; i++) { if (extraBees[i].parent) extraBees[i].parent.removeChild(extraBees[i]); } extraBees = []; beeQueue = []; if (neighborHiveTimer) { LK.clearInterval(neighborHiveTimer); neighborHiveTimer = null; } // Remove old elements from game while (game.children.length > 0) { game.removeChild(game.children[0]); } // --- Bee Wars: Custom background system --- if (typeof storage.selectedBg === "undefined") { storage.selectedBg = "default"; } var bgAssetId = null; if (storage.selectedBg === "hive") bgAssetId = "bg_hive";else if (storage.selectedBg === "campagne") bgAssetId = "bg_campagne";else if (storage.selectedBg === "roche") bgAssetId = "bg_roche";else if (storage.selectedBg === "nid") bgAssetId = "bg_nid";else if (storage.selectedBg === "mais") bgAssetId = "bg_mais";else if (storage.selectedBg === "foret") bgAssetId = "bg_foret";else if (storage.selectedBg === "muguet") bgAssetId = "bg_muguet";else if (storage.selectedBg === "roses") bgAssetId = "bg_roses";else if (storage.selectedBg === "prairie") bgAssetId = "bg_prairie";else if (storage.selectedBg === "orties") bgAssetId = "bg_orties"; if (bgAssetId) { var bgImg = LK.getAsset(bgAssetId, { anchorX: 0, anchorY: 0, x: 0, y: 0, scaleX: 2048 / 2048, scaleY: 2732 / 2732 }); game.addChild(bgImg); } // Create bee bee = new Bee(); bee.x = 150; // Update bee's max health based on level (50 more health per level) bee.maxHealth = bee.baseMaxHealth + (level - 1) * 50; bee.health = bee.maxHealth; // RĂ©initialise le compteur d'utilisations de Revitaliser Ă chaque niveau bee.healUses = 0; // --- Bee Wars: Setup beeQueue and extra bees --- bee.isActive = true; beeQueue = [bee]; extraBees = []; // Create first platform to ensure bee starts on a platform var firstPlatform = new Platform(); firstPlatform.x = 200; firstPlatform.y = 2732 / 2 + 100; platforms.push(firstPlatform); game.addChild(firstPlatform); // Position bee on first platform bee.x = firstPlatform.x; bee.y = firstPlatform.y - firstPlatform.height / 2 - bee.height / 2; bee.onGround = true; game.addChild(bee); // Create platforms based on level var platformCount = 5 + level; var platformWidth = 400; var platformHeight = 30; var minPlatformY = 500; var maxPlatformY = 2732 - 500; var platformSpacing = 2048 / platformCount; for (var i = 0; i < platformCount; i++) { var platform = new Platform(); platform.x = i * platformSpacing + platformSpacing / 2; platform.y = minPlatformY + Math.random() * (maxPlatformY - minPlatformY); platforms.push(platform); game.addChild(platform); } // Create spiders based on level var spiderCount = level; for (var i = 0; i < spiderCount; i++) { // Determine enemy type based on level and random chance var enemy; if (level >= 5000 && Math.random() < 0.15) { enemy = new Bird(); } else if (level >= 750 && Math.random() < 0.12) { enemy = new Dragonfly(); } else if (level >= 444 && Math.random() < 0.10) { enemy = new Wasp(); } else if (level >= 100 && Math.random() < 0.08) { enemy = new Hornet(); } else { // Regular spider logic var isEndOfLevel = i === spiderCount - 1; var isLowHealth = level > 2 && Math.random() < 0.25; var makeDividing = (isEndOfLevel || isLowHealth) && Math.random() < 0.7; if (makeDividing) { enemy = new DividingSpider(); } else { enemy = new Spider(); } } var spider = enemy; // Update spider's max health based on level (20 more health per level) - but only for regular spiders if (!spider.isHornet && !spider.isWasp && !spider.isDragonfly && !spider.isBird) { spider.maxHealth = spider.baseMaxHealth + (level - 1) * 20; spider.health = spider.maxHealth; } // Position spiders on platforms, starting from the second platform var platformIndex = Math.floor((i + 1) * (platformCount - 1) / spiderCount); spider.x = platforms[platformIndex].x; spider.y = platforms[platformIndex].y - platforms[platformIndex].height / 2 - spider.height / 2; spider.currentPlatform = platforms[platformIndex]; spiders.push(spider); game.addChild(spider); } // Create finish line finishLine = new FinishLine(); finishLine.x = 2048 - 100; finishLine.y = platforms[platformCount - 1].y - platforms[platformCount - 1].height / 2 - finishLine.height / 2; game.addChild(finishLine); // --- Bee Wars: Randomly spawn neighbor hives on platforms --- for (var i = 1; i < platforms.length - 1; i++) { // 25% chance to spawn a neighbor hive on this platform if (Math.random() < 0.25) { var hive = new NeighborHive(); hive.x = platforms[i].x; hive.y = platforms[i].y - platforms[i].height / 2 - hive.height / 2; hive.platform = platforms[i]; neighborHives.push(hive); game.addChild(hive); } } // Create controls UI controlsUI = new ControlsUI(); controlsUI.x = 2048 / 2; controlsUI.y = 2732 - 150; LK.gui.addChild(controlsUI); // Set up controls controlsUI.onLeftPressed = function () { bee.moveLeft(); }; controlsUI.onRightPressed = function () { bee.moveRight(); }; controlsUI.onJumpPressed = function () { bee.jump(); }; controlsUI.onUpPressed = function () { bee.moveUp(); }; controlsUI.onControlsReleased = function () { bee.stopMoving(); }; // Create spiders defeated counter spidersDefeated = 0; spidersDefeatedText = new Text2("Spiders: 0", { size: 40, fill: 0xFFFFFF }); spidersDefeatedText.anchor.set(0, 0); spidersDefeatedText.x = 50; spidersDefeatedText.y = 100; LK.gui.topLeft.addChild(spidersDefeatedText); // Always reset spidersDefeated to 0 at the start of each level spidersDefeated = 0; spidersDefeatedText.setText("Spiders: " + spidersDefeated); // Reset platform counters for ML platformsPassed = 0; platformsPassedSinceLastML = 0; lastBeePlatform = null; // Remove previous levelText if it exists if (levelText && levelText.parent) { levelText.parent.removeChild(levelText); } levelText = null; // Remove previous spidersDefeatedText if it exists if (spidersDefeatedText && spidersDefeatedText.parent) { spidersDefeatedText.parent.removeChild(spidersDefeatedText); } spidersDefeatedText = null; // Remove previous ML text if it exists if (mlText && mlText.parent) { mlText.parent.removeChild(mlText); } mlText = null; // Remove previous boutique button/panel if they exist if (boutiqueButton && boutiqueButton.parent) { boutiqueButton.parent.removeChild(boutiqueButton); } boutiqueButton = null; if (boutiquePanel && boutiquePanel.parent) { boutiquePanel.parent.removeChild(boutiquePanel); } boutiquePanel = null; boutiqueOpen = false; // Create level display text levelText = new Text2("Niveau : " + currentLevel + " / " + maxLevels, { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); // Create spiders defeated counter spidersDefeatedText = new Text2("Spiders: " + spidersDefeated, { size: 40, fill: 0xFFFFFF }); spidersDefeatedText.anchor.set(0, 0); spidersDefeatedText.x = 50; spidersDefeatedText.y = 100; LK.gui.topLeft.addChild(spidersDefeatedText); // ML counter (just below the level banner, left-aligned to levelText) mlText = new Text2("ML: " + ml, { size: 40, fill: 0x000000 }); mlText.anchor.set(0.5, 0); mlText.x = levelText.x; mlText.y = levelText.y + levelText.height + 10; LK.gui.top.addChild(mlText); // Boutique button (just below ML counter, left-aligned to levelText) boutiqueButton = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.0, scaleX: 0.4, scaleY: 0.4, x: levelText.x, y: mlText.y + mlText.height + 10, tint: 0xffffff }); var boutiqueBtnText = new Text2("Boutique", { size: 30, fill: 0x000000 }); boutiqueBtnText.anchor.set(0.5, 0.5); boutiqueBtnText.x = levelText.x; boutiqueBtnText.y = boutiqueButton.y + boutiqueButton.height * boutiqueButton.scaleY / 2; LK.gui.top.addChild(boutiqueButton); LK.gui.top.addChild(boutiqueBtnText); // --- Bee Wars: Add blue settings button for background customization --- var settingsButton = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.0, scaleX: 0.4, scaleY: 0.4, x: levelText.x, y: boutiqueButton.y + boutiqueButton.height * boutiqueButton.scaleY + 10, tint: 0x3399FF }); var settingsBtnText = new Text2("ParamĂštres", { size: 30, fill: 0xffffff }); settingsBtnText.anchor.set(0.5, 0.5); settingsBtnText.x = levelText.x; settingsBtnText.y = settingsButton.y + settingsButton.height * settingsButton.scaleY / 2; LK.gui.top.addChild(settingsButton); LK.gui.top.addChild(settingsBtnText); // Handler for settings button to show background selection settingsButton.interactive = true; settingsButton.down = function (x, y, obj) { // Show background selection dialog if (typeof window._bgPanel !== "undefined" && window._bgPanel && window._bgPanel.parent) { // Already open return; } var bgPanel = new Container(); window._bgPanel = bgPanel; bgPanel.x = 2048 / 2; bgPanel.y = 2732 / 2; var bg = LK.getAsset('battlePanel', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.9, alpha: 0.97 }); bgPanel.addChild(bg); // Create scrollable content container var scrollContainer = new Container(); bgPanel.addChild(scrollContainer); var title = new Text2("Choisis ton fond :", { size: 60, fill: 0x000000 }); title.anchor.set(0.5, 0); title.y = -bg.height * 0.4; scrollContainer.addChild(title); // List of backgrounds var bgs = [{ key: "hive", label: "Ruche", price: 30, asset: "bg_hive" }, { key: "campagne", label: "Campagnes", price: 60, asset: "bg_campagne" }, { key: "roche", label: "Roche", price: 86, asset: "bg_roche" }, { key: "nid", label: "Nid des araignĂ©es", price: 100, asset: "bg_nid" }, { key: "mais", label: "MaĂŻs", price: 125, asset: "bg_mais" }, { key: "foret", label: "ForĂȘt enchantĂ©e", price: 185, asset: "bg_foret" }, { key: "muguet", label: "Muguet", price: 200, asset: "bg_muguet" }, { key: "roses", label: "Roses Ă©pineuses", price: 170, asset: "bg_roses" }, { key: "prairie", label: "Prairie manga", price: 220, asset: "bg_prairie" }, { key: "orties", label: "Orties", price: 240, asset: "bg_orties" }]; var yStart = -bg.height * 0.25; var scrollY = 0; var maxScrollY = Math.max(0, bgs.length * 120 - bg.height * 0.6); for (var i = 0; i < bgs.length; i++) { (function (idx) { var bgItem = bgs[idx]; var y = yStart + idx * 120; var btn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.5, x: 0, y: y, tint: 0xeeeeee }); var txt = new Text2(bgItem.label + " (" + bgItem.price + " ML)", { size: 40, fill: 0x000000 }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = y; var selectBtn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.4, scaleY: 0.4, x: 350, y: y, tint: 0x3399FF }); var selectTxt = new Text2("Celui-ci", { size: 30, fill: 0xffffff }); selectTxt.anchor.set(0.5, 0.5); selectTxt.x = 350; selectTxt.y = y; scrollContainer.addChild(btn); scrollContainer.addChild(txt); scrollContainer.addChild(selectBtn); scrollContainer.addChild(selectTxt); selectBtn.interactive = true; selectBtn.down = function (xx, yy, obj2) { // If already selected, just close if (storage.selectedBg === bgItem.key) { if (bgPanel.parent) bgPanel.parent.removeChild(bgPanel); window._bgPanel = null; return; } // Check if player has enough ML if (ml < bgItem.price) { title.setText("Pas assez de ML !"); return; } // Deduct ML and set background ml -= bgItem.price; storage.ml = ml; if (mlText) mlText.setText("ML: " + ml); storage.selectedBg = bgItem.key; // Show confirmation title.setText("Fond changĂ© !"); // Remove panel and re-init level after short delay LK.setTimeout(function () { if (bgPanel.parent) bgPanel.parent.removeChild(bgPanel); window._bgPanel = null; initLevel(currentLevel); }, 700); }; })(i); } // Scroll up button var scrollUpBtn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, x: 300, y: -bg.height * 0.35, tint: 0x00AA00 }); var scrollUpTxt = new Text2("â", { size: 40, fill: 0xffffff }); scrollUpTxt.anchor.set(0.5, 0.5); scrollUpTxt.x = 300; scrollUpTxt.y = -bg.height * 0.35; bgPanel.addChild(scrollUpBtn); bgPanel.addChild(scrollUpTxt); // Scroll down button var scrollDownBtn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, x: 300, y: bg.height * 0.35, tint: 0x00AA00 }); var scrollDownTxt = new Text2("â", { size: 40, fill: 0xffffff }); scrollDownTxt.anchor.set(0.5, 0.5); scrollDownTxt.x = 300; scrollDownTxt.y = bg.height * 0.35; bgPanel.addChild(scrollDownBtn); bgPanel.addChild(scrollDownTxt); // Scroll button handlers scrollUpBtn.interactive = true; scrollUpBtn.down = function (xx, yy, obj2) { if (scrollY > 0) { scrollY = Math.max(0, scrollY - 120); scrollContainer.y = scrollY; } }; scrollDownBtn.interactive = true; scrollDownBtn.down = function (xx, yy, obj2) { if (scrollY < maxScrollY) { scrollY = Math.min(maxScrollY, scrollY + 120); scrollContainer.y = -scrollY; } }; // Close button var closeBtn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: 0, y: bg.height * 0.4, tint: 0x000000 }); var closeTxt = new Text2("Fermer", { size: 35, fill: 0xffffff }); closeTxt.anchor.set(0.5, 0.5); closeTxt.x = 0; closeTxt.y = bg.height * 0.4; bgPanel.addChild(closeBtn); bgPanel.addChild(closeTxt); closeBtn.interactive = true; closeBtn.down = function (xx, yy, obj2) { if (bgPanel.parent) bgPanel.parent.removeChild(bgPanel); window._bgPanel = null; }; LK.gui.addChild(bgPanel); }; // (reset button supprimĂ©) // Boutique button handler boutiqueButton.interactive = true; boutiqueButton.down = function (x, y, obj) { if (boutiqueOpen) { // Hide boutique if (boutiquePanel && boutiquePanel.parent) { boutiquePanel.parent.removeChild(boutiquePanel); } boutiquePanel = null; boutiqueOpen = false; return; } // Show boutique if (boutiquePanel && boutiquePanel.parent) { boutiquePanel.parent.removeChild(boutiquePanel); } boutiquePanel = new Container(); boutiquePanel.x = 2048 / 2; boutiquePanel.y = 2732 / 2; // Background var bg = LK.getAsset('battlePanel', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, alpha: 0.95 }); boutiquePanel.addChild(bg); // Title var title = new Text2("Boutique", { size: 70, fill: 0x000000 }); title.anchor.set(0.5, 0); title.y = -bg.height * 0.3 + 40; boutiquePanel.addChild(title); // Items var items = [{ label: "30 points de vie", price: 2, heal: 30, percent: 0 }, { label: "50 points de vie", price: 3, heal: 50, percent: 0 }, { label: "RĂ©cupĂ©rer 10% de vie", price: 6, heal: 0, percent: 0.10 }, { label: "RĂ©cupĂ©rer 20% de vie", price: 10, heal: 0, percent: 0.20 }, { label: "RĂ©cupĂ©rer 30% de vie", price: 12, heal: 0, percent: 0.30 }]; boutiqueItems = []; for (var i = 0; i < items.length; i++) { (function (idx) { var item = items[idx]; var y = -bg.height * 0.15 + idx * 120; var btn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.5, x: 0, y: y, tint: 0xffffff }); var txt = new Text2(item.label + " (" + item.price + " ML)", { size: 40, fill: 0x000000 }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = y; boutiquePanel.addChild(btn); boutiquePanel.addChild(txt); btn.interactive = true; btn.down = function (xx, yy, obj2) { // Check ML if (ml < item.price) { title.setText("Pas assez de ML !"); return; } // Heal logic var healAmount = item.heal; if (item.percent > 0) { healAmount = Math.floor(bee.maxHealth * item.percent); } if (healAmount > 0) { bee.heal(healAmount); } // Deduct ML ml -= item.price; if (ml < 0) ml = 0; storage.ml = ml; if (mlText) mlText.setText("ML: " + ml); title.setText("Achat rĂ©ussi !"); // Hide boutique after purchase LK.setTimeout(function () { if (boutiquePanel && boutiquePanel.parent) { boutiquePanel.parent.removeChild(boutiquePanel); } boutiquePanel = null; boutiqueOpen = false; }, 700); }; boutiqueItems.push(btn); })(i); } // Close button var closeBtn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: 0, y: bg.height * 0.3 - 60, tint: 0x000000 }); var closeTxt = new Text2("Fermer", { size: 35, fill: 0xffffff }); closeTxt.anchor.set(0.5, 0.5); closeTxt.x = 0; closeTxt.y = bg.height * 0.3 - 60; boutiquePanel.addChild(closeBtn); boutiquePanel.addChild(closeTxt); closeBtn.interactive = true; closeBtn.down = function (xx, yy, obj2) { if (boutiquePanel && boutiquePanel.parent) { boutiquePanel.parent.removeChild(boutiquePanel); } boutiquePanel = null; boutiqueOpen = false; }; LK.gui.addChild(boutiquePanel); boutiqueOpen = true; }; // Reset spiders defeated counter for this level spidersDefeated = 0; // Create score display scoreText = new Text2("Score: " + LK.getScore(), { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); scoreText.x = -50; LK.gui.topRight.addChild(scoreText); // Set game state gameState = "platform"; // Play background music LK.playMusic('gameMusic'); } // Start battle with a spider function startBattle(spider) { // Check if already in battle mode - prevent multiple battles at once if (gameState === "battle") { return; } // Store bee's position and ground state before battle var originalBeeX = bee.x; var originalBeeY = bee.y; var originalOnGround = bee.onGround; gameState = "battle"; game.battleState.currentSpider = spider; // Mark spider as encountered by player spider.encounteredByPlayer = true; game.battleState.isPlayerTurn = true; // Keep bee in place by setting velocities to zero bee.velocityX = 0; bee.velocityY = 0; // Create battle UI battleUI = new BattleUI(); battleUI.x = 2048 / 2; battleUI.y = 2732 / 2; battleUI.updateHealth(bee.health, bee.maxHealth, spider.health, spider.maxHealth); battleUI.setTurnText(true); game.addChild(battleUI); // --- Ajout du bouton Revitaliser --- if (typeof bee.healUses === "undefined") bee.healUses = 0; bee.healUses = 0; // Reset heal uses at start of each battle // CrĂ©e le bouton bleu "Revitaliser" sous le bouton d'attaque var healBtn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 320, tint: 0x3399FF }); battleUI.addChild(healBtn); var healText = new Text2("Revitaliser", { size: 40, fill: 0xFFFFFF }); healText.anchor.set(0.5, 0.5); healText.x = 0; healText.y = 320; battleUI.addChild(healText); // Affichage du nombre d'utilisations restantes var healUsesText = new Text2("3 utilisations restantes", { size: 30, fill: 0xFFFFFF }); healUsesText.anchor.set(0.5, 0.5); healUsesText.x = 0; healUsesText.y = 370; battleUI.addChild(healUsesText); // Handler pour le bouton Revitaliser healBtn.interactive = true; healBtn.down = function (x, y, obj) { // Conditions pour pouvoir se soigner var canHeal = false; var spidersRequired = currentLevel < 3 ? 3 : 6; if (spidersDefeated >= spidersRequired && bee.healUses < 3 && game.battleState.isPlayerTurn) { canHeal = true; } if (canHeal) { var healAmount = Math.floor(bee.maxHealth * 0.2); bee.heal(healAmount); bee.healUses++; battleUI.updateHealth(bee.health, bee.maxHealth, game.battleState.currentSpider.health, game.battleState.currentSpider.maxHealth); // Feedback visuel LK.effects.flashObject(bee, 0x00ccff, 300); } // Met Ă jour le texte d'utilisation var usesLeft = 3 - bee.healUses; healUsesText.setText(usesLeft + " utilisation" + (usesLeft === 1 ? "" : "s") + " restante" + (usesLeft > 1 ? "s" : "")); // Message si non autorisĂ© if (!canHeal && game.battleState.isPlayerTurn) { if (bee.healUses >= 3) { healUsesText.setText("Limite atteinte ce niveau"); } else if (spidersDefeated < spidersRequired) { healUsesText.setText("Vaincs " + spidersRequired + " araignĂ©es pour te soigner"); } } }; // Set up attack button handler battleUI.onAttackPressed = function () { if (game.battleState.isPlayerTurn) { playerAttack(); } }; // Store original position and state in battle state for recovery after battle game.battleState.originalBeeX = originalBeeX; game.battleState.originalBeeY = originalBeeY; game.battleState.originalOnGround = originalOnGround; } // --- Mini-quizz et bonus de dĂ©gĂąts --- // Variables globales pour le quizz et le bonus if (typeof window.quizState === "undefined") { window.quizState = { spidersSinceLastQuiz: 0, bonusActive: false, bonusSpidersLeft: 0 }; } // Liste de questions/choix/rĂ©ponses (exemples, Ă Ă©tendre) var quizQuestions = [{ question: "Combien de pattes a une araignĂ©e ?", choices: ["6", "8", "10"], answer: 1 }, { question: "Combien de temps vit une abeille ouvriĂšre ?", choices: ["Quelques semaines", "Plusieurs annĂ©es", "Un jour"], answer: 0 }, { question: "Quel est le rĂŽle principal de la reine des abeilles ?", choices: ["Butiner", "Pondre des Ćufs", "Tisser la toile"], answer: 1 }, { question: "Les abeilles fabriquent du miel Ă partir de :", choices: ["Pollen", "Nectar", "Eau"], answer: 1 }, { question: "Les araignĂ©es sont-elles des insectes ?", choices: ["Oui", "Non", "Seulement les petites"], answer: 1 }, { question: "Combien d'yeux ont la plupart des araignĂ©es ?", choices: ["2", "8", "4"], answer: 1 }, { question: "Quel est l'aliment principal des abeilles ?", choices: ["Miel", "Nectar", "Feuilles"], answer: 1 }, { question: "Comment s'appelle la maison des abeilles ?", choices: ["Ruche", "Toile", "Nid"], answer: 0 }, { question: "Quel est le principal prĂ©dateur des abeilles ?", choices: ["Ours", "AraignĂ©e", "GuĂȘpe"], answer: 2 }, { question: "Combien de reines y a-t-il dans une ruche ?", choices: ["1", "10", "Aucune"], answer: 0 }, { question: "Les araignĂ©es tissent leur toile pour :", choices: ["Dormir", "Attraper des proies", "Voler"], answer: 1 }, { question: "Quel est le rĂŽle des faux-bourdons dans la ruche ?", choices: ["Butiner", "Fertiliser la reine", "Fabriquer du miel"], answer: 1 }, { question: "Les abeilles communiquent entre elles par :", choices: ["Chant", "Danse", "Couleur"], answer: 1 }, { question: "Combien de temps vit une reine des abeilles ?", choices: ["Quelques semaines", "Plusieurs annĂ©es", "Un jour"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles voler ?", choices: ["Oui", "Non", "Seulement les petites"], answer: 1 }, { question: "Quel est le principal ingrĂ©dient du miel ?", choices: ["Eau", "Nectar", "Pollen"], answer: 1 }, { question: "Les abeilles voient-elles les couleurs ?", choices: ["Oui", "Non", "Seulement le rouge"], answer: 0 }, { question: "Combien d'ailes a une abeille ?", choices: ["2", "4", "6"], answer: 1 }, { question: "Les araignĂ©es sont utiles car elles :", choices: ["Pollinisent", "Mangent des insectes", "Font du miel"], answer: 1 }, { question: "Quel est le nom scientifique de l'abeille domestique ?", choices: ["Apis mellifera", "Bombus terrestris", "Vespa crabro"], answer: 0 }, { question: "Les abeilles piquent-elles plusieurs fois ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 1 }, { question: "Les araignĂ©es boivent-elles du sang ?", choices: ["Oui", "Non", "Seulement certaines"], answer: 1 }, { question: "Combien de pattes a une abeille ?", choices: ["4", "6", "8"], answer: 1 }, { question: "Les abeilles peuvent-elles voir les ultraviolets ?", choices: ["Oui", "Non", "Seulement la nuit"], answer: 0 }, { question: "Les araignĂ©es pondent-elles des Ćufs ?", choices: ["Oui", "Non", "Seulement les mĂąles"], answer: 0 }, { question: "Quel est le principal danger pour les abeilles ?", choices: ["Froid", "Pesticides", "LumiĂšre"], answer: 1 }, { question: "Les abeilles fabriquent-elles la cire ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 0 }, { question: "Les araignĂ©es ont-elles des antennes ?", choices: ["Oui", "Non", "Seulement les bĂ©bĂ©s"], answer: 1 }, { question: "Combien de temps met une abeille pour fabriquer du miel ?", choices: ["Quelques heures", "Plusieurs jours", "Un mois"], answer: 1 }, { question: "Les abeilles vivent-elles seules ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles nager ?", choices: ["Oui", "Non", "Seulement certaines"], answer: 2 }, { question: "Quel est le rĂŽle du pollen pour les abeilles ?", choices: ["Nourriture", "Construire la ruche", "Attirer les prĂ©dateurs"], answer: 0 }, { question: "Les abeilles dorment-elles ?", choices: ["Oui", "Non", "Seulement la nuit"], answer: 0 }, { question: "Les araignĂ©es sont-elles toutes venimeuses ?", choices: ["Oui", "Non", "Seulement les grandes"], answer: 1 }, { question: "Combien de temps vit une araignĂ©e ?", choices: ["Quelques jours", "Plusieurs mois", "Plusieurs annĂ©es"], answer: 2 }, { question: "Les abeilles peuvent-elles voler sous la pluie ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 1 }, { question: "Les araignĂ©es mangent-elles des abeilles ?", choices: ["Oui", "Non", "Seulement les grandes"], answer: 2 }, { question: "Quel est le principal ennemi des araignĂ©es ?", choices: ["Abeilles", "Oiseaux", "GuĂȘpes"], answer: 1 }, { question: "Les abeilles fabriquent-elles du miel en hiver ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles changer de couleur ?", choices: ["Oui", "Non", "Seulement certaines"], answer: 2 }, { question: "Combien de reines dans une ruche normale ?", choices: ["1", "2", "Aucune"], answer: 0 }, { question: "Les abeilles peuvent-elles piquer plusieurs fois ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 1 }, { question: "Les araignĂ©es ont-elles des ailes ?", choices: ["Oui", "Non", "Seulement les mĂąles"], answer: 1 }, { question: "Quel est le rĂŽle du dard chez l'abeille ?", choices: ["Butiner", "Se dĂ©fendre", "Construire la ruche"], answer: 1 }, { question: "Les abeilles mangent-elles du miel ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 0 }, { question: "Les araignĂ©es peuvent-elles vivre dans l'eau ?", choices: ["Oui", "Non", "Seulement certaines"], answer: 2 }, { question: "Combien de temps vit une abeille reine ?", choices: ["Quelques semaines", "Plusieurs annĂ©es", "Un jour"], answer: 1 }, { question: "Les abeilles voient-elles la couleur rouge ?", choices: ["Oui", "Non", "Seulement la nuit"], answer: 1 }, { question: "Les araignĂ©es sont-elles sourdes ?", choices: ["Oui", "Non", "Seulement les petites"], answer: 0 }, { question: "Quel est le rĂŽle du nectar pour les abeilles ?", choices: ["Nourriture", "Construire la ruche", "Attirer les prĂ©dateurs"], answer: 0 }, { question: "Les abeilles peuvent-elles vivre sans reine ?", choices: ["Oui", "Non", "Seulement quelques jours"], answer: 2 }, { question: "Les araignĂ©es peuvent-elles sauter ?", choices: ["Oui", "Non", "Seulement les grandes"], answer: 0 }, { question: "Combien de temps met une araignĂ©e pour tisser sa toile ?", choices: ["Quelques minutes", "Plusieurs heures", "Un jour"], answer: 0 }, { question: "Les abeilles sont-elles toutes ouvriĂšres ?", choices: ["Oui", "Non", "Seulement la nuit"], answer: 1 }, { question: "Les araignĂ©es mangent-elles des plantes ?", choices: ["Oui", "Non", "Seulement les bĂ©bĂ©s"], answer: 1 }, { question: "Quel est le rĂŽle du pollen pour la ruche ?", choices: ["Nourriture", "Construire la ruche", "Attirer les prĂ©dateurs"], answer: 0 }, { question: "Les abeilles peuvent-elles reconnaĂźtre les humains ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 0 }, { question: "Les araignĂ©es peuvent-elles vivre dans le dĂ©sert ?", choices: ["Oui", "Non", "Seulement les grandes"], answer: 0 }, { question: "Combien de temps vit une abeille en hiver ?", choices: ["Quelques semaines", "Plusieurs mois", "Un jour"], answer: 1 }, { question: "Les abeilles fabriquent-elles la gelĂ©e royale ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 0 }, { question: "Les araignĂ©es peuvent-elles voir dans le noir ?", choices: ["Oui", "Non", "Seulement certaines"], answer: 2 }, { question: "Quel est le principal ingrĂ©dient de la cire d'abeille ?", choices: ["Nectar", "Pollen", "SĂ©crĂ©tion"], answer: 2 }, { question: "Les abeilles peuvent-elles voler la nuit ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 1 }, { question: "Les araignĂ©es sont-elles toutes solitaires ?", choices: ["Oui", "Non", "Seulement les grandes"], answer: 1 }, { question: "Combien de temps vit une abeille butineuse ?", choices: ["Quelques semaines", "Plusieurs annĂ©es", "Un jour"], answer: 0 }, { question: "Les abeilles mangent-elles du pollen ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 0 }, { question: "Les araignĂ©es peuvent-elles vivre dans les arbres ?", choices: ["Oui", "Non", "Seulement les grandes"], answer: 0 }, { question: "Quel est le rĂŽle de la gelĂ©e royale ?", choices: ["Nourrir la reine", "Construire la ruche", "Attirer les prĂ©dateurs"], answer: 0 }, { question: "Les abeilles peuvent-elles reconnaĂźtre leur ruche ?", choices: ["Oui", "Non", "Seulement la reine"], answer: 0 }, { question: "Les araignĂ©es peuvent-elles vivre sous terre ?", choices: ["Oui", "Non", "Seulement les grandes"], answer: 0 }, { question: "Combien de cellules hexagonales une abeille peut-elle construire par jour ?", choices: ["10", "100", "1000"], answer: 1 }, { question: "Les abeilles peuvent-elles reconnaĂźtre les visages humains ?", choices: ["Oui", "Non", "Seulement les apiculteurs"], answer: 0 }, { question: "Quel est le principal composant de la propolis ?", choices: ["RĂ©sine", "Miel", "Pollen"], answer: 0 }, { question: "Les araignĂ©es ont-elles du sang rouge ?", choices: ["Oui", "Non", "Seulement les grandes"], answer: 1 }, { question: "Combien de fois par seconde les ailes d'une abeille battent-elles ?", choices: ["50", "230", "500"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles rĂ©gĂ©nĂ©rer leurs pattes ?", choices: ["Oui", "Non", "Seulement jeunes"], answer: 0 }, { question: "Quelle est la tempĂ©rature idĂ©ale dans une ruche ?", choices: ["25°C", "35°C", "45°C"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles entendre ?", choices: ["Oui", "Non", "Seulement les vibrations"], answer: 2 }, { question: "Combien de kilomĂštres une abeille peut-elle voler en une journĂ©e ?", choices: ["50 km", "150 km", "300 km"], answer: 1 }, { question: "Les araignĂ©es muent-elles ?", choices: ["Oui", "Non", "Seulement les mĂąles"], answer: 0 }, { question: "Quel pourcentage de plantes dĂ©pend de la pollinisation par les abeilles ?", choices: ["30%", "50%", "80%"], answer: 2 }, { question: "Les araignĂ©es peuvent-elles survivre dans l'espace ?", choices: ["Oui", "Non", "Quelques heures"], answer: 1 }, { question: "Combien d'Ćufs une reine peut-elle pondre par jour ?", choices: ["100", "1000", "2000"], answer: 2 }, { question: "Les araignĂ©es sociales existent-elles ?", choices: ["Oui", "Non", "Seulement en AmĂ©rique"], answer: 0 }, { question: "Ă quelle vitesse vole une abeille ?", choices: ["15 km/h", "25 km/h", "40 km/h"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles nager sous l'eau ?", choices: ["Oui", "Non", "Seulement certaines espĂšces"], answer: 2 }, { question: "Combien de fleurs une abeille visite-t-elle par jour ?", choices: ["100", "500", "2000"], answer: 2 }, { question: "Les araignĂ©es ont-elles des poumons ?", choices: ["Oui", "Non", "Seulement les grandes"], answer: 1 }, { question: "Quelle est la durĂ©e de vie d'une ruche ?", choices: ["1 an", "5 ans", "20 ans"], answer: 2 }, { question: "Les araignĂ©es peuvent-elles vomir ?", choices: ["Oui", "Non", "Seulement malades"], answer: 0 }, { question: "Combien pĂšse une abeille ouvriĂšre ?", choices: ["0.1 gramme", "0.5 gramme", "1 gramme"], answer: 0 }, { question: "Les araignĂ©es dorment-elles ?", choices: ["Oui", "Non", "Ătat de repos"], answer: 2 }, { question: "Quel est le record de distance de vol d'une abeille ?", choices: ["5 km", "10 km", "15 km"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles sentir les odeurs ?", choices: ["Oui", "Non", "Seulement les phĂ©romones"], answer: 0 }, { question: "Combien de temps met le miel Ă cristalliser ?", choices: ["1 semaine", "6 mois", "2 ans"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles survivre au froid ?", choices: ["Oui", "Non", "Avec antigel"], answer: 2 }, { question: "Ă quel Ăąge une abeille ouvriĂšre commence-t-elle Ă butiner ?", choices: ["1 jour", "3 semaines", "2 mois"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles changer de sexe ?", choices: ["Oui", "Non", "Seulement certaines"], answer: 1 }, { question: "Combien de cellules contient un rayon de miel ?", choices: ["1000", "25000", "100000"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles vivre sans tĂȘte ?", choices: ["Oui", "Non", "Quelques heures"], answer: 2 }, { question: "Quelle est la portĂ©e de communication des abeilles ?", choices: ["10 mĂštres", "100 mĂštres", "1 kilomĂštre"], answer: 2 }, { question: "Les araignĂ©es peuvent-elles planer ?", choices: ["Oui", "Non", "Avec balloning"], answer: 2 }, { question: "Combien de gĂ©nĂ©rations d'abeilles naissent par an ?", choices: ["2", "6", "12"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles manger leurs partenaires ?", choices: ["Oui", "Non", "Seulement les femelles"], answer: 2 }, { question: "Quel est le pH du miel ?", choices: ["Acide", "Neutre", "Basique"], answer: 0 }, { question: "Les araignĂ©es peuvent-elles tisser sous l'eau ?", choices: ["Oui", "Non", "Seulement bulles d'air"], answer: 2 }, { question: "Combien de muscles contrĂŽlent les ailes d'une abeille ?", choices: ["4", "75", "200"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles voir les couleurs ?", choices: ["Oui", "Non", "Seulement certaines"], answer: 2 }, { question: "Ă quelle tempĂ©rature le miel devient-il toxique ?", choices: ["60°C", "100°C", "Jamais"], answer: 2 }, { question: "Les araignĂ©es peuvent-elles survivre Ă la radioactivitĂ© ?", choices: ["Oui", "Non", "Mieux que humains"], answer: 2 }, { question: "Combien de types de cellules une ruche contient-elle ?", choices: ["2", "3", "5"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles se camoufler ?", choices: ["Oui", "Non", "Seulement mimĂ©tisme"], answer: 0 }, { question: "Quelle distance parcourt une abeille pour 1 kg de miel ?", choices: ["40000 km", "80000 km", "120000 km"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles pleurer ?", choices: ["Oui", "Non", "Pas de larmes"], answer: 2 }, { question: "Combien de phĂ©romones diffĂ©rentes une reine produit-elle ?", choices: ["5", "20", "50"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles vivre en groupe ?", choices: ["Oui", "Non", "Rarement"], answer: 2 }, { question: "Ă quelle altitude maximale les abeilles peuvent-elles voler ?", choices: ["1000m", "3000m", "5000m"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles hiberner ?", choices: ["Oui", "Non", "Diapause"], answer: 2 }, { question: "Combien de fois son poids une abeille peut-elle porter ?", choices: ["0.5 fois", "1 fois", "2 fois"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles ĂȘtre cannibales ?", choices: ["Oui", "Non", "Seulement affamĂ©es"], answer: 0 }, { question: "Quelle est la vitesse de production du miel ?", choices: ["1g/jour", "10g/jour", "100g/jour"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles voler rĂ©ellement ?", choices: ["Oui", "Non", "Balloning seulement"], answer: 2 }, { question: "Combien de danses diffĂ©rentes les abeilles connaissent-elles ?", choices: ["2", "8", "20"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles survivre sous l'eau longtemps ?", choices: ["Oui", "Non", "Avec bulles d'air"], answer: 2 }, { question: "Ă quelle frĂ©quence vibrent les ailes d'une abeille ?", choices: ["100 Hz", "230 Hz", "500 Hz"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles ĂȘtre venimeuses ET vĂ©nĂ©neuses ?", choices: ["Oui", "Non", "TrĂšs rarement"], answer: 2 }, { question: "Combien de sucre contient le nectar ?", choices: ["10%", "30%", "70%"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles rĂ©gĂ©nĂ©rer leur cerveau ?", choices: ["Oui", "Non", "Partiellement"], answer: 1 }, { question: "Quelle est la forme gĂ©omĂ©trique parfaite des cellules ?", choices: ["CarrĂ©", "Hexagone", "Octogone"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles survivre Ă l'espace ?", choices: ["Oui", "Non", "Quelques minutes"], answer: 1 }, { question: "Combien d'antennes ont les abeilles ?", choices: ["2", "4", "6"], answer: 0 }, { question: "Les araignĂ©es peuvent-elles ĂȘtre albinos ?", choices: ["Oui", "Non", "TrĂšs rare"], answer: 2 }, { question: "Ă quelle tempĂ©rature les abeilles ne volent plus ?", choices: ["5°C", "10°C", "15°C"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles chasser en groupe ?", choices: ["Oui", "Non", "Certaines espĂšces"], answer: 2 }, { question: "Combien de pattes a une larve d'abeille ?", choices: ["0", "3", "6"], answer: 0 }, { question: "Les araignĂ©es peuvent-elles survivre sans eau ?", choices: ["Oui", "Non", "Longtemps"], answer: 2 }, { question: "Quelle est la consommation de miel d'une ruche en hiver ?", choices: ["5 kg", "15 kg", "30 kg"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles ĂȘtre gĂ©antes ?", choices: ["Oui", "Non", "PrĂ©histoire"], answer: 2 }, { question: "Combien pĂšse une reine des abeilles ?", choices: ["0.2g", "0.5g", "1g"], answer: 0 }, { question: "Les araignĂ©es peuvent-elles ĂȘtre transparentes ?", choices: ["Oui", "Non", "Certaines espĂšces"], answer: 2 }, { question: "Ă quelle distance les abeilles sentent-elles les fleurs ?", choices: ["1m", "100m", "1km"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles ĂȘtre immortelles ?", choices: ["Oui", "Non", "ThĂ©oriquement"], answer: 1 }, { question: "Combien de rayons contient une ruche moyenne ?", choices: ["5", "10", "20"], answer: 1 }, { question: "Les araignĂ©es peuvent-elles prĂ©dire le temps ?", choices: ["Oui", "Non", "Comportement change"], answer: 2 }, { question: "Quel pourcentage d'eau contient le miel mĂ»r ?", choices: ["10%", "18%", "30%"], answer: 1 }]; // Affiche le panneau de choix pour faire un quizz ou non function showQuizChoicePanel(onYes, onNo) { var panel = new Container(); panel.x = 2048 / 2; panel.y = 2732 / 2; var bg = LK.getAsset('battlePanel', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.5, alpha: 0.97 }); panel.addChild(bg); var txt = new Text2("Veux-tu tenter un mini-quizz pour un bonus de dĂ©gĂąts ?", { size: 50, fill: 0x000000 }); txt.anchor.set(0.5, 0.5); txt.y = -80; panel.addChild(txt); // Oui var yesBtn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: -180, y: 80, tint: 0x00bb00 }); var yesTxt = new Text2("Oui", { size: 40, fill: 0xffffff }); yesTxt.anchor.set(0.5, 0.5); yesTxt.x = -180; yesTxt.y = 80; panel.addChild(yesBtn); panel.addChild(yesTxt); // Non var noBtn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: 180, y: 80, tint: 0xbb0000 }); var noTxt = new Text2("Non", { size: 40, fill: 0xffffff }); noTxt.anchor.set(0.5, 0.5); noTxt.x = 180; noTxt.y = 80; panel.addChild(noBtn); panel.addChild(noTxt); yesBtn.interactive = true; yesBtn.down = function () { if (panel.parent) panel.parent.removeChild(panel); if (onYes) onYes(); }; noBtn.interactive = true; noBtn.down = function () { if (panel.parent) panel.parent.removeChild(panel); if (onNo) onNo(); }; LK.gui.addChild(panel); } // Affiche le panneau de quizz function showQuizPanel(onResult) { // Choisit une question au hasard var q = quizQuestions[Math.floor(Math.random() * quizQuestions.length)]; var panel = new Container(); panel.x = 2048 / 2; panel.y = 2732 / 2; var bg = LK.getAsset('battlePanel', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.7, alpha: 0.97 }); panel.addChild(bg); var txt = new Text2(q.question, { size: 50, fill: 0x000000 }); txt.anchor.set(0.5, 0.5); txt.y = -180; panel.addChild(txt); // Affiche les choix for (var i = 0; i < q.choices.length; i++) { (function (idx) { var btn = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.5, x: 0, y: -40 + idx * 120, tint: 0xeeeeee }); var choiceTxt = new Text2(q.choices[idx], { size: 40, fill: 0x000000 }); choiceTxt.anchor.set(0.5, 0.5); choiceTxt.x = 0; choiceTxt.y = -40 + idx * 120; panel.addChild(btn); panel.addChild(choiceTxt); btn.interactive = true; btn.down = function () { // Affiche rĂ©sultat if (idx === q.answer) { txt.setText("Bonne rĂ©ponse ! Bonus de dĂ©gĂąts activĂ© !"); if (onResult) onResult(true); } else { txt.setText("Mauvaise rĂ©ponse !"); if (onResult) onResult(false); } // Ferme le panneau aprĂšs 1s LK.setTimeout(function () { if (panel.parent) panel.parent.removeChild(panel); }, 1000); }; })(i); } LK.gui.addChild(panel); } // Remplace la fonction playerAttack par une version qui gĂšre le quizz et le bonus function playerAttack() { // VĂ©rifie si on doit proposer un quizz var spidersToQuiz = currentLevel < 10 ? 4 : 7; if (!window.quizState) window.quizState = { spidersSinceLastQuiz: 0, bonusActive: false, bonusSpidersLeft: 0 }; // Si le bonus est actif, on le dĂ©crĂ©mente if (window.quizState.bonusActive) { // On applique le bonus de dĂ©gĂąts window.quizState.bonusSpidersLeft--; if (window.quizState.bonusSpidersLeft <= 0) { window.quizState.bonusActive = false; } } // Si c'est le moment du quizz, on propose le choix if (window.quizState.spidersSinceLastQuiz >= spidersToQuiz) { showQuizChoicePanel(function () { // Oui, on fait le quizz showQuizPanel(function (isCorrect) { if (isCorrect) { window.quizState.bonusActive = true; window.quizState.bonusSpidersLeft = 2; } window.quizState.spidersSinceLastQuiz = 0; // AprĂšs le quizz, attaque normale doPlayerAttack(); }); }, function () { // Non, on attaque normalement window.quizState.spidersSinceLastQuiz = 0; doPlayerAttack(); }); return; } else { doPlayerAttack(); } } // Fonction d'attaque rĂ©elle du joueur (avec bonus si actif) function doPlayerAttack() { var baseDamage = 20 + Math.floor(Math.random() * 10); // 20-29 var damage = baseDamage; if (window.quizState && window.quizState.bonusActive) { damage = Math.floor(baseDamage * 1.2); } game.battleState.currentSpider.takeDamage(damage); LK.getSound('attack').play(); // Update battle UI battleUI.updateHealth(bee.health, bee.maxHealth, game.battleState.currentSpider.health, game.battleState.currentSpider.maxHealth); // Flash effect on spider LK.effects.flashObject(game.battleState.currentSpider, 0xFF0000, 300); // Check if spider is defeated if (game.battleState.currentSpider.defeated) { // IncrĂ©mente le compteur d'araignĂ©es vaincues pour le quizz if (window.quizState) window.quizState.spidersSinceLastQuiz++; LK.setTimeout(function () { endBattle(true); }, 1000); return; } // Switch turns game.battleState.isPlayerTurn = false; battleUI.setTurnText(false); // Spider attacks after delay LK.setTimeout(function () { spiderAttack(); }, game.battleState.turnDelay); } // Spider attacks in battle function spiderAttack() { // Spider attack now deals random damage between 1 and 20 var damage = 1 + Math.floor(Math.random() * 20); bee.takeDamage(damage); LK.getSound('hurt').play(); // Update battle UI battleUI.updateHealth(bee.health, bee.maxHealth, game.battleState.currentSpider.health, game.battleState.currentSpider.maxHealth); // Flash effect on bee LK.effects.flashObject(bee, 0xFF0000, 300); // Check if bee is defeated if (bee.health <= 0) { LK.setTimeout(function () { endBattle(false); }, 1000); return; } // Switch turns game.battleState.isPlayerTurn = true; battleUI.setTurnText(true); } // End battle function endBattle(playerWon) { // Remove battle UI game.removeChild(battleUI); if (playerWon) { // Mark spider as defeated game.battleState.currentSpider.defeated = true; // Joue le son de coup de fusil LK.getSound('gun').play(); // Make spider invisible game.battleState.currentSpider.alpha = 0; // Increase score LK.setScore(LK.getScore() + 100); scoreText.setText("Score: " + LK.getScore()); // Only increment spiders defeated counter if the spider was properly encountered and defeated manually in battle // Ensure only one spider is counted at a time if (game.battleState.currentSpider.encounteredByPlayer && !game.battleState.currentSpider.countedAsDefeated) { var spiderEquivalent = 1; if (game.battleState.currentSpider.isHornet) spiderEquivalent = 10;else if (game.battleState.currentSpider.isWasp) spiderEquivalent = 20;else if (game.battleState.currentSpider.isDragonfly) spiderEquivalent = 30;else if (game.battleState.currentSpider.isBird) spiderEquivalent = 70; spidersDefeated += spiderEquivalent; game.battleState.currentSpider.countedAsDefeated = true; spidersDefeatedText.setText("Spiders: " + spidersDefeated); // Award ML based on enemy type ml += spiderEquivalent; storage.ml = ml; if (mlText) mlText.setText("ML: " + ml); // IncrĂ©mente le compteur d'araignĂ©es vaincues pour le quizz if (window.quizState) window.quizState.spidersSinceLastQuiz += spiderEquivalent; } // Bee ne rĂ©cupĂšre plus de points de vie automatiquement aprĂšs victoire (sauf lors du passage de niveau ou revitaliser) // (Bloc supprimĂ© pour respecter la nouvelle rĂšgle) // Only allow one level up at a time and require progressive spider defeats // Level 1: 5 spiders, Level 2: 10, Level 3: 20, Level 4: 40, Level 5: 80, etc. (doubles each level) var spidersNeededForNextLevel = 5 * Math.pow(2, currentLevel - 1); // Game now has 17500 levels var maxLevels = 17500; // Check if player is at max level and has defeated enough spiders if (currentLevel >= maxLevels && spidersDefeated >= spidersNeededForNextLevel) { // Display victory message var victoryContainer = new Container(); victoryContainer.x = 2048 / 2; victoryContainer.y = 2732 / 2; var victoryBackground = LK.getAsset('battlePanel', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, alpha: 0.9 }); victoryContainer.addChild(victoryBackground); var victoryText = new Text2("Merci d'avoir jouĂ© a Bee Wars!\nFĂ©licitations tu as complĂ©ter le jeu!\nA bientĂŽt pour de futures jeux de clem27games !", { size: 80, fill: 0xFF69B4 // Pink color }); victoryText.anchor.set(0.5, 0.5); victoryContainer.addChild(victoryText); game.addChild(victoryContainer); // Create OK button to reset game var okButton = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 200, tint: 0x00FF00 }); victoryContainer.addChild(okButton); var okText = new Text2("OK", { size: 60, fill: 0xFFFFFF }); okText.anchor.set(0.5, 0.5); okText.x = 0; okText.y = 200; victoryContainer.addChild(okText); // Add down handler to the container victoryContainer.down = function (x, y, obj) { // Check if OK button was pressed if (x >= okButton.x - okButton.width / 2 && x <= okButton.x + okButton.width / 2 && y >= okButton.y - okButton.height / 2 && y <= okButton.y + okButton.height / 2) { // Reset to level 1 currentLevel = 1; storage.currentLevel = 1; // Remove previous levelText if it exists if (levelText && levelText.parent) { levelText.parent.removeChild(levelText); } levelText = null; // Remove previous spidersDefeatedText if it exists if (spidersDefeatedText && spidersDefeatedText.parent) { spidersDefeatedText.parent.removeChild(spidersDefeatedText); } spidersDefeatedText = null; initLevel(currentLevel); game.removeChild(victoryContainer); } }; return; // Exit function early } else if (spidersDefeated >= spidersNeededForNextLevel && currentLevel < maxLevels) { // Only allow a single level up at a time, even if player has defeated more spiders than needed // Restore bee health before advancing to next level bee.health = bee.maxHealth; // Prevent skipping levels: only increment by 1, and reset spidersDefeated to 0 LK.setTimeout(function () { currentLevel++; storage.currentLevel = currentLevel; // Reset spiders defeated for the new level spidersDefeated = 0; spidersDefeatedText.setText("Spiders: " + spidersDefeated); // Update the level banner to show the new level if (levelText) { levelText.setText("Niveau : " + currentLevel + " / " + maxLevels); } initLevel(currentLevel); }, 1000); } } else { // --- Bee Wars: If main bee dies in battle, replace with extra bee if available --- if (extraBees.length > 0) { // Remove main bee from game if (bee.parent) bee.parent.removeChild(bee); // Promote first extra bee to main bee var newBee = extraBees.shift(); beeQueue.shift(); newBee.isActive = true; bee = newBee; beeQueue[0] = bee; // Set controls to new bee controlsUI.onLeftPressed = function () { bee.moveLeft(); }; controlsUI.onRightPressed = function () { bee.moveRight(); }; controlsUI.onJumpPressed = function () { bee.jump(); }; controlsUI.onUpPressed = function () { bee.moveUp(); }; controlsUI.onControlsReleased = function () { bee.stopMoving(); }; // Place new bee at last position bee.x = game.battleState.originalBeeX; bee.y = game.battleState.originalBeeY; bee.velocityX = 0; bee.velocityY = 0; bee.onGround = true; bee.fallingInVoid = false; bee.alpha = 1.0; // Defensive: update followTarget for remaining extra bees for (var i = 0; i < extraBees.length; i++) { extraBees[i].followTarget = beeQueue[i]; extraBees[i]._index = i; } // Add to game if not already if (!bee.parent) game.addChild(bee); // Return to platform mode gameState = "platform"; return; } else { // Reset to level 1 on defeat currentLevel = 1; storage.currentLevel = 1; // Remove previous levelText if it exists if (levelText && levelText.parent) { levelText.parent.removeChild(levelText); } levelText = null; // Remove previous spidersDefeatedText if it exists if (spidersDefeatedText && spidersDefeatedText.parent) { spidersDefeatedText.parent.removeChild(spidersDefeatedText); } spidersDefeatedText = null; initLevel(currentLevel); // Game over if player lost LK.showGameOver({ message: "L'araign\xE9e t'a vaincu, tu es morte, petite abeille\u202F!" }); return; } } // Restore bee's position and state from before the battle bee.x = game.battleState.originalBeeX; bee.y = game.battleState.originalBeeY; bee.onGround = game.battleState.originalOnGround; // Ensure bee doesn't fall by zeroing velocities bee.velocityX = 0; bee.velocityY = 0; // Return to platform mode gameState = "platform"; } // Start level scrolling function startLevelScrolling() { levelScrolling = true; lastPlatformX = platforms[platforms.length - 1].x; // Start platform generation timer platformGenerationTimer = LK.setInterval(function () { generateNewPlatform(); }, 2000); // Start spider generation timer spiderGenerationTimer = LK.setInterval(function () { generateNewSpider(); }, 5000); // Move finish line further ahead tween(finishLine, { x: 2048 + 3000 }, { duration: 1000, easing: tween.linear }); } // Generate a new platform ahead function generateNewPlatform() { if (!levelScrolling) { return; } var platform = new Platform(); // Position new platform off screen to the right platform.x = 2048 + platform.width / 2; // Randomize y position within screen bounds var minPlatformY = 500; var maxPlatformY = 2732 - 500; platform.y = minPlatformY + Math.random() * (maxPlatformY - minPlatformY); // Add platform to game platforms.push(platform); game.addChild(platform); // Update last platform x position lastPlatformX = platform.x; } // Generate a new spider on a platform function generateNewSpider() { if (!levelScrolling) { return; } // Find suitable platform for new spider (one that's just entered the screen) var suitablePlatforms = []; for (var i = 0; i < platforms.length; i++) { if (platforms[i].x > 1500 && platforms[i].x < 2500) { suitablePlatforms.push(platforms[i]); } } if (suitablePlatforms.length === 0) { return; } // Choose a random platform var platform = suitablePlatforms[Math.floor(Math.random() * suitablePlatforms.length)]; // Create new enemy based on level var spider; if (currentLevel >= 5000 && Math.random() < 0.15) { spider = new Bird(); } else if (currentLevel >= 750 && Math.random() < 0.12) { spider = new Dragonfly(); } else if (currentLevel >= 444 && Math.random() < 0.10) { spider = new Wasp(); } else if (currentLevel >= 100 && Math.random() < 0.08) { spider = new Hornet(); } else { spider = new Spider(); } // Update spider's max health based on current level (20 more health per level) - but only for regular spiders if (!spider.isHornet && !spider.isWasp && !spider.isDragonfly && !spider.isBird) { spider.maxHealth = spider.baseMaxHealth + (currentLevel - 1) * 20; spider.health = spider.maxHealth; } spider.x = platform.x; spider.y = platform.y - platform.height / 2 - spider.height / 2; spider.currentPlatform = platform; // Add spider to game spiders.push(spider); game.addChild(spider); } // Stop level scrolling function stopLevelScrolling() { levelScrolling = false; // Clear timers if (platformGenerationTimer) { LK.clearInterval(platformGenerationTimer); platformGenerationTimer = null; } if (spiderGenerationTimer) { LK.clearInterval(spiderGenerationTimer); spiderGenerationTimer = null; } } // Complete level function completeLevel() { LK.getSound('levelComplete').play(); // Stop level scrolling stopLevelScrolling(); // Increase level currentLevel++; storage.currentLevel = currentLevel; // Award ML for level completion if (currentLevel < 10) { ml += 3; } else { ml += 8; } storage.ml = ml; if (mlText) mlText.setText("ML: " + ml); // Update bee's max health based on new level and restore health (seul moment oĂč l'abeille rĂ©cupĂšre toute sa vie) bee.maxHealth = bee.baseMaxHealth + (currentLevel - 1) * 50; bee.health = bee.maxHealth; // Update the level banner to show the new level if (levelText) { levelText.setText("Niveau : " + currentLevel + " / " + maxLevels); } // Check if player has reached the max level if (currentLevel >= maxLevels) { // Reset to level 1 and show victory message currentLevel = 1; storage.currentLevel = 1; // Remove previous levelText if it exists if (levelText && levelText.parent) { levelText.parent.removeChild(levelText); } levelText = null; // Remove previous spidersDefeatedText if it exists if (spidersDefeatedText && spidersDefeatedText.parent) { spidersDefeatedText.parent.removeChild(spidersDefeatedText); } spidersDefeatedText = null; initLevel(currentLevel); // Create victory message var victoryContainer = new Container(); victoryContainer.x = 2048 / 2; victoryContainer.y = 2732 / 2; var victoryBackground = LK.getAsset('battlePanel', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, alpha: 0.9 }); victoryContainer.addChild(victoryBackground); var victoryText = new Text2("FĂ©licitations vous avez complĂ©tĂ© Bee Wars !\nA bientĂŽt pour de nouveaux jeu de clem27games", { size: 80, fill: 0xFF69B4 // Pink color }); victoryText.anchor.set(0.5, 0.5); victoryContainer.addChild(victoryText); game.addChild(victoryContainer); // Create OK button to reset game var okButton = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 200, tint: 0x00FF00 }); victoryContainer.addChild(okButton); var okText = new Text2("OK", { size: 60, fill: 0xFFFFFF }); okText.anchor.set(0.5, 0.5); okText.x = 0; okText.y = 200; victoryContainer.addChild(okText); // Add down handler to the container victoryContainer.down = function (x, y, obj) { // Check if OK button was pressed if (x >= okButton.x - okButton.width / 2 && x <= okButton.x + okButton.width / 2 && y >= okButton.y - okButton.height / 2 && y <= okButton.y + okButton.height / 2) { // Reset to level 1 currentLevel = 1; storage.currentLevel = 1; // Reset spiders defeated for new level spidersDefeated = 0; spidersDefeatedText.setText("Spiders: " + spidersDefeated); initLevel(currentLevel); game.removeChild(victoryContainer); } }; // Show win screen after showing message for a few seconds if player doesn't click OK LK.setTimeout(function () { LK.showYouWin(); }, 30000); return; } // Initialize next level LK.setTimeout(function () { initLevel(currentLevel); // Remove previous levelText if it exists if (levelText && levelText.parent) { levelText.parent.removeChild(levelText); } levelText = null; // Remove previous spidersDefeatedText if it exists if (spidersDefeatedText && spidersDefeatedText.parent) { spidersDefeatedText.parent.removeChild(spidersDefeatedText); } spidersDefeatedText = null; initLevel(currentLevel); }, 1000); } // Check collision between bee and platform function checkPlatformCollision(bee, platform) { // Simple rectangle collision var beeLeft = bee.x - bee.width / 2; var beeRight = bee.x + bee.width / 2; var beeTop = bee.y - bee.height / 2; var beeBottom = bee.y + bee.height / 2; var platformLeft = platform.x - platform.width / 2; var platformRight = platform.x + platform.width / 2; var platformTop = platform.y - platform.height / 2; var platformBottom = platform.y + platform.height / 2; // Check for collision if (beeRight > platformLeft && beeLeft < platformRight && beeBottom > platformTop && beeTop < platformBottom) { // Check if landing on top of platform if (beeBottom > platformTop && bee.velocityY > 0 && beeTop < platformTop) { bee.y = platformTop - bee.height / 2; bee.velocityY = 0; bee.onGround = true; bee.isJumping = false; // Check for spiders on this platform to battle for (var i = 0; i < spiders.length; i++) { var spider = spiders[i]; if (!spider.defeated && spider.currentPlatform === platform) { // If we landed on a platform with a spider, start battle LK.setTimeout(function () { startBattle(spider); }, 100); break; } } return true; } } return false; } // Find and jump to the nearest platform function findAndJumpToNearestPlatform() { var nearestPlatform = null; var shortestDistance = Infinity; // Find the nearest platform for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; var horizontalDistance = Math.abs(platform.x - bee.x); // Only consider platforms that are reasonably within reach horizontally if (horizontalDistance < 500) { var verticalDistance = platform.y - platform.height / 2 - bee.y; // Prefer platforms slightly above the bee or at the same level var distance = horizontalDistance + (verticalDistance > 0 ? verticalDistance * 2 : Math.abs(verticalDistance) * 0.5); if (distance < shortestDistance) { shortestDistance = distance; nearestPlatform = platform; } } } // If we found a platform, animate jumping to it if (nearestPlatform) { // Stop current movement bee.velocityX = 0; bee.velocityY = 0; // Play jump sound LK.getSound('jump').play(); // Tween to the platform position with a nice arc var targetX = nearestPlatform.x; var targetY = nearestPlatform.y - nearestPlatform.height / 2 - bee.height / 2; // Create an animation that looks like a jump tween(bee, { x: targetX, y: targetY }, { duration: 800, easing: tween.easeOutQuad, onFinish: function onFinish() { bee.onGround = true; bee.isJumping = false; } }); } } // Handle bee dragging - mouse/touch down game.down = function (x, y, obj) { if (gameState === "platform") { // Check if tap is on the bee var beeLeft = bee.x - bee.width / 2; var beeRight = bee.x + bee.width / 2; var beeTop = bee.y - bee.height / 2; var beeBottom = bee.y + bee.height / 2; if (x >= beeLeft && x <= beeRight && y >= beeTop && y <= beeBottom) { dragTarget = bee; // Stop current movement when starting to drag bee.velocityX = 0; bee.velocityY = 0; LK.getSound('bzz').play(); } } }; // Handle game movement game.move = function (x, y, obj) { // Only process movement in platform mode if (gameState === "platform") { // If dragging the bee, update its position if (dragTarget) { dragTarget.x = x; dragTarget.y = y; // Reset falling flags when manually dragging bee.fallingInVoid = false; return; } // Check if bee is falling in void and rescue it with any tap if (bee.fallingInVoid) { findAndJumpToNearestPlatform(); return; } // If tap is on the top fifth of the screen, jump if (y < 2732 / 5) { bee.jump(); } // If tap is in the top-mid section of the screen, move up else if (y < 2732 / 3) { bee.moveUp(); } // If tap is on the right half of the screen, move right else if (x > 2048 / 2) { bee.moveRight(); } // If tap is on the left half of the screen, move left else { bee.moveLeft(); } } }; // Initialize first level initLevel(currentLevel); // Handle touch release to stop bee movement or place bee on platform when dragging game.up = function (x, y, obj) { if (gameState === "platform") { if (dragTarget) { // Check if bee is over a platform to place it properly var platformFound = false; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; var platformLeft = platform.x - platform.width / 2; var platformRight = platform.x + platform.width / 2; var platformTop = platform.y - platform.height / 2; // If bee is above platform horizontally, place it on the platform if (bee.x >= platformLeft && bee.x <= platformRight) { bee.y = platformTop - bee.height / 2; bee.velocityY = 0; bee.onGround = true; bee.isJumping = false; platformFound = true; break; } } // If no platform found beneath the bee, it starts falling if (!platformFound) { bee.onGround = false; bee.velocityY = 1; // Start falling gently } // Release drag target dragTarget = null; // --- Bee Wars: After drag, update extra bees followTarget --- for (var i = 0; i < extraBees.length; i++) { extraBees[i].followTarget = beeQueue[i]; extraBees[i]._index = i; } } else { bee.stopMoving(); } } }; // Game update loop game.update = function () { // Skip update if in battle mode if (gameState === "battle") { return; } // Only update bee physics if not being dragged if (!dragTarget) { // Update bee bee.update(); // Update extra bees (they follow the beeQueue) for (var i = 0; i < extraBees.length; i++) { extraBees[i].update(); } } // Draw extra bees in front of main bee for (var i = 0; i < extraBees.length; i++) { if (extraBees[i].parent !== game) { game.addChild(extraBees[i]); } // Always keep extra bees above the bee if (bee.parent && extraBees[i].parent) { if (game.children.indexOf(extraBees[i]) < game.children.indexOf(bee)) { game.removeChild(extraBees[i]); game.addChild(extraBees[i]); } } } // Add visual indication when bee is falling in void if (bee.fallingInVoid) { // Flash the bee to indicate it can be rescued if (LK.ticks % 10 < 5) { bee.alpha = 0.5; } else { bee.alpha = 1.0; } } else { bee.alpha = 1.0; } // Check for platform collisions if bee is not being dragged if (!dragTarget) { // Check for platform collisions for (var i = 0; i < platforms.length; i++) { var collided = checkPlatformCollision(bee, platforms[i]); // Platform ML logic: count platforms passed (without spider) if (collided) { if (lastBeePlatform !== platforms[i]) { // Only count if platform has no spider on it var hasSpider = false; for (var s = 0; s < spiders.length; s++) { if (!spiders[s].defeated && spiders[s].currentPlatform === platforms[i]) { hasSpider = true; break; } } if (!hasSpider) { platformsPassed++; platformsPassedSinceLastML++; // Award 2 ML every 5 platforms passed (without spider) if (platformsPassedSinceLastML >= 5) { ml += 2; storage.ml = ml; if (mlText) mlText.setText("ML: " + ml); platformsPassedSinceLastML = 0; } } lastBeePlatform = platforms[i]; } } // Defensive: if bee is not on any platform, reset lastBeePlatform if (!collided && lastBeePlatform === platforms[i]) { lastBeePlatform = null; } checkPlatformCollision(bee, platforms[i]); } } // Check for screen boundaries if (bee.x < bee.width / 2) { bee.x = bee.width / 2; } else if (bee.x > 2048 - bee.width / 2) { bee.x = 2048 - bee.width / 2; } // Check if bee is falling with no platform below if (bee.y > 2732 - 400 && bee.velocityY > 0 && !bee.onGround) { // Set a flag that bee is falling in void to allow rescue by tap bee.fallingInVoid = true; } else if (bee.y > 2732 + bee.height) { // Fell off the screen // --- Bee Wars: If main bee dies outside battle, replace with extra bee if available --- if (extraBees.length > 0) { // Remove main bee from game if (bee.parent) bee.parent.removeChild(bee); // Promote first extra bee to main bee var newBee = extraBees.shift(); beeQueue.shift(); newBee.isActive = true; bee = newBee; beeQueue[0] = bee; // Set controls to new bee controlsUI.onLeftPressed = function () { bee.moveLeft(); }; controlsUI.onRightPressed = function () { bee.moveRight(); }; controlsUI.onJumpPressed = function () { bee.jump(); }; controlsUI.onUpPressed = function () { bee.moveUp(); }; controlsUI.onControlsReleased = function () { bee.stopMoving(); }; // Place new bee at start position bee.x = 150; bee.y = 2732 / 2; bee.velocityX = 0; bee.velocityY = 0; bee.onGround = true; bee.fallingInVoid = false; bee.alpha = 1.0; // Defensive: update followTarget for remaining extra bees for (var i = 0; i < extraBees.length; i++) { extraBees[i].followTarget = beeQueue[i]; extraBees[i]._index = i; } // Add to game if not already if (!bee.parent) game.addChild(bee); return; } else { LK.showGameOver(); return; } } else { // Reset falling flag when not in danger zone bee.fallingInVoid = false; } // Check for spiders on the same platform as bee for (var i = 0; i < spiders.length; i++) { var spider = spiders[i]; if (!spider.defeated) { // Check if bee and spider are on the same platform if (spider.currentPlatform) { var onSamePlatform = Math.abs(bee.x - spider.x) < spider.currentPlatform.width * 0.8 && Math.abs(bee.y - spider.y) < 20; if (onSamePlatform && !spider.moving) { // Spider should move away spider.moveAwayFromBee(bee); } } // Check for collision or shared platform to start battle if (bee.intersects(spider) || spider.currentPlatform && bee.onGround && Math.abs(bee.x - spider.x) < spider.currentPlatform.width * 0.5) { startBattle(spider); return; } } } // Check if all spiders on screen are defeated to start scrolling var visibleSpiders = false; for (var i = 0; i < spiders.length; i++) { if (!spiders[i].defeated && spiders[i].x < 2048) { visibleSpiders = true; break; } } // Start level scrolling if all visible spiders are defeated and not already scrolling if (!visibleSpiders && !levelScrolling && bee.onGround) { startLevelScrolling(); } // Handle platform and object movement when scrolling if (levelScrolling) { // Move platforms for (var i = 0; i < platforms.length; i++) { platforms[i].x += scrollSpeed; // Remove platforms that have gone off screen if (platforms[i].x < -platforms[i].width) { game.removeChild(platforms[i]); platforms.splice(i, 1); i--; } } // Move spiders with their platforms for (var i = 0; i < spiders.length; i++) { if (spiders[i].currentPlatform) { spiders[i].x = spiders[i].currentPlatform.x; } } // Move finish line finishLine.x += scrollSpeed; // If bee is on a platform, move it with the platform if (bee.onGround) { bee.x += scrollSpeed; } } // Check for finish line collision if (bee.intersects(finishLine)) { // Check if all spiders are defeated var allSpidersDefeated = true; for (var i = 0; i < spiders.length; i++) { if (!spiders[i].defeated) { allSpidersDefeated = false; break; } } if (allSpidersDefeated) { completeLevel(); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
currentLevel: 1
});
/****
* Classes
****/
var BattleUI = Container.expand(function () {
var self = Container.call(this);
var panel = self.attachAsset('battlePanel', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
var attackBtn = self.attachAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 200
});
self.beeHealthBar = self.attachAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
x: -300,
y: -150
});
self.spiderHealthBar = self.attachAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
x: 0,
y: -150
});
var beeHealthText = new Text2("Bee: 100/100", {
size: 40,
fill: 0xFFFFFF
});
beeHealthText.anchor.set(0, 0.5);
beeHealthText.x = -300;
beeHealthText.y = -200;
self.addChild(beeHealthText);
var spiderHealthText = new Text2("Spider: 50/50", {
size: 40,
fill: 0xFFFFFF
});
spiderHealthText.anchor.set(0, 0.5);
spiderHealthText.x = 0;
spiderHealthText.y = -200;
self.addChild(spiderHealthText);
var turnText = new Text2("Your Turn", {
size: 60,
fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0.5);
turnText.y = -300;
self.addChild(turnText);
var attackText = new Text2("Attack", {
size: 50,
fill: 0xFFFFFF
});
attackText.anchor.set(0.5, 0.5);
attackText.x = 0;
attackText.y = 200;
self.addChild(attackText);
self.updateHealth = function (beeHealth, beeMaxHealth, spiderHealth, spiderMaxHealth) {
// Update health bars
self.beeHealthBar.scale.x = beeHealth / beeMaxHealth;
self.spiderHealthBar.scale.x = spiderHealth / spiderMaxHealth;
// Update text
beeHealthText.setText("Bee: " + beeHealth + "/" + beeMaxHealth);
spiderHealthText.setText("Spider: " + spiderHealth + "/" + spiderMaxHealth);
};
self.setTurnText = function (isPlayerTurn) {
turnText.setText(isPlayerTurn ? "Your Turn" : "Spider's Turn");
};
self.down = function (x, y, obj) {
// Check if attack button was pressed
if (x >= attackBtn.x - attackBtn.width / 2 && x <= attackBtn.x + attackBtn.width / 2 && y >= attackBtn.y - attackBtn.height / 2 && y <= attackBtn.y + attackBtn.height / 2) {
if (self.onAttackPressed && game.battleState.isPlayerTurn) {
self.onAttackPressed();
}
}
};
return self;
});
var Bee = Container.expand(function () {
var self = Container.call(this);
var beeGraphic = self.attachAsset('bee', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.speed = 8;
self.jumpForce = -20;
self.gravity = 1;
self.onGround = false;
self.health = 100;
self.maxHealth = 100;
self.baseMaxHealth = 100; // Base health value
self.isJumping = false;
self.fallingInVoid = false;
self.update = function () {
// Apply gravity
if (!self.onGround) {
self.velocityY += self.gravity;
}
// Update position
self.x += self.velocityX;
self.y += self.velocityY;
// Reset onGround flag for next frame collision detection
self.onGround = false;
};
self.moveUp = function () {
// Only allow moving up when not jumping
if (!self.isJumping) {
self.velocityY = -self.speed * 0.8; // Slower than horizontal movement
LK.getSound('bzz').play();
}
};
self.jump = function () {
if (self.onGround) {
self.velocityY = self.jumpForce;
self.onGround = false;
self.isJumping = true;
LK.getSound('jump').play();
LK.getSound('bzz').play();
}
};
self.moveLeft = function () {
self.velocityX = -self.speed;
LK.getSound('bzz').play();
};
self.moveRight = function () {
self.velocityX = self.speed;
LK.getSound('bzz').play();
};
self.stopMoving = function () {
self.velocityX = 0;
};
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health < 0) {
self.health = 0;
}
LK.getSound('hurt').play();
};
self.heal = function (amount) {
self.health += amount;
if (self.health > self.maxHealth) {
self.health = self.maxHealth;
}
};
return self;
});
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphic = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x8B4513,
scaleX: 2.0,
scaleY: 2.0
});
self.baseMaxHealth = 6000 + Math.floor(Math.random() * 20001); // 6000-26000
self.maxHealth = self.baseMaxHealth;
self.health = self.maxHealth;
self.attackDamage = 80 + Math.floor(Math.random() * 41); // 80-120
self.defeated = false;
self.currentPlatform = null;
self.moving = false;
self.encounteredByPlayer = false;
self.isBird = true;
self.moveAwayFromBee = function (bee) {
if (self.moving || self.defeated) return;
self.moving = true;
var originalBeeY = bee.y;
var originalBeeX = bee.x;
var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8;
var keepBeeOnPlatform = isOnSamePlatform;
var nearbyPlatforms = [];
for (var i = 0; i < platforms.length; i++) {
if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) {
nearbyPlatforms.push(platforms[i]);
}
}
if (nearbyPlatforms.length === 0) {
self.moving = false;
return;
}
nearbyPlatforms.sort(function (a, b) {
var distA = Math.abs(a.x - bee.x);
var distB = Math.abs(b.x - bee.x);
return distB - distA;
});
var targetPlatform = nearbyPlatforms[0];
var targetX = targetPlatform.x;
var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2;
tween(self, {
x: targetX,
y: targetY
}, {
duration: 500,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
self.currentPlatform = targetPlatform;
self.moving = false;
if (keepBeeOnPlatform) {
bee.x = originalBeeX;
bee.y = originalBeeY;
bee.onGround = true;
bee.velocityY = 0;
bee.isJumping = false;
}
}
});
};
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
self.defeated = true;
}
};
self.attack = function () {
return self.attackDamage;
};
return self;
});
var ControlsUI = Container.expand(function () {
var self = Container.call(this);
// Left button
var leftBtn = self.attachAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
x: -800,
y: 0,
tint: 0x0000FF
});
var leftText = new Text2("<", {
size: 80,
fill: 0xFFFFFF
});
leftText.anchor.set(0.5, 0.5);
leftText.x = -800;
self.addChild(leftText);
// Right button
var rightBtn = self.attachAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
x: -400,
y: 0,
tint: 0x0000FF
});
var rightText = new Text2(">", {
size: 80,
fill: 0xFFFFFF
});
rightText.anchor.set(0.5, 0.5);
rightText.x = -400;
self.addChild(rightText);
// Jump button
var jumpBtn = self.attachAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 800,
y: 0,
tint: 0x00FF00
});
var jumpText = new Text2("Jump", {
size: 50,
fill: 0xFFFFFF
});
jumpText.anchor.set(0.5, 0.5);
jumpText.x = 800;
self.addChild(jumpText);
// Up button
var upBtn = self.attachAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -80,
tint: 0x0099FF
});
var upText = new Text2("Up", {
size: 50,
fill: 0xFFFFFF
});
upText.anchor.set(0.5, 0.5);
upText.x = 0;
upText.y = -80;
self.addChild(upText);
self.down = function (x, y, obj) {
// Check if left button was pressed
if (x >= leftBtn.x - leftBtn.width / 2 && x <= leftBtn.x + leftBtn.width / 2 && y >= leftBtn.y - leftBtn.height / 2 && y <= leftBtn.y + leftBtn.height / 2) {
if (self.onLeftPressed) {
self.onLeftPressed();
}
}
// Check if right button was pressed
if (x >= rightBtn.x - rightBtn.width / 2 && x <= rightBtn.x + rightBtn.width / 2 && y >= rightBtn.y - rightBtn.height / 2 && y <= rightBtn.y + rightBtn.height / 2) {
if (self.onRightPressed) {
self.onRightPressed();
}
}
// Check if jump button was pressed
if (x >= jumpBtn.x - jumpBtn.width / 2 && x <= jumpBtn.x + jumpBtn.width / 2 && y >= jumpBtn.y - jumpBtn.height / 2 && y <= jumpBtn.y + jumpBtn.height / 2) {
if (self.onJumpPressed) {
self.onJumpPressed();
}
}
// Check if up button was pressed
if (x >= upBtn.x - upBtn.width / 2 && x <= upBtn.x + upBtn.width / 2 && y >= upBtn.y - upBtn.height / 2 && y <= upBtn.y + upBtn.height / 2) {
if (self.onUpPressed) {
self.onUpPressed();
}
}
};
self.up = function (x, y, obj) {
// When buttons are released, stop movement
if (self.onControlsReleased) {
self.onControlsReleased();
}
};
return self;
});
// DividingSpider: special spider that can split into two stronger spiders
var DividingSpider = Container.expand(function () {
var self = Container.call(this);
self.isDividingSpider = true;
self.hasDivided = false;
// Ensure health properties are always initialized and valid
self.baseMaxHealth = 50;
self.maxHealth = typeof self.maxHealth === "number" && !isNaN(self.maxHealth) ? self.maxHealth : 50;
self.health = typeof self.health === "number" && !isNaN(self.health) ? self.health : self.maxHealth;
self.attackDamage = 15;
self.defeated = false;
self.currentPlatform = null;
self.moving = false;
// Override attack to deal more damage (random between 15 and 50)
self.attack = function () {
return 15 + Math.floor(Math.random() * 36); // 15-50
};
// Override takeDamage to allow splitting
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0 && !self.hasDivided) {
// Only divide if not already divided
self.health = 0;
self.defeated = true;
self.hasDivided = true;
// Spawn two new spiders with more health
var newHealth = self.maxHealth + 30 + Math.floor(Math.random() * 40); // More health
for (var i = 0; i < 2; i++) {
var newSpider = new Spider();
newSpider.baseMaxHealth = 50;
newSpider.maxHealth = newHealth;
newSpider.health = newHealth;
newSpider.attackDamage = 15 + Math.floor(Math.random() * 36);
// Place on same platform, offset X
newSpider.x = self.x + (i === 0 ? -60 : 60);
newSpider.y = self.y;
newSpider.currentPlatform = self.currentPlatform;
spiders.push(newSpider);
game.addChild(newSpider);
}
} else if (self.health <= 0) {
self.health = 0;
self.defeated = true;
}
};
// Add moveAwayFromBee method (copy of Spider's)
self.moveAwayFromBee = function (bee) {
if (self.moving || self.defeated) {
return;
}
self.moving = true;
// Store bee's original position to ensure it doesn't fall
var originalBeeY = bee.y;
var originalBeeX = bee.x;
var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8;
var keepBeeOnPlatform = isOnSamePlatform;
// Find nearby platforms to move to
var nearbyPlatforms = [];
for (var i = 0; i < platforms.length; i++) {
if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) {
nearbyPlatforms.push(platforms[i]);
}
}
// If no nearby platforms, just return
if (nearbyPlatforms.length === 0) {
self.moving = false;
return;
}
// Sort platforms by distance from bee
nearbyPlatforms.sort(function (a, b) {
var distA = Math.abs(a.x - bee.x);
var distB = Math.abs(b.x - bee.x);
return distB - distA; // Further platforms first
});
// Get target platform (furthest from bee)
var targetPlatform = nearbyPlatforms[0];
var targetX = targetPlatform.x;
var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2;
// Animate spider moving to new platform
tween(self, {
x: targetX,
y: targetY
}, {
duration: 500,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
self.currentPlatform = targetPlatform;
self.moving = false;
// Ensure bee stays on platform if it was on the same platform as spider
if (keepBeeOnPlatform) {
bee.x = originalBeeX;
bee.y = originalBeeY;
bee.onGround = true;
bee.velocityY = 0;
bee.isJumping = false;
}
}
});
};
return self;
});
var Dragonfly = Container.expand(function () {
var self = Container.call(this);
var dragonflyGraphic = self.attachAsset('dragonfly', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x0099FF,
scaleX: 1.5,
scaleY: 1.5
});
self.baseMaxHealth = 1000 + Math.floor(Math.random() * 14001); // 1000-15000
self.maxHealth = self.baseMaxHealth;
self.health = self.maxHealth;
self.attackDamage = 50 + Math.floor(Math.random() * 31); // 50-80
self.defeated = false;
self.currentPlatform = null;
self.moving = false;
self.encounteredByPlayer = false;
self.isDragonfly = true;
self.moveAwayFromBee = function (bee) {
if (self.moving || self.defeated) return;
self.moving = true;
var originalBeeY = bee.y;
var originalBeeX = bee.x;
var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8;
var keepBeeOnPlatform = isOnSamePlatform;
var nearbyPlatforms = [];
for (var i = 0; i < platforms.length; i++) {
if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) {
nearbyPlatforms.push(platforms[i]);
}
}
if (nearbyPlatforms.length === 0) {
self.moving = false;
return;
}
nearbyPlatforms.sort(function (a, b) {
var distA = Math.abs(a.x - bee.x);
var distB = Math.abs(b.x - bee.x);
return distB - distA;
});
var targetPlatform = nearbyPlatforms[0];
var targetX = targetPlatform.x;
var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2;
tween(self, {
x: targetX,
y: targetY
}, {
duration: 500,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
self.currentPlatform = targetPlatform;
self.moving = false;
if (keepBeeOnPlatform) {
bee.x = originalBeeX;
bee.y = originalBeeY;
bee.onGround = true;
bee.velocityY = 0;
bee.isJumping = false;
}
}
});
};
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
self.defeated = true;
}
};
self.attack = function () {
return self.attackDamage;
};
return self;
});
// ExtraBee: small bee that follows the main bee and can replace it if main bee dies
var ExtraBee = Container.expand(function () {
var self = Container.call(this);
var beeGraphic = self.attachAsset('extraBee', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.9
});
self.velocityX = 0;
self.velocityY = 0;
self.speed = 8;
self.jumpForce = -20;
self.gravity = 1;
self.onGround = false;
self.health = 100;
self.maxHealth = 100;
self.baseMaxHealth = 100;
self.isJumping = false;
self.fallingInVoid = false;
self.isActive = false; // Only true if this bee is currently the main bee
self.followTarget = null; // The bee or extra bee to follow
self._index = 0; // Index in the beeQueue
self.update = function () {
// If not active, follow the previous bee in the queue
if (!self.isActive && self.followTarget) {
// Follow with a trailing effect
var dx = self.followTarget.x - self.x;
var dy = self.followTarget.y - self.y;
self.x += dx * 0.15;
self.y += dy * 0.15;
// Stay on ground if followTarget is on ground
self.onGround = self.followTarget.onGround;
} else if (self.isActive) {
// If active, behave like main bee
if (!self.onGround) {
self.velocityY += self.gravity;
}
self.x += self.velocityX;
self.y += self.velocityY;
self.onGround = false;
}
};
self.moveLeft = function () {
if (self.isActive) self.velocityX = -self.speed;
};
self.moveRight = function () {
if (self.isActive) self.velocityX = self.speed;
};
self.moveUp = function () {
if (self.isActive && !self.isJumping) {
self.velocityY = -self.speed * 0.8;
}
};
self.jump = function () {
if (self.isActive && self.onGround) {
self.velocityY = self.jumpForce;
self.onGround = false;
self.isJumping = true;
LK.getSound('jump').play();
}
};
self.stopMoving = function () {
if (self.isActive) self.velocityX = 0;
};
self.takeDamage = function (amount) {
if (self.isActive) {
self.health -= amount;
if (self.health < 0) self.health = 0;
LK.getSound('hurt').play();
}
};
self.heal = function (amount) {
if (self.isActive) {
self.health += amount;
if (self.health > self.maxHealth) self.health = self.maxHealth;
}
};
return self;
});
var FinishLine = Container.expand(function () {
var self = Container.call(this);
var finishLineGraphic = self.attachAsset('finishLine', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = finishLineGraphic.width;
self.height = finishLineGraphic.height;
return self;
});
var Hornet = Container.expand(function () {
var self = Container.call(this);
var hornetGraphic = self.attachAsset('hornet', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFFAA00
});
self.baseMaxHealth = 300 + Math.floor(Math.random() * 301); // 300-600
self.maxHealth = self.baseMaxHealth;
self.health = self.maxHealth;
self.attackDamage = 25 + Math.floor(Math.random() * 16); // 25-40
self.defeated = false;
self.currentPlatform = null;
self.moving = false;
self.encounteredByPlayer = false;
self.hasRevitalized = false;
self.originalMaxHealth = self.maxHealth;
self.isHornet = true;
self.moveAwayFromBee = function (bee) {
if (self.moving || self.defeated) return;
self.moving = true;
var originalBeeY = bee.y;
var originalBeeX = bee.x;
var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8;
var keepBeeOnPlatform = isOnSamePlatform;
var nearbyPlatforms = [];
for (var i = 0; i < platforms.length; i++) {
if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) {
nearbyPlatforms.push(platforms[i]);
}
}
if (nearbyPlatforms.length === 0) {
self.moving = false;
return;
}
nearbyPlatforms.sort(function (a, b) {
var distA = Math.abs(a.x - bee.x);
var distB = Math.abs(b.x - bee.x);
return distB - distA;
});
var targetPlatform = nearbyPlatforms[0];
var targetX = targetPlatform.x;
var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2;
tween(self, {
x: targetX,
y: targetY
}, {
duration: 500,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
self.currentPlatform = targetPlatform;
self.moving = false;
if (keepBeeOnPlatform) {
bee.x = originalBeeX;
bee.y = originalBeeY;
bee.onGround = true;
bee.velocityY = 0;
bee.isJumping = false;
}
}
});
};
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 100 && !self.hasRevitalized && Math.random() < 0.6) {
var healAmount = Math.floor(self.originalMaxHealth * 0.35);
self.health += healAmount;
if (self.health > self.maxHealth) self.health = self.maxHealth;
self.hasRevitalized = true;
LK.effects.flashObject(self, 0x00FF00, 500);
}
if (self.health <= 0) {
self.health = 0;
self.defeated = true;
}
};
self.attack = function () {
return self.attackDamage;
};
return self;
});
// NeighborHive: special hive that appears on platforms and allows buying extra bees
var NeighborHive = Container.expand(function () {
var self = Container.call(this);
var hiveGraphic = self.attachAsset('neighborHive', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.95
});
self.width = hiveGraphic.width;
self.height = hiveGraphic.height;
self.platform = null; // The platform this hive is on
self.interactive = true;
self.down = function (x, y, obj) {
// Only allow interaction if bee is on the same platform and close enough
if (!self.platform) return;
var dx = Math.abs(bee.x - self.x);
var dy = Math.abs(bee.y - self.y);
if (dx < self.width && dy < self.height * 2) {
// Show hive purchase dialog
showNeighborHiveDialog(self);
}
};
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphic = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = platformGraphic.width;
self.height = platformGraphic.height;
// Handle touch on platform
self.down = function (x, y, obj) {
if (gameState === "platform" && !dragTarget) {
// Move bee to this platform
self.moveBeeToThisPlatform();
}
};
// Function to move the bee to this platform
self.moveBeeToThisPlatform = function () {
// Stop current movement
bee.velocityX = 0;
bee.velocityY = 0;
// Play jump sound
LK.getSound('jump').play();
// Calculate target position on top of platform
var targetX = self.x;
var targetY = self.y - self.height / 2 - bee.height / 2;
// Create a tween animation for bee to jump to the platform
tween(bee, {
x: targetX,
y: targetY
}, {
duration: 800,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
bee.onGround = true;
bee.isJumping = false;
bee.fallingInVoid = false;
// Ensure the bee stays on this platform by locking position
bee.x = targetX;
bee.y = targetY;
// Make sure velocity is zero so it doesn't start moving/falling
bee.velocityX = 0;
bee.velocityY = 0;
// Check if there's a spider on this platform and make it move away
for (var i = 0; i < spiders.length; i++) {
var spider = spiders[i];
if (!spider.defeated && spider.currentPlatform === self) {
spider.moveAwayFromBee(bee);
}
}
}
});
};
return self;
});
var Spider = Container.expand(function () {
var self = Container.call(this);
var spiderGraphic = self.attachAsset('spider', {
anchorX: 0.5,
anchorY: 0.5
});
// Defensive: always initialize health properties
self.baseMaxHealth = 50; // Base health that will be scaled with level
self.maxHealth = typeof self.maxHealth === "number" && !isNaN(self.maxHealth) ? self.maxHealth : 50;
self.health = typeof self.health === "number" && !isNaN(self.health) ? self.health : self.maxHealth;
self.attackDamage = 15;
self.defeated = false;
self.currentPlatform = null;
self.moving = false;
self.encounteredByPlayer = false; // Track if player has encountered this spider
self.moveAwayFromBee = function (bee) {
if (self.moving || self.defeated) {
return;
}
self.moving = true;
// Store bee's original position to ensure it doesn't fall
var originalBeeY = bee.y;
var originalBeeX = bee.x;
var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8;
var keepBeeOnPlatform = isOnSamePlatform;
// Find nearby platforms to move to
var nearbyPlatforms = [];
for (var i = 0; i < platforms.length; i++) {
// Don't include current platform or platforms too far away
if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) {
nearbyPlatforms.push(platforms[i]);
}
}
// If no nearby platforms, just return
if (nearbyPlatforms.length === 0) {
self.moving = false;
return;
}
// Sort platforms by distance from bee
nearbyPlatforms.sort(function (a, b) {
var distA = Math.abs(a.x - bee.x);
var distB = Math.abs(b.x - bee.x);
return distB - distA; // Further platforms first
});
// Get target platform (furthest from bee)
var targetPlatform = nearbyPlatforms[0];
var targetX = targetPlatform.x;
var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2;
// Animate spider moving to new platform
tween(self, {
x: targetX,
y: targetY
}, {
duration: 500,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
self.currentPlatform = targetPlatform;
self.moving = false;
// Ensure bee stays on platform if it was on the same platform as spider
if (keepBeeOnPlatform) {
bee.x = originalBeeX;
bee.y = originalBeeY;
bee.onGround = true;
bee.velocityY = 0;
bee.isJumping = false;
}
}
});
};
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
self.defeated = true;
}
};
self.attack = function () {
return self.attackDamage;
};
return self;
});
var Wasp = Container.expand(function () {
var self = Container.call(this);
var waspGraphic = self.attachAsset('wasp', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFF6600,
scaleX: 1.2,
scaleY: 1.2
});
self.baseMaxHealth = 700 + Math.floor(Math.random() * 5301); // 700-6000
self.maxHealth = self.baseMaxHealth;
self.health = self.maxHealth;
self.attackDamage = 35 + Math.floor(Math.random() * 21); // 35-55
self.defeated = false;
self.currentPlatform = null;
self.moving = false;
self.encounteredByPlayer = false;
self.hasSpawnedHornet = false;
self.isWasp = true;
self.moveAwayFromBee = function (bee) {
if (self.moving || self.defeated) return;
self.moving = true;
var originalBeeY = bee.y;
var originalBeeX = bee.x;
var isOnSamePlatform = bee.onGround && Math.abs(bee.x - self.x) < self.currentPlatform.width * 0.8;
var keepBeeOnPlatform = isOnSamePlatform;
var nearbyPlatforms = [];
for (var i = 0; i < platforms.length; i++) {
if (platforms[i] !== self.currentPlatform && Math.abs(platforms[i].x - self.x) < 800) {
nearbyPlatforms.push(platforms[i]);
}
}
if (nearbyPlatforms.length === 0) {
self.moving = false;
return;
}
nearbyPlatforms.sort(function (a, b) {
var distA = Math.abs(a.x - bee.x);
var distB = Math.abs(b.x - bee.x);
return distB - distA;
});
var targetPlatform = nearbyPlatforms[0];
var targetX = targetPlatform.x;
var targetY = targetPlatform.y - targetPlatform.height / 2 - self.height / 2;
tween(self, {
x: targetX,
y: targetY
}, {
duration: 500,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
self.currentPlatform = targetPlatform;
self.moving = false;
if (keepBeeOnPlatform) {
bee.x = originalBeeX;
bee.y = originalBeeY;
bee.onGround = true;
bee.velocityY = 0;
bee.isJumping = false;
}
}
});
};
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 500 && !self.hasSpawnedHornet && Math.random() < 0.4) {
var newHornet = new Hornet();
newHornet.x = self.x + 80;
newHornet.y = self.y;
newHornet.currentPlatform = self.currentPlatform;
spiders.push(newHornet);
game.addChild(newHornet);
self.hasSpawnedHornet = true;
}
if (self.health <= 0) {
self.health = 0;
self.defeated = true;
}
};
self.attack = function () {
return self.attackDamage;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue background
});
/****
* Game Code
****/
// Show dialog to buy extra bee from neighbor hive
// --- Bee Wars: Assets for neighbor hives and extra bees ---
// Replace id with actual asset id if available
// Replace id with actual asset id if available
// Custom background images
// --- Nouveaux sons pour animations ---
function showNeighborHiveDialog(hive) {
// Only allow up to 6 extra bees (check current stock, not total purchased)
if (extraBees.length >= 6) {
// Show message: max bees reached
var maxPanel = new Container();
maxPanel.x = 2048 / 2;
maxPanel.y = 2732 / 2;
var bg = LK.getAsset('battlePanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.3,
alpha: 0.98
});
maxPanel.addChild(bg);
var txt = new Text2("Nombre maximum d'abeilles en stock atteint !", {
size: 50,
fill: 0x000000
});
txt.anchor.set(0.5, 0.5);
txt.x = 0;
txt.y = 0;
maxPanel.addChild(txt);
LK.gui.addChild(maxPanel);
LK.setTimeout(function () {
if (maxPanel.parent) maxPanel.parent.removeChild(maxPanel);
}, 1200);
return;
}
// Show confirmation dialog
var panel = new Container();
panel.x = 2048 / 2;
panel.y = 2732 / 2;
var bg = LK.getAsset('battlePanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.4,
alpha: 0.98
});
panel.addChild(bg);
var txt = new Text2("Acheter une abeille supplémentaire pour 50 ML ?\nStock actuel: " + extraBees.length + "/6", {
size: 48,
fill: 0x000000
});
txt.anchor.set(0.5, 0.5);
txt.x = 0;
txt.y = -60;
panel.addChild(txt);
// Oui button
var yesBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
x: -120,
y: 60,
tint: 0xFFBB00
});
var yesText = new Text2("Oui", {
size: 40,
fill: 0xFFFFFF
});
yesText.anchor.set(0.5, 0.5);
yesText.x = -120;
yesText.y = 60;
panel.addChild(yesBtn);
panel.addChild(yesText);
// Non button
var noBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
x: 120,
y: 60,
tint: 0x00AA00
});
var noText = new Text2("Non", {
size: 40,
fill: 0xFFFFFF
});
noText.anchor.set(0.5, 0.5);
noText.x = 120;
noText.y = 60;
panel.addChild(noBtn);
panel.addChild(noText);
LK.gui.addChild(panel);
// Oui handler
yesBtn.interactive = true;
yesBtn.down = function (xx, yy, obj2) {
if (ml >= 50) {
ml -= 50;
storage.ml = ml;
if (mlText) mlText.setText("ML: " + ml);
// Add extra bee
var newBee = new ExtraBee();
// Place it behind the last bee in the queue
var lastBee = beeQueue[beeQueue.length - 1];
newBee.x = lastBee.x - 60;
newBee.y = lastBee.y + 40;
newBee.isActive = false;
newBee.maxHealth = bee.maxHealth;
newBee.health = newBee.maxHealth;
newBee.followTarget = lastBee;
newBee._index = beeQueue.length;
extraBees.push(newBee);
beeQueue.push(newBee);
game.addChild(newBee);
// Store in persistent storage for tracking total purchased
if (typeof storage.totalBeesPurchased === "undefined") {
storage.totalBeesPurchased = 0;
}
storage.totalBeesPurchased++;
// Remove hive from game
if (hive && hive.parent) hive.parent.removeChild(hive);
var idx = neighborHives.indexOf(hive);
if (idx >= 0) neighborHives.splice(idx, 1);
// Update dialog message to show current stock
txt.setText("Abeille achetée ! Stock: " + extraBees.length + "/6");
LK.setTimeout(function () {
if (panel.parent) panel.parent.removeChild(panel);
}, 1200);
} else {
txt.setText("Pas assez de ML !");
LK.setTimeout(function () {
if (panel.parent) panel.parent.removeChild(panel);
}, 1000);
}
};
// Non handler
noBtn.interactive = true;
noBtn.down = function (xx, yy, obj2) {
if (panel.parent) panel.parent.removeChild(panel);
};
}
var neighborHives = [];
var extraBees = [];
var beeQueue = [];
var neighborHiveTimer = null;
// Initialize bee asset
// Initialize spider assets
// Initialize platform assets
// Initialize finish line
// Initialize battle UI elements
// Initialize sounds
// Initialize music
var currentLevel = storage.currentLevel || 1;
var maxLevels = 17500;
var gameState = "platform"; // "platform" or "battle"
var platforms = [];
var spiders = [];
var finishLine;
var bee;
var battleUI;
var controlsUI;
var levelText;
var spidersDefeatedText; // Text element for displaying spiders defeated count
var dragTarget = null; // Track if the bee is being dragged
var levelScrolling = false; // Whether the platforms are moving
var scrollSpeed = -3; // Horizontal scroll speed
var platformGenerationTimer = null; // Timer for platform generation
var spiderGenerationTimer = null; // Timer for spider generation
var lastPlatformX = 0; // Track last platform position for generation
// ML (monnaie du jeu) system
var ml = typeof storage.ml === "number" ? storage.ml : 0;
var mlText = null;
var platformsPassed = 0;
var platformsPassedSinceLastML = 0;
var lastBeePlatform = null;
var boutiqueButton = null;
var boutiquePanel = null;
var boutiqueItems = [];
var boutiqueOpen = false;
// Battle state
game.battleState = {
currentSpider: null,
isPlayerTurn: true,
turnDelay: 1000 // ms
};
// Initialize level
function initLevel(level) {
// Reset level scrolling
levelScrolling = false;
if (platformGenerationTimer) {
LK.clearInterval(platformGenerationTimer);
platformGenerationTimer = null;
}
if (spiderGenerationTimer) {
LK.clearInterval(spiderGenerationTimer);
spiderGenerationTimer = null;
}
// Clear existing elements
platforms = [];
spiders = [];
// Remove neighbor hives and extra bees
if (!neighborHives) neighborHives = [];
for (var i = 0; i < neighborHives.length; i++) {
if (neighborHives[i].parent) neighborHives[i].parent.removeChild(neighborHives[i]);
}
neighborHives = [];
if (!extraBees) extraBees = [];
for (var i = 0; i < extraBees.length; i++) {
if (extraBees[i].parent) extraBees[i].parent.removeChild(extraBees[i]);
}
extraBees = [];
beeQueue = [];
if (neighborHiveTimer) {
LK.clearInterval(neighborHiveTimer);
neighborHiveTimer = null;
}
// Remove old elements from game
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
// --- Bee Wars: Custom background system ---
if (typeof storage.selectedBg === "undefined") {
storage.selectedBg = "default";
}
var bgAssetId = null;
if (storage.selectedBg === "hive") bgAssetId = "bg_hive";else if (storage.selectedBg === "campagne") bgAssetId = "bg_campagne";else if (storage.selectedBg === "roche") bgAssetId = "bg_roche";else if (storage.selectedBg === "nid") bgAssetId = "bg_nid";else if (storage.selectedBg === "mais") bgAssetId = "bg_mais";else if (storage.selectedBg === "foret") bgAssetId = "bg_foret";else if (storage.selectedBg === "muguet") bgAssetId = "bg_muguet";else if (storage.selectedBg === "roses") bgAssetId = "bg_roses";else if (storage.selectedBg === "prairie") bgAssetId = "bg_prairie";else if (storage.selectedBg === "orties") bgAssetId = "bg_orties";
if (bgAssetId) {
var bgImg = LK.getAsset(bgAssetId, {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
scaleX: 2048 / 2048,
scaleY: 2732 / 2732
});
game.addChild(bgImg);
}
// Create bee
bee = new Bee();
bee.x = 150;
// Update bee's max health based on level (50 more health per level)
bee.maxHealth = bee.baseMaxHealth + (level - 1) * 50;
bee.health = bee.maxHealth;
// Réinitialise le compteur d'utilisations de Revitaliser à chaque niveau
bee.healUses = 0;
// --- Bee Wars: Setup beeQueue and extra bees ---
bee.isActive = true;
beeQueue = [bee];
extraBees = [];
// Create first platform to ensure bee starts on a platform
var firstPlatform = new Platform();
firstPlatform.x = 200;
firstPlatform.y = 2732 / 2 + 100;
platforms.push(firstPlatform);
game.addChild(firstPlatform);
// Position bee on first platform
bee.x = firstPlatform.x;
bee.y = firstPlatform.y - firstPlatform.height / 2 - bee.height / 2;
bee.onGround = true;
game.addChild(bee);
// Create platforms based on level
var platformCount = 5 + level;
var platformWidth = 400;
var platformHeight = 30;
var minPlatformY = 500;
var maxPlatformY = 2732 - 500;
var platformSpacing = 2048 / platformCount;
for (var i = 0; i < platformCount; i++) {
var platform = new Platform();
platform.x = i * platformSpacing + platformSpacing / 2;
platform.y = minPlatformY + Math.random() * (maxPlatformY - minPlatformY);
platforms.push(platform);
game.addChild(platform);
}
// Create spiders based on level
var spiderCount = level;
for (var i = 0; i < spiderCount; i++) {
// Determine enemy type based on level and random chance
var enemy;
if (level >= 5000 && Math.random() < 0.15) {
enemy = new Bird();
} else if (level >= 750 && Math.random() < 0.12) {
enemy = new Dragonfly();
} else if (level >= 444 && Math.random() < 0.10) {
enemy = new Wasp();
} else if (level >= 100 && Math.random() < 0.08) {
enemy = new Hornet();
} else {
// Regular spider logic
var isEndOfLevel = i === spiderCount - 1;
var isLowHealth = level > 2 && Math.random() < 0.25;
var makeDividing = (isEndOfLevel || isLowHealth) && Math.random() < 0.7;
if (makeDividing) {
enemy = new DividingSpider();
} else {
enemy = new Spider();
}
}
var spider = enemy;
// Update spider's max health based on level (20 more health per level) - but only for regular spiders
if (!spider.isHornet && !spider.isWasp && !spider.isDragonfly && !spider.isBird) {
spider.maxHealth = spider.baseMaxHealth + (level - 1) * 20;
spider.health = spider.maxHealth;
}
// Position spiders on platforms, starting from the second platform
var platformIndex = Math.floor((i + 1) * (platformCount - 1) / spiderCount);
spider.x = platforms[platformIndex].x;
spider.y = platforms[platformIndex].y - platforms[platformIndex].height / 2 - spider.height / 2;
spider.currentPlatform = platforms[platformIndex];
spiders.push(spider);
game.addChild(spider);
}
// Create finish line
finishLine = new FinishLine();
finishLine.x = 2048 - 100;
finishLine.y = platforms[platformCount - 1].y - platforms[platformCount - 1].height / 2 - finishLine.height / 2;
game.addChild(finishLine);
// --- Bee Wars: Randomly spawn neighbor hives on platforms ---
for (var i = 1; i < platforms.length - 1; i++) {
// 25% chance to spawn a neighbor hive on this platform
if (Math.random() < 0.25) {
var hive = new NeighborHive();
hive.x = platforms[i].x;
hive.y = platforms[i].y - platforms[i].height / 2 - hive.height / 2;
hive.platform = platforms[i];
neighborHives.push(hive);
game.addChild(hive);
}
}
// Create controls UI
controlsUI = new ControlsUI();
controlsUI.x = 2048 / 2;
controlsUI.y = 2732 - 150;
LK.gui.addChild(controlsUI);
// Set up controls
controlsUI.onLeftPressed = function () {
bee.moveLeft();
};
controlsUI.onRightPressed = function () {
bee.moveRight();
};
controlsUI.onJumpPressed = function () {
bee.jump();
};
controlsUI.onUpPressed = function () {
bee.moveUp();
};
controlsUI.onControlsReleased = function () {
bee.stopMoving();
};
// Create spiders defeated counter
spidersDefeated = 0;
spidersDefeatedText = new Text2("Spiders: 0", {
size: 40,
fill: 0xFFFFFF
});
spidersDefeatedText.anchor.set(0, 0);
spidersDefeatedText.x = 50;
spidersDefeatedText.y = 100;
LK.gui.topLeft.addChild(spidersDefeatedText);
// Always reset spidersDefeated to 0 at the start of each level
spidersDefeated = 0;
spidersDefeatedText.setText("Spiders: " + spidersDefeated);
// Reset platform counters for ML
platformsPassed = 0;
platformsPassedSinceLastML = 0;
lastBeePlatform = null;
// Remove previous levelText if it exists
if (levelText && levelText.parent) {
levelText.parent.removeChild(levelText);
}
levelText = null;
// Remove previous spidersDefeatedText if it exists
if (spidersDefeatedText && spidersDefeatedText.parent) {
spidersDefeatedText.parent.removeChild(spidersDefeatedText);
}
spidersDefeatedText = null;
// Remove previous ML text if it exists
if (mlText && mlText.parent) {
mlText.parent.removeChild(mlText);
}
mlText = null;
// Remove previous boutique button/panel if they exist
if (boutiqueButton && boutiqueButton.parent) {
boutiqueButton.parent.removeChild(boutiqueButton);
}
boutiqueButton = null;
if (boutiquePanel && boutiquePanel.parent) {
boutiquePanel.parent.removeChild(boutiquePanel);
}
boutiquePanel = null;
boutiqueOpen = false;
// Create level display text
levelText = new Text2("Niveau : " + currentLevel + " / " + maxLevels, {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
// Create spiders defeated counter
spidersDefeatedText = new Text2("Spiders: " + spidersDefeated, {
size: 40,
fill: 0xFFFFFF
});
spidersDefeatedText.anchor.set(0, 0);
spidersDefeatedText.x = 50;
spidersDefeatedText.y = 100;
LK.gui.topLeft.addChild(spidersDefeatedText);
// ML counter (just below the level banner, left-aligned to levelText)
mlText = new Text2("ML: " + ml, {
size: 40,
fill: 0x000000
});
mlText.anchor.set(0.5, 0);
mlText.x = levelText.x;
mlText.y = levelText.y + levelText.height + 10;
LK.gui.top.addChild(mlText);
// Boutique button (just below ML counter, left-aligned to levelText)
boutiqueButton = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.0,
scaleX: 0.4,
scaleY: 0.4,
x: levelText.x,
y: mlText.y + mlText.height + 10,
tint: 0xffffff
});
var boutiqueBtnText = new Text2("Boutique", {
size: 30,
fill: 0x000000
});
boutiqueBtnText.anchor.set(0.5, 0.5);
boutiqueBtnText.x = levelText.x;
boutiqueBtnText.y = boutiqueButton.y + boutiqueButton.height * boutiqueButton.scaleY / 2;
LK.gui.top.addChild(boutiqueButton);
LK.gui.top.addChild(boutiqueBtnText);
// --- Bee Wars: Add blue settings button for background customization ---
var settingsButton = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.0,
scaleX: 0.4,
scaleY: 0.4,
x: levelText.x,
y: boutiqueButton.y + boutiqueButton.height * boutiqueButton.scaleY + 10,
tint: 0x3399FF
});
var settingsBtnText = new Text2("ParamĂštres", {
size: 30,
fill: 0xffffff
});
settingsBtnText.anchor.set(0.5, 0.5);
settingsBtnText.x = levelText.x;
settingsBtnText.y = settingsButton.y + settingsButton.height * settingsButton.scaleY / 2;
LK.gui.top.addChild(settingsButton);
LK.gui.top.addChild(settingsBtnText);
// Handler for settings button to show background selection
settingsButton.interactive = true;
settingsButton.down = function (x, y, obj) {
// Show background selection dialog
if (typeof window._bgPanel !== "undefined" && window._bgPanel && window._bgPanel.parent) {
// Already open
return;
}
var bgPanel = new Container();
window._bgPanel = bgPanel;
bgPanel.x = 2048 / 2;
bgPanel.y = 2732 / 2;
var bg = LK.getAsset('battlePanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.9,
alpha: 0.97
});
bgPanel.addChild(bg);
// Create scrollable content container
var scrollContainer = new Container();
bgPanel.addChild(scrollContainer);
var title = new Text2("Choisis ton fond :", {
size: 60,
fill: 0x000000
});
title.anchor.set(0.5, 0);
title.y = -bg.height * 0.4;
scrollContainer.addChild(title);
// List of backgrounds
var bgs = [{
key: "hive",
label: "Ruche",
price: 30,
asset: "bg_hive"
}, {
key: "campagne",
label: "Campagnes",
price: 60,
asset: "bg_campagne"
}, {
key: "roche",
label: "Roche",
price: 86,
asset: "bg_roche"
}, {
key: "nid",
label: "Nid des araignées",
price: 100,
asset: "bg_nid"
}, {
key: "mais",
label: "MaĂŻs",
price: 125,
asset: "bg_mais"
}, {
key: "foret",
label: "ForĂȘt enchantĂ©e",
price: 185,
asset: "bg_foret"
}, {
key: "muguet",
label: "Muguet",
price: 200,
asset: "bg_muguet"
}, {
key: "roses",
label: "Roses épineuses",
price: 170,
asset: "bg_roses"
}, {
key: "prairie",
label: "Prairie manga",
price: 220,
asset: "bg_prairie"
}, {
key: "orties",
label: "Orties",
price: 240,
asset: "bg_orties"
}];
var yStart = -bg.height * 0.25;
var scrollY = 0;
var maxScrollY = Math.max(0, bgs.length * 120 - bg.height * 0.6);
for (var i = 0; i < bgs.length; i++) {
(function (idx) {
var bgItem = bgs[idx];
var y = yStart + idx * 120;
var btn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.5,
x: 0,
y: y,
tint: 0xeeeeee
});
var txt = new Text2(bgItem.label + " (" + bgItem.price + " ML)", {
size: 40,
fill: 0x000000
});
txt.anchor.set(0.5, 0.5);
txt.x = 0;
txt.y = y;
var selectBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.4,
x: 350,
y: y,
tint: 0x3399FF
});
var selectTxt = new Text2("Celui-ci", {
size: 30,
fill: 0xffffff
});
selectTxt.anchor.set(0.5, 0.5);
selectTxt.x = 350;
selectTxt.y = y;
scrollContainer.addChild(btn);
scrollContainer.addChild(txt);
scrollContainer.addChild(selectBtn);
scrollContainer.addChild(selectTxt);
selectBtn.interactive = true;
selectBtn.down = function (xx, yy, obj2) {
// If already selected, just close
if (storage.selectedBg === bgItem.key) {
if (bgPanel.parent) bgPanel.parent.removeChild(bgPanel);
window._bgPanel = null;
return;
}
// Check if player has enough ML
if (ml < bgItem.price) {
title.setText("Pas assez de ML !");
return;
}
// Deduct ML and set background
ml -= bgItem.price;
storage.ml = ml;
if (mlText) mlText.setText("ML: " + ml);
storage.selectedBg = bgItem.key;
// Show confirmation
title.setText("Fond changé !");
// Remove panel and re-init level after short delay
LK.setTimeout(function () {
if (bgPanel.parent) bgPanel.parent.removeChild(bgPanel);
window._bgPanel = null;
initLevel(currentLevel);
}, 700);
};
})(i);
}
// Scroll up button
var scrollUpBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
x: 300,
y: -bg.height * 0.35,
tint: 0x00AA00
});
var scrollUpTxt = new Text2("â", {
size: 40,
fill: 0xffffff
});
scrollUpTxt.anchor.set(0.5, 0.5);
scrollUpTxt.x = 300;
scrollUpTxt.y = -bg.height * 0.35;
bgPanel.addChild(scrollUpBtn);
bgPanel.addChild(scrollUpTxt);
// Scroll down button
var scrollDownBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
x: 300,
y: bg.height * 0.35,
tint: 0x00AA00
});
var scrollDownTxt = new Text2("â", {
size: 40,
fill: 0xffffff
});
scrollDownTxt.anchor.set(0.5, 0.5);
scrollDownTxt.x = 300;
scrollDownTxt.y = bg.height * 0.35;
bgPanel.addChild(scrollDownBtn);
bgPanel.addChild(scrollDownTxt);
// Scroll button handlers
scrollUpBtn.interactive = true;
scrollUpBtn.down = function (xx, yy, obj2) {
if (scrollY > 0) {
scrollY = Math.max(0, scrollY - 120);
scrollContainer.y = scrollY;
}
};
scrollDownBtn.interactive = true;
scrollDownBtn.down = function (xx, yy, obj2) {
if (scrollY < maxScrollY) {
scrollY = Math.min(maxScrollY, scrollY + 120);
scrollContainer.y = -scrollY;
}
};
// Close button
var closeBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
x: 0,
y: bg.height * 0.4,
tint: 0x000000
});
var closeTxt = new Text2("Fermer", {
size: 35,
fill: 0xffffff
});
closeTxt.anchor.set(0.5, 0.5);
closeTxt.x = 0;
closeTxt.y = bg.height * 0.4;
bgPanel.addChild(closeBtn);
bgPanel.addChild(closeTxt);
closeBtn.interactive = true;
closeBtn.down = function (xx, yy, obj2) {
if (bgPanel.parent) bgPanel.parent.removeChild(bgPanel);
window._bgPanel = null;
};
LK.gui.addChild(bgPanel);
};
// (reset button supprimé)
// Boutique button handler
boutiqueButton.interactive = true;
boutiqueButton.down = function (x, y, obj) {
if (boutiqueOpen) {
// Hide boutique
if (boutiquePanel && boutiquePanel.parent) {
boutiquePanel.parent.removeChild(boutiquePanel);
}
boutiquePanel = null;
boutiqueOpen = false;
return;
}
// Show boutique
if (boutiquePanel && boutiquePanel.parent) {
boutiquePanel.parent.removeChild(boutiquePanel);
}
boutiquePanel = new Container();
boutiquePanel.x = 2048 / 2;
boutiquePanel.y = 2732 / 2;
// Background
var bg = LK.getAsset('battlePanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7,
alpha: 0.95
});
boutiquePanel.addChild(bg);
// Title
var title = new Text2("Boutique", {
size: 70,
fill: 0x000000
});
title.anchor.set(0.5, 0);
title.y = -bg.height * 0.3 + 40;
boutiquePanel.addChild(title);
// Items
var items = [{
label: "30 points de vie",
price: 2,
heal: 30,
percent: 0
}, {
label: "50 points de vie",
price: 3,
heal: 50,
percent: 0
}, {
label: "Récupérer 10% de vie",
price: 6,
heal: 0,
percent: 0.10
}, {
label: "Récupérer 20% de vie",
price: 10,
heal: 0,
percent: 0.20
}, {
label: "Récupérer 30% de vie",
price: 12,
heal: 0,
percent: 0.30
}];
boutiqueItems = [];
for (var i = 0; i < items.length; i++) {
(function (idx) {
var item = items[idx];
var y = -bg.height * 0.15 + idx * 120;
var btn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.5,
x: 0,
y: y,
tint: 0xffffff
});
var txt = new Text2(item.label + " (" + item.price + " ML)", {
size: 40,
fill: 0x000000
});
txt.anchor.set(0.5, 0.5);
txt.x = 0;
txt.y = y;
boutiquePanel.addChild(btn);
boutiquePanel.addChild(txt);
btn.interactive = true;
btn.down = function (xx, yy, obj2) {
// Check ML
if (ml < item.price) {
title.setText("Pas assez de ML !");
return;
}
// Heal logic
var healAmount = item.heal;
if (item.percent > 0) {
healAmount = Math.floor(bee.maxHealth * item.percent);
}
if (healAmount > 0) {
bee.heal(healAmount);
}
// Deduct ML
ml -= item.price;
if (ml < 0) ml = 0;
storage.ml = ml;
if (mlText) mlText.setText("ML: " + ml);
title.setText("Achat réussi !");
// Hide boutique after purchase
LK.setTimeout(function () {
if (boutiquePanel && boutiquePanel.parent) {
boutiquePanel.parent.removeChild(boutiquePanel);
}
boutiquePanel = null;
boutiqueOpen = false;
}, 700);
};
boutiqueItems.push(btn);
})(i);
}
// Close button
var closeBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
x: 0,
y: bg.height * 0.3 - 60,
tint: 0x000000
});
var closeTxt = new Text2("Fermer", {
size: 35,
fill: 0xffffff
});
closeTxt.anchor.set(0.5, 0.5);
closeTxt.x = 0;
closeTxt.y = bg.height * 0.3 - 60;
boutiquePanel.addChild(closeBtn);
boutiquePanel.addChild(closeTxt);
closeBtn.interactive = true;
closeBtn.down = function (xx, yy, obj2) {
if (boutiquePanel && boutiquePanel.parent) {
boutiquePanel.parent.removeChild(boutiquePanel);
}
boutiquePanel = null;
boutiqueOpen = false;
};
LK.gui.addChild(boutiquePanel);
boutiqueOpen = true;
};
// Reset spiders defeated counter for this level
spidersDefeated = 0;
// Create score display
scoreText = new Text2("Score: " + LK.getScore(), {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
scoreText.x = -50;
LK.gui.topRight.addChild(scoreText);
// Set game state
gameState = "platform";
// Play background music
LK.playMusic('gameMusic');
}
// Start battle with a spider
function startBattle(spider) {
// Check if already in battle mode - prevent multiple battles at once
if (gameState === "battle") {
return;
}
// Store bee's position and ground state before battle
var originalBeeX = bee.x;
var originalBeeY = bee.y;
var originalOnGround = bee.onGround;
gameState = "battle";
game.battleState.currentSpider = spider;
// Mark spider as encountered by player
spider.encounteredByPlayer = true;
game.battleState.isPlayerTurn = true;
// Keep bee in place by setting velocities to zero
bee.velocityX = 0;
bee.velocityY = 0;
// Create battle UI
battleUI = new BattleUI();
battleUI.x = 2048 / 2;
battleUI.y = 2732 / 2;
battleUI.updateHealth(bee.health, bee.maxHealth, spider.health, spider.maxHealth);
battleUI.setTurnText(true);
game.addChild(battleUI);
// --- Ajout du bouton Revitaliser ---
if (typeof bee.healUses === "undefined") bee.healUses = 0;
bee.healUses = 0; // Reset heal uses at start of each battle
// Crée le bouton bleu "Revitaliser" sous le bouton d'attaque
var healBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 320,
tint: 0x3399FF
});
battleUI.addChild(healBtn);
var healText = new Text2("Revitaliser", {
size: 40,
fill: 0xFFFFFF
});
healText.anchor.set(0.5, 0.5);
healText.x = 0;
healText.y = 320;
battleUI.addChild(healText);
// Affichage du nombre d'utilisations restantes
var healUsesText = new Text2("3 utilisations restantes", {
size: 30,
fill: 0xFFFFFF
});
healUsesText.anchor.set(0.5, 0.5);
healUsesText.x = 0;
healUsesText.y = 370;
battleUI.addChild(healUsesText);
// Handler pour le bouton Revitaliser
healBtn.interactive = true;
healBtn.down = function (x, y, obj) {
// Conditions pour pouvoir se soigner
var canHeal = false;
var spidersRequired = currentLevel < 3 ? 3 : 6;
if (spidersDefeated >= spidersRequired && bee.healUses < 3 && game.battleState.isPlayerTurn) {
canHeal = true;
}
if (canHeal) {
var healAmount = Math.floor(bee.maxHealth * 0.2);
bee.heal(healAmount);
bee.healUses++;
battleUI.updateHealth(bee.health, bee.maxHealth, game.battleState.currentSpider.health, game.battleState.currentSpider.maxHealth);
// Feedback visuel
LK.effects.flashObject(bee, 0x00ccff, 300);
}
// Met Ă jour le texte d'utilisation
var usesLeft = 3 - bee.healUses;
healUsesText.setText(usesLeft + " utilisation" + (usesLeft === 1 ? "" : "s") + " restante" + (usesLeft > 1 ? "s" : ""));
// Message si non autorisé
if (!canHeal && game.battleState.isPlayerTurn) {
if (bee.healUses >= 3) {
healUsesText.setText("Limite atteinte ce niveau");
} else if (spidersDefeated < spidersRequired) {
healUsesText.setText("Vaincs " + spidersRequired + " araignées pour te soigner");
}
}
};
// Set up attack button handler
battleUI.onAttackPressed = function () {
if (game.battleState.isPlayerTurn) {
playerAttack();
}
};
// Store original position and state in battle state for recovery after battle
game.battleState.originalBeeX = originalBeeX;
game.battleState.originalBeeY = originalBeeY;
game.battleState.originalOnGround = originalOnGround;
}
// --- Mini-quizz et bonus de dégùts ---
// Variables globales pour le quizz et le bonus
if (typeof window.quizState === "undefined") {
window.quizState = {
spidersSinceLastQuiz: 0,
bonusActive: false,
bonusSpidersLeft: 0
};
}
// Liste de questions/choix/réponses (exemples, à étendre)
var quizQuestions = [{
question: "Combien de pattes a une araignée ?",
choices: ["6", "8", "10"],
answer: 1
}, {
question: "Combien de temps vit une abeille ouvriĂšre ?",
choices: ["Quelques semaines", "Plusieurs années", "Un jour"],
answer: 0
}, {
question: "Quel est le rĂŽle principal de la reine des abeilles ?",
choices: ["Butiner", "Pondre des Ćufs", "Tisser la toile"],
answer: 1
}, {
question: "Les abeilles fabriquent du miel Ă partir de :",
choices: ["Pollen", "Nectar", "Eau"],
answer: 1
}, {
question: "Les araignées sont-elles des insectes ?",
choices: ["Oui", "Non", "Seulement les petites"],
answer: 1
}, {
question: "Combien d'yeux ont la plupart des araignées ?",
choices: ["2", "8", "4"],
answer: 1
}, {
question: "Quel est l'aliment principal des abeilles ?",
choices: ["Miel", "Nectar", "Feuilles"],
answer: 1
}, {
question: "Comment s'appelle la maison des abeilles ?",
choices: ["Ruche", "Toile", "Nid"],
answer: 0
}, {
question: "Quel est le principal prédateur des abeilles ?",
choices: ["Ours", "AraignĂ©e", "GuĂȘpe"],
answer: 2
}, {
question: "Combien de reines y a-t-il dans une ruche ?",
choices: ["1", "10", "Aucune"],
answer: 0
}, {
question: "Les araignées tissent leur toile pour :",
choices: ["Dormir", "Attraper des proies", "Voler"],
answer: 1
}, {
question: "Quel est le rĂŽle des faux-bourdons dans la ruche ?",
choices: ["Butiner", "Fertiliser la reine", "Fabriquer du miel"],
answer: 1
}, {
question: "Les abeilles communiquent entre elles par :",
choices: ["Chant", "Danse", "Couleur"],
answer: 1
}, {
question: "Combien de temps vit une reine des abeilles ?",
choices: ["Quelques semaines", "Plusieurs années", "Un jour"],
answer: 1
}, {
question: "Les araignées peuvent-elles voler ?",
choices: ["Oui", "Non", "Seulement les petites"],
answer: 1
}, {
question: "Quel est le principal ingrédient du miel ?",
choices: ["Eau", "Nectar", "Pollen"],
answer: 1
}, {
question: "Les abeilles voient-elles les couleurs ?",
choices: ["Oui", "Non", "Seulement le rouge"],
answer: 0
}, {
question: "Combien d'ailes a une abeille ?",
choices: ["2", "4", "6"],
answer: 1
}, {
question: "Les araignées sont utiles car elles :",
choices: ["Pollinisent", "Mangent des insectes", "Font du miel"],
answer: 1
}, {
question: "Quel est le nom scientifique de l'abeille domestique ?",
choices: ["Apis mellifera", "Bombus terrestris", "Vespa crabro"],
answer: 0
}, {
question: "Les abeilles piquent-elles plusieurs fois ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 1
}, {
question: "Les araignées boivent-elles du sang ?",
choices: ["Oui", "Non", "Seulement certaines"],
answer: 1
}, {
question: "Combien de pattes a une abeille ?",
choices: ["4", "6", "8"],
answer: 1
}, {
question: "Les abeilles peuvent-elles voir les ultraviolets ?",
choices: ["Oui", "Non", "Seulement la nuit"],
answer: 0
}, {
question: "Les araignĂ©es pondent-elles des Ćufs ?",
choices: ["Oui", "Non", "Seulement les mĂąles"],
answer: 0
}, {
question: "Quel est le principal danger pour les abeilles ?",
choices: ["Froid", "Pesticides", "LumiĂšre"],
answer: 1
}, {
question: "Les abeilles fabriquent-elles la cire ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 0
}, {
question: "Les araignées ont-elles des antennes ?",
choices: ["Oui", "Non", "Seulement les bébés"],
answer: 1
}, {
question: "Combien de temps met une abeille pour fabriquer du miel ?",
choices: ["Quelques heures", "Plusieurs jours", "Un mois"],
answer: 1
}, {
question: "Les abeilles vivent-elles seules ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 1
}, {
question: "Les araignées peuvent-elles nager ?",
choices: ["Oui", "Non", "Seulement certaines"],
answer: 2
}, {
question: "Quel est le rĂŽle du pollen pour les abeilles ?",
choices: ["Nourriture", "Construire la ruche", "Attirer les prédateurs"],
answer: 0
}, {
question: "Les abeilles dorment-elles ?",
choices: ["Oui", "Non", "Seulement la nuit"],
answer: 0
}, {
question: "Les araignées sont-elles toutes venimeuses ?",
choices: ["Oui", "Non", "Seulement les grandes"],
answer: 1
}, {
question: "Combien de temps vit une araignée ?",
choices: ["Quelques jours", "Plusieurs mois", "Plusieurs années"],
answer: 2
}, {
question: "Les abeilles peuvent-elles voler sous la pluie ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 1
}, {
question: "Les araignées mangent-elles des abeilles ?",
choices: ["Oui", "Non", "Seulement les grandes"],
answer: 2
}, {
question: "Quel est le principal ennemi des araignées ?",
choices: ["Abeilles", "Oiseaux", "GuĂȘpes"],
answer: 1
}, {
question: "Les abeilles fabriquent-elles du miel en hiver ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 1
}, {
question: "Les araignées peuvent-elles changer de couleur ?",
choices: ["Oui", "Non", "Seulement certaines"],
answer: 2
}, {
question: "Combien de reines dans une ruche normale ?",
choices: ["1", "2", "Aucune"],
answer: 0
}, {
question: "Les abeilles peuvent-elles piquer plusieurs fois ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 1
}, {
question: "Les araignées ont-elles des ailes ?",
choices: ["Oui", "Non", "Seulement les mĂąles"],
answer: 1
}, {
question: "Quel est le rĂŽle du dard chez l'abeille ?",
choices: ["Butiner", "Se défendre", "Construire la ruche"],
answer: 1
}, {
question: "Les abeilles mangent-elles du miel ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 0
}, {
question: "Les araignées peuvent-elles vivre dans l'eau ?",
choices: ["Oui", "Non", "Seulement certaines"],
answer: 2
}, {
question: "Combien de temps vit une abeille reine ?",
choices: ["Quelques semaines", "Plusieurs années", "Un jour"],
answer: 1
}, {
question: "Les abeilles voient-elles la couleur rouge ?",
choices: ["Oui", "Non", "Seulement la nuit"],
answer: 1
}, {
question: "Les araignées sont-elles sourdes ?",
choices: ["Oui", "Non", "Seulement les petites"],
answer: 0
}, {
question: "Quel est le rĂŽle du nectar pour les abeilles ?",
choices: ["Nourriture", "Construire la ruche", "Attirer les prédateurs"],
answer: 0
}, {
question: "Les abeilles peuvent-elles vivre sans reine ?",
choices: ["Oui", "Non", "Seulement quelques jours"],
answer: 2
}, {
question: "Les araignées peuvent-elles sauter ?",
choices: ["Oui", "Non", "Seulement les grandes"],
answer: 0
}, {
question: "Combien de temps met une araignée pour tisser sa toile ?",
choices: ["Quelques minutes", "Plusieurs heures", "Un jour"],
answer: 0
}, {
question: "Les abeilles sont-elles toutes ouvriĂšres ?",
choices: ["Oui", "Non", "Seulement la nuit"],
answer: 1
}, {
question: "Les araignées mangent-elles des plantes ?",
choices: ["Oui", "Non", "Seulement les bébés"],
answer: 1
}, {
question: "Quel est le rĂŽle du pollen pour la ruche ?",
choices: ["Nourriture", "Construire la ruche", "Attirer les prédateurs"],
answer: 0
}, {
question: "Les abeilles peuvent-elles reconnaĂźtre les humains ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 0
}, {
question: "Les araignées peuvent-elles vivre dans le désert ?",
choices: ["Oui", "Non", "Seulement les grandes"],
answer: 0
}, {
question: "Combien de temps vit une abeille en hiver ?",
choices: ["Quelques semaines", "Plusieurs mois", "Un jour"],
answer: 1
}, {
question: "Les abeilles fabriquent-elles la gelée royale ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 0
}, {
question: "Les araignées peuvent-elles voir dans le noir ?",
choices: ["Oui", "Non", "Seulement certaines"],
answer: 2
}, {
question: "Quel est le principal ingrédient de la cire d'abeille ?",
choices: ["Nectar", "Pollen", "Sécrétion"],
answer: 2
}, {
question: "Les abeilles peuvent-elles voler la nuit ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 1
}, {
question: "Les araignées sont-elles toutes solitaires ?",
choices: ["Oui", "Non", "Seulement les grandes"],
answer: 1
}, {
question: "Combien de temps vit une abeille butineuse ?",
choices: ["Quelques semaines", "Plusieurs années", "Un jour"],
answer: 0
}, {
question: "Les abeilles mangent-elles du pollen ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 0
}, {
question: "Les araignées peuvent-elles vivre dans les arbres ?",
choices: ["Oui", "Non", "Seulement les grandes"],
answer: 0
}, {
question: "Quel est le rÎle de la gelée royale ?",
choices: ["Nourrir la reine", "Construire la ruche", "Attirer les prédateurs"],
answer: 0
}, {
question: "Les abeilles peuvent-elles reconnaĂźtre leur ruche ?",
choices: ["Oui", "Non", "Seulement la reine"],
answer: 0
}, {
question: "Les araignées peuvent-elles vivre sous terre ?",
choices: ["Oui", "Non", "Seulement les grandes"],
answer: 0
}, {
question: "Combien de cellules hexagonales une abeille peut-elle construire par jour ?",
choices: ["10", "100", "1000"],
answer: 1
}, {
question: "Les abeilles peuvent-elles reconnaĂźtre les visages humains ?",
choices: ["Oui", "Non", "Seulement les apiculteurs"],
answer: 0
}, {
question: "Quel est le principal composant de la propolis ?",
choices: ["Résine", "Miel", "Pollen"],
answer: 0
}, {
question: "Les araignées ont-elles du sang rouge ?",
choices: ["Oui", "Non", "Seulement les grandes"],
answer: 1
}, {
question: "Combien de fois par seconde les ailes d'une abeille battent-elles ?",
choices: ["50", "230", "500"],
answer: 1
}, {
question: "Les araignées peuvent-elles régénérer leurs pattes ?",
choices: ["Oui", "Non", "Seulement jeunes"],
answer: 0
}, {
question: "Quelle est la température idéale dans une ruche ?",
choices: ["25°C", "35°C", "45°C"],
answer: 1
}, {
question: "Les araignées peuvent-elles entendre ?",
choices: ["Oui", "Non", "Seulement les vibrations"],
answer: 2
}, {
question: "Combien de kilomÚtres une abeille peut-elle voler en une journée ?",
choices: ["50 km", "150 km", "300 km"],
answer: 1
}, {
question: "Les araignées muent-elles ?",
choices: ["Oui", "Non", "Seulement les mĂąles"],
answer: 0
}, {
question: "Quel pourcentage de plantes dépend de la pollinisation par les abeilles ?",
choices: ["30%", "50%", "80%"],
answer: 2
}, {
question: "Les araignées peuvent-elles survivre dans l'espace ?",
choices: ["Oui", "Non", "Quelques heures"],
answer: 1
}, {
question: "Combien d'Ćufs une reine peut-elle pondre par jour ?",
choices: ["100", "1000", "2000"],
answer: 2
}, {
question: "Les araignées sociales existent-elles ?",
choices: ["Oui", "Non", "Seulement en Amérique"],
answer: 0
}, {
question: "Ă quelle vitesse vole une abeille ?",
choices: ["15 km/h", "25 km/h", "40 km/h"],
answer: 1
}, {
question: "Les araignées peuvent-elles nager sous l'eau ?",
choices: ["Oui", "Non", "Seulement certaines espĂšces"],
answer: 2
}, {
question: "Combien de fleurs une abeille visite-t-elle par jour ?",
choices: ["100", "500", "2000"],
answer: 2
}, {
question: "Les araignées ont-elles des poumons ?",
choices: ["Oui", "Non", "Seulement les grandes"],
answer: 1
}, {
question: "Quelle est la durée de vie d'une ruche ?",
choices: ["1 an", "5 ans", "20 ans"],
answer: 2
}, {
question: "Les araignées peuvent-elles vomir ?",
choices: ["Oui", "Non", "Seulement malades"],
answer: 0
}, {
question: "Combien pĂšse une abeille ouvriĂšre ?",
choices: ["0.1 gramme", "0.5 gramme", "1 gramme"],
answer: 0
}, {
question: "Les araignées dorment-elles ?",
choices: ["Oui", "Non", "Ătat de repos"],
answer: 2
}, {
question: "Quel est le record de distance de vol d'une abeille ?",
choices: ["5 km", "10 km", "15 km"],
answer: 1
}, {
question: "Les araignées peuvent-elles sentir les odeurs ?",
choices: ["Oui", "Non", "Seulement les phéromones"],
answer: 0
}, {
question: "Combien de temps met le miel Ă cristalliser ?",
choices: ["1 semaine", "6 mois", "2 ans"],
answer: 1
}, {
question: "Les araignées peuvent-elles survivre au froid ?",
choices: ["Oui", "Non", "Avec antigel"],
answer: 2
}, {
question: "Ă quel Ăąge une abeille ouvriĂšre commence-t-elle Ă butiner ?",
choices: ["1 jour", "3 semaines", "2 mois"],
answer: 1
}, {
question: "Les araignées peuvent-elles changer de sexe ?",
choices: ["Oui", "Non", "Seulement certaines"],
answer: 1
}, {
question: "Combien de cellules contient un rayon de miel ?",
choices: ["1000", "25000", "100000"],
answer: 1
}, {
question: "Les araignĂ©es peuvent-elles vivre sans tĂȘte ?",
choices: ["Oui", "Non", "Quelques heures"],
answer: 2
}, {
question: "Quelle est la portée de communication des abeilles ?",
choices: ["10 mĂštres", "100 mĂštres", "1 kilomĂštre"],
answer: 2
}, {
question: "Les araignées peuvent-elles planer ?",
choices: ["Oui", "Non", "Avec balloning"],
answer: 2
}, {
question: "Combien de générations d'abeilles naissent par an ?",
choices: ["2", "6", "12"],
answer: 1
}, {
question: "Les araignées peuvent-elles manger leurs partenaires ?",
choices: ["Oui", "Non", "Seulement les femelles"],
answer: 2
}, {
question: "Quel est le pH du miel ?",
choices: ["Acide", "Neutre", "Basique"],
answer: 0
}, {
question: "Les araignées peuvent-elles tisser sous l'eau ?",
choices: ["Oui", "Non", "Seulement bulles d'air"],
answer: 2
}, {
question: "Combien de muscles contrĂŽlent les ailes d'une abeille ?",
choices: ["4", "75", "200"],
answer: 1
}, {
question: "Les araignées peuvent-elles voir les couleurs ?",
choices: ["Oui", "Non", "Seulement certaines"],
answer: 2
}, {
question: "à quelle température le miel devient-il toxique ?",
choices: ["60°C", "100°C", "Jamais"],
answer: 2
}, {
question: "Les araignées peuvent-elles survivre à la radioactivité ?",
choices: ["Oui", "Non", "Mieux que humains"],
answer: 2
}, {
question: "Combien de types de cellules une ruche contient-elle ?",
choices: ["2", "3", "5"],
answer: 1
}, {
question: "Les araignées peuvent-elles se camoufler ?",
choices: ["Oui", "Non", "Seulement mimétisme"],
answer: 0
}, {
question: "Quelle distance parcourt une abeille pour 1 kg de miel ?",
choices: ["40000 km", "80000 km", "120000 km"],
answer: 1
}, {
question: "Les araignées peuvent-elles pleurer ?",
choices: ["Oui", "Non", "Pas de larmes"],
answer: 2
}, {
question: "Combien de phéromones différentes une reine produit-elle ?",
choices: ["5", "20", "50"],
answer: 1
}, {
question: "Les araignées peuvent-elles vivre en groupe ?",
choices: ["Oui", "Non", "Rarement"],
answer: 2
}, {
question: "Ă quelle altitude maximale les abeilles peuvent-elles voler ?",
choices: ["1000m", "3000m", "5000m"],
answer: 1
}, {
question: "Les araignées peuvent-elles hiberner ?",
choices: ["Oui", "Non", "Diapause"],
answer: 2
}, {
question: "Combien de fois son poids une abeille peut-elle porter ?",
choices: ["0.5 fois", "1 fois", "2 fois"],
answer: 1
}, {
question: "Les araignĂ©es peuvent-elles ĂȘtre cannibales ?",
choices: ["Oui", "Non", "Seulement affamées"],
answer: 0
}, {
question: "Quelle est la vitesse de production du miel ?",
choices: ["1g/jour", "10g/jour", "100g/jour"],
answer: 1
}, {
question: "Les araignées peuvent-elles voler réellement ?",
choices: ["Oui", "Non", "Balloning seulement"],
answer: 2
}, {
question: "Combien de danses différentes les abeilles connaissent-elles ?",
choices: ["2", "8", "20"],
answer: 1
}, {
question: "Les araignées peuvent-elles survivre sous l'eau longtemps ?",
choices: ["Oui", "Non", "Avec bulles d'air"],
answer: 2
}, {
question: "à quelle fréquence vibrent les ailes d'une abeille ?",
choices: ["100 Hz", "230 Hz", "500 Hz"],
answer: 1
}, {
question: "Les araignĂ©es peuvent-elles ĂȘtre venimeuses ET vĂ©nĂ©neuses ?",
choices: ["Oui", "Non", "TrĂšs rarement"],
answer: 2
}, {
question: "Combien de sucre contient le nectar ?",
choices: ["10%", "30%", "70%"],
answer: 1
}, {
question: "Les araignées peuvent-elles régénérer leur cerveau ?",
choices: ["Oui", "Non", "Partiellement"],
answer: 1
}, {
question: "Quelle est la forme géométrique parfaite des cellules ?",
choices: ["Carré", "Hexagone", "Octogone"],
answer: 1
}, {
question: "Les araignées peuvent-elles survivre à l'espace ?",
choices: ["Oui", "Non", "Quelques minutes"],
answer: 1
}, {
question: "Combien d'antennes ont les abeilles ?",
choices: ["2", "4", "6"],
answer: 0
}, {
question: "Les araignĂ©es peuvent-elles ĂȘtre albinos ?",
choices: ["Oui", "Non", "TrĂšs rare"],
answer: 2
}, {
question: "à quelle température les abeilles ne volent plus ?",
choices: ["5°C", "10°C", "15°C"],
answer: 1
}, {
question: "Les araignées peuvent-elles chasser en groupe ?",
choices: ["Oui", "Non", "Certaines espĂšces"],
answer: 2
}, {
question: "Combien de pattes a une larve d'abeille ?",
choices: ["0", "3", "6"],
answer: 0
}, {
question: "Les araignées peuvent-elles survivre sans eau ?",
choices: ["Oui", "Non", "Longtemps"],
answer: 2
}, {
question: "Quelle est la consommation de miel d'une ruche en hiver ?",
choices: ["5 kg", "15 kg", "30 kg"],
answer: 1
}, {
question: "Les araignĂ©es peuvent-elles ĂȘtre gĂ©antes ?",
choices: ["Oui", "Non", "Préhistoire"],
answer: 2
}, {
question: "Combien pĂšse une reine des abeilles ?",
choices: ["0.2g", "0.5g", "1g"],
answer: 0
}, {
question: "Les araignĂ©es peuvent-elles ĂȘtre transparentes ?",
choices: ["Oui", "Non", "Certaines espĂšces"],
answer: 2
}, {
question: "Ă quelle distance les abeilles sentent-elles les fleurs ?",
choices: ["1m", "100m", "1km"],
answer: 1
}, {
question: "Les araignĂ©es peuvent-elles ĂȘtre immortelles ?",
choices: ["Oui", "Non", "Théoriquement"],
answer: 1
}, {
question: "Combien de rayons contient une ruche moyenne ?",
choices: ["5", "10", "20"],
answer: 1
}, {
question: "Les araignées peuvent-elles prédire le temps ?",
choices: ["Oui", "Non", "Comportement change"],
answer: 2
}, {
question: "Quel pourcentage d'eau contient le miel mûr ?",
choices: ["10%", "18%", "30%"],
answer: 1
}];
// Affiche le panneau de choix pour faire un quizz ou non
function showQuizChoicePanel(onYes, onNo) {
var panel = new Container();
panel.x = 2048 / 2;
panel.y = 2732 / 2;
var bg = LK.getAsset('battlePanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.5,
alpha: 0.97
});
panel.addChild(bg);
var txt = new Text2("Veux-tu tenter un mini-quizz pour un bonus de dégùts ?", {
size: 50,
fill: 0x000000
});
txt.anchor.set(0.5, 0.5);
txt.y = -80;
panel.addChild(txt);
// Oui
var yesBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
x: -180,
y: 80,
tint: 0x00bb00
});
var yesTxt = new Text2("Oui", {
size: 40,
fill: 0xffffff
});
yesTxt.anchor.set(0.5, 0.5);
yesTxt.x = -180;
yesTxt.y = 80;
panel.addChild(yesBtn);
panel.addChild(yesTxt);
// Non
var noBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
x: 180,
y: 80,
tint: 0xbb0000
});
var noTxt = new Text2("Non", {
size: 40,
fill: 0xffffff
});
noTxt.anchor.set(0.5, 0.5);
noTxt.x = 180;
noTxt.y = 80;
panel.addChild(noBtn);
panel.addChild(noTxt);
yesBtn.interactive = true;
yesBtn.down = function () {
if (panel.parent) panel.parent.removeChild(panel);
if (onYes) onYes();
};
noBtn.interactive = true;
noBtn.down = function () {
if (panel.parent) panel.parent.removeChild(panel);
if (onNo) onNo();
};
LK.gui.addChild(panel);
}
// Affiche le panneau de quizz
function showQuizPanel(onResult) {
// Choisit une question au hasard
var q = quizQuestions[Math.floor(Math.random() * quizQuestions.length)];
var panel = new Container();
panel.x = 2048 / 2;
panel.y = 2732 / 2;
var bg = LK.getAsset('battlePanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.7,
alpha: 0.97
});
panel.addChild(bg);
var txt = new Text2(q.question, {
size: 50,
fill: 0x000000
});
txt.anchor.set(0.5, 0.5);
txt.y = -180;
panel.addChild(txt);
// Affiche les choix
for (var i = 0; i < q.choices.length; i++) {
(function (idx) {
var btn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.5,
x: 0,
y: -40 + idx * 120,
tint: 0xeeeeee
});
var choiceTxt = new Text2(q.choices[idx], {
size: 40,
fill: 0x000000
});
choiceTxt.anchor.set(0.5, 0.5);
choiceTxt.x = 0;
choiceTxt.y = -40 + idx * 120;
panel.addChild(btn);
panel.addChild(choiceTxt);
btn.interactive = true;
btn.down = function () {
// Affiche résultat
if (idx === q.answer) {
txt.setText("Bonne réponse ! Bonus de dégùts activé !");
if (onResult) onResult(true);
} else {
txt.setText("Mauvaise réponse !");
if (onResult) onResult(false);
}
// Ferme le panneau aprĂšs 1s
LK.setTimeout(function () {
if (panel.parent) panel.parent.removeChild(panel);
}, 1000);
};
})(i);
}
LK.gui.addChild(panel);
}
// Remplace la fonction playerAttack par une version qui gĂšre le quizz et le bonus
function playerAttack() {
// Vérifie si on doit proposer un quizz
var spidersToQuiz = currentLevel < 10 ? 4 : 7;
if (!window.quizState) window.quizState = {
spidersSinceLastQuiz: 0,
bonusActive: false,
bonusSpidersLeft: 0
};
// Si le bonus est actif, on le décrémente
if (window.quizState.bonusActive) {
// On applique le bonus de dégùts
window.quizState.bonusSpidersLeft--;
if (window.quizState.bonusSpidersLeft <= 0) {
window.quizState.bonusActive = false;
}
}
// Si c'est le moment du quizz, on propose le choix
if (window.quizState.spidersSinceLastQuiz >= spidersToQuiz) {
showQuizChoicePanel(function () {
// Oui, on fait le quizz
showQuizPanel(function (isCorrect) {
if (isCorrect) {
window.quizState.bonusActive = true;
window.quizState.bonusSpidersLeft = 2;
}
window.quizState.spidersSinceLastQuiz = 0;
// AprĂšs le quizz, attaque normale
doPlayerAttack();
});
}, function () {
// Non, on attaque normalement
window.quizState.spidersSinceLastQuiz = 0;
doPlayerAttack();
});
return;
} else {
doPlayerAttack();
}
}
// Fonction d'attaque réelle du joueur (avec bonus si actif)
function doPlayerAttack() {
var baseDamage = 20 + Math.floor(Math.random() * 10); // 20-29
var damage = baseDamage;
if (window.quizState && window.quizState.bonusActive) {
damage = Math.floor(baseDamage * 1.2);
}
game.battleState.currentSpider.takeDamage(damage);
LK.getSound('attack').play();
// Update battle UI
battleUI.updateHealth(bee.health, bee.maxHealth, game.battleState.currentSpider.health, game.battleState.currentSpider.maxHealth);
// Flash effect on spider
LK.effects.flashObject(game.battleState.currentSpider, 0xFF0000, 300);
// Check if spider is defeated
if (game.battleState.currentSpider.defeated) {
// Incrémente le compteur d'araignées vaincues pour le quizz
if (window.quizState) window.quizState.spidersSinceLastQuiz++;
LK.setTimeout(function () {
endBattle(true);
}, 1000);
return;
}
// Switch turns
game.battleState.isPlayerTurn = false;
battleUI.setTurnText(false);
// Spider attacks after delay
LK.setTimeout(function () {
spiderAttack();
}, game.battleState.turnDelay);
}
// Spider attacks in battle
function spiderAttack() {
// Spider attack now deals random damage between 1 and 20
var damage = 1 + Math.floor(Math.random() * 20);
bee.takeDamage(damage);
LK.getSound('hurt').play();
// Update battle UI
battleUI.updateHealth(bee.health, bee.maxHealth, game.battleState.currentSpider.health, game.battleState.currentSpider.maxHealth);
// Flash effect on bee
LK.effects.flashObject(bee, 0xFF0000, 300);
// Check if bee is defeated
if (bee.health <= 0) {
LK.setTimeout(function () {
endBattle(false);
}, 1000);
return;
}
// Switch turns
game.battleState.isPlayerTurn = true;
battleUI.setTurnText(true);
}
// End battle
function endBattle(playerWon) {
// Remove battle UI
game.removeChild(battleUI);
if (playerWon) {
// Mark spider as defeated
game.battleState.currentSpider.defeated = true;
// Joue le son de coup de fusil
LK.getSound('gun').play();
// Make spider invisible
game.battleState.currentSpider.alpha = 0;
// Increase score
LK.setScore(LK.getScore() + 100);
scoreText.setText("Score: " + LK.getScore());
// Only increment spiders defeated counter if the spider was properly encountered and defeated manually in battle
// Ensure only one spider is counted at a time
if (game.battleState.currentSpider.encounteredByPlayer && !game.battleState.currentSpider.countedAsDefeated) {
var spiderEquivalent = 1;
if (game.battleState.currentSpider.isHornet) spiderEquivalent = 10;else if (game.battleState.currentSpider.isWasp) spiderEquivalent = 20;else if (game.battleState.currentSpider.isDragonfly) spiderEquivalent = 30;else if (game.battleState.currentSpider.isBird) spiderEquivalent = 70;
spidersDefeated += spiderEquivalent;
game.battleState.currentSpider.countedAsDefeated = true;
spidersDefeatedText.setText("Spiders: " + spidersDefeated);
// Award ML based on enemy type
ml += spiderEquivalent;
storage.ml = ml;
if (mlText) mlText.setText("ML: " + ml);
// Incrémente le compteur d'araignées vaincues pour le quizz
if (window.quizState) window.quizState.spidersSinceLastQuiz += spiderEquivalent;
}
// Bee ne récupÚre plus de points de vie automatiquement aprÚs victoire (sauf lors du passage de niveau ou revitaliser)
// (Bloc supprimé pour respecter la nouvelle rÚgle)
// Only allow one level up at a time and require progressive spider defeats
// Level 1: 5 spiders, Level 2: 10, Level 3: 20, Level 4: 40, Level 5: 80, etc. (doubles each level)
var spidersNeededForNextLevel = 5 * Math.pow(2, currentLevel - 1);
// Game now has 17500 levels
var maxLevels = 17500;
// Check if player is at max level and has defeated enough spiders
if (currentLevel >= maxLevels && spidersDefeated >= spidersNeededForNextLevel) {
// Display victory message
var victoryContainer = new Container();
victoryContainer.x = 2048 / 2;
victoryContainer.y = 2732 / 2;
var victoryBackground = LK.getAsset('battlePanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.9
});
victoryContainer.addChild(victoryBackground);
var victoryText = new Text2("Merci d'avoir joué a Bee Wars!\nFélicitations tu as compléter le jeu!\nA bientÎt pour de futures jeux de clem27games !", {
size: 80,
fill: 0xFF69B4 // Pink color
});
victoryText.anchor.set(0.5, 0.5);
victoryContainer.addChild(victoryText);
game.addChild(victoryContainer);
// Create OK button to reset game
var okButton = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 200,
tint: 0x00FF00
});
victoryContainer.addChild(okButton);
var okText = new Text2("OK", {
size: 60,
fill: 0xFFFFFF
});
okText.anchor.set(0.5, 0.5);
okText.x = 0;
okText.y = 200;
victoryContainer.addChild(okText);
// Add down handler to the container
victoryContainer.down = function (x, y, obj) {
// Check if OK button was pressed
if (x >= okButton.x - okButton.width / 2 && x <= okButton.x + okButton.width / 2 && y >= okButton.y - okButton.height / 2 && y <= okButton.y + okButton.height / 2) {
// Reset to level 1
currentLevel = 1;
storage.currentLevel = 1;
// Remove previous levelText if it exists
if (levelText && levelText.parent) {
levelText.parent.removeChild(levelText);
}
levelText = null;
// Remove previous spidersDefeatedText if it exists
if (spidersDefeatedText && spidersDefeatedText.parent) {
spidersDefeatedText.parent.removeChild(spidersDefeatedText);
}
spidersDefeatedText = null;
initLevel(currentLevel);
game.removeChild(victoryContainer);
}
};
return; // Exit function early
} else if (spidersDefeated >= spidersNeededForNextLevel && currentLevel < maxLevels) {
// Only allow a single level up at a time, even if player has defeated more spiders than needed
// Restore bee health before advancing to next level
bee.health = bee.maxHealth;
// Prevent skipping levels: only increment by 1, and reset spidersDefeated to 0
LK.setTimeout(function () {
currentLevel++;
storage.currentLevel = currentLevel;
// Reset spiders defeated for the new level
spidersDefeated = 0;
spidersDefeatedText.setText("Spiders: " + spidersDefeated);
// Update the level banner to show the new level
if (levelText) {
levelText.setText("Niveau : " + currentLevel + " / " + maxLevels);
}
initLevel(currentLevel);
}, 1000);
}
} else {
// --- Bee Wars: If main bee dies in battle, replace with extra bee if available ---
if (extraBees.length > 0) {
// Remove main bee from game
if (bee.parent) bee.parent.removeChild(bee);
// Promote first extra bee to main bee
var newBee = extraBees.shift();
beeQueue.shift();
newBee.isActive = true;
bee = newBee;
beeQueue[0] = bee;
// Set controls to new bee
controlsUI.onLeftPressed = function () {
bee.moveLeft();
};
controlsUI.onRightPressed = function () {
bee.moveRight();
};
controlsUI.onJumpPressed = function () {
bee.jump();
};
controlsUI.onUpPressed = function () {
bee.moveUp();
};
controlsUI.onControlsReleased = function () {
bee.stopMoving();
};
// Place new bee at last position
bee.x = game.battleState.originalBeeX;
bee.y = game.battleState.originalBeeY;
bee.velocityX = 0;
bee.velocityY = 0;
bee.onGround = true;
bee.fallingInVoid = false;
bee.alpha = 1.0;
// Defensive: update followTarget for remaining extra bees
for (var i = 0; i < extraBees.length; i++) {
extraBees[i].followTarget = beeQueue[i];
extraBees[i]._index = i;
}
// Add to game if not already
if (!bee.parent) game.addChild(bee);
// Return to platform mode
gameState = "platform";
return;
} else {
// Reset to level 1 on defeat
currentLevel = 1;
storage.currentLevel = 1;
// Remove previous levelText if it exists
if (levelText && levelText.parent) {
levelText.parent.removeChild(levelText);
}
levelText = null;
// Remove previous spidersDefeatedText if it exists
if (spidersDefeatedText && spidersDefeatedText.parent) {
spidersDefeatedText.parent.removeChild(spidersDefeatedText);
}
spidersDefeatedText = null;
initLevel(currentLevel);
// Game over if player lost
LK.showGameOver({
message: "L'araign\xE9e t'a vaincu, tu es morte, petite abeille\u202F!"
});
return;
}
}
// Restore bee's position and state from before the battle
bee.x = game.battleState.originalBeeX;
bee.y = game.battleState.originalBeeY;
bee.onGround = game.battleState.originalOnGround;
// Ensure bee doesn't fall by zeroing velocities
bee.velocityX = 0;
bee.velocityY = 0;
// Return to platform mode
gameState = "platform";
}
// Start level scrolling
function startLevelScrolling() {
levelScrolling = true;
lastPlatformX = platforms[platforms.length - 1].x;
// Start platform generation timer
platformGenerationTimer = LK.setInterval(function () {
generateNewPlatform();
}, 2000);
// Start spider generation timer
spiderGenerationTimer = LK.setInterval(function () {
generateNewSpider();
}, 5000);
// Move finish line further ahead
tween(finishLine, {
x: 2048 + 3000
}, {
duration: 1000,
easing: tween.linear
});
}
// Generate a new platform ahead
function generateNewPlatform() {
if (!levelScrolling) {
return;
}
var platform = new Platform();
// Position new platform off screen to the right
platform.x = 2048 + platform.width / 2;
// Randomize y position within screen bounds
var minPlatformY = 500;
var maxPlatformY = 2732 - 500;
platform.y = minPlatformY + Math.random() * (maxPlatformY - minPlatformY);
// Add platform to game
platforms.push(platform);
game.addChild(platform);
// Update last platform x position
lastPlatformX = platform.x;
}
// Generate a new spider on a platform
function generateNewSpider() {
if (!levelScrolling) {
return;
}
// Find suitable platform for new spider (one that's just entered the screen)
var suitablePlatforms = [];
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].x > 1500 && platforms[i].x < 2500) {
suitablePlatforms.push(platforms[i]);
}
}
if (suitablePlatforms.length === 0) {
return;
}
// Choose a random platform
var platform = suitablePlatforms[Math.floor(Math.random() * suitablePlatforms.length)];
// Create new enemy based on level
var spider;
if (currentLevel >= 5000 && Math.random() < 0.15) {
spider = new Bird();
} else if (currentLevel >= 750 && Math.random() < 0.12) {
spider = new Dragonfly();
} else if (currentLevel >= 444 && Math.random() < 0.10) {
spider = new Wasp();
} else if (currentLevel >= 100 && Math.random() < 0.08) {
spider = new Hornet();
} else {
spider = new Spider();
}
// Update spider's max health based on current level (20 more health per level) - but only for regular spiders
if (!spider.isHornet && !spider.isWasp && !spider.isDragonfly && !spider.isBird) {
spider.maxHealth = spider.baseMaxHealth + (currentLevel - 1) * 20;
spider.health = spider.maxHealth;
}
spider.x = platform.x;
spider.y = platform.y - platform.height / 2 - spider.height / 2;
spider.currentPlatform = platform;
// Add spider to game
spiders.push(spider);
game.addChild(spider);
}
// Stop level scrolling
function stopLevelScrolling() {
levelScrolling = false;
// Clear timers
if (platformGenerationTimer) {
LK.clearInterval(platformGenerationTimer);
platformGenerationTimer = null;
}
if (spiderGenerationTimer) {
LK.clearInterval(spiderGenerationTimer);
spiderGenerationTimer = null;
}
}
// Complete level
function completeLevel() {
LK.getSound('levelComplete').play();
// Stop level scrolling
stopLevelScrolling();
// Increase level
currentLevel++;
storage.currentLevel = currentLevel;
// Award ML for level completion
if (currentLevel < 10) {
ml += 3;
} else {
ml += 8;
}
storage.ml = ml;
if (mlText) mlText.setText("ML: " + ml);
// Update bee's max health based on new level and restore health (seul moment oĂč l'abeille rĂ©cupĂšre toute sa vie)
bee.maxHealth = bee.baseMaxHealth + (currentLevel - 1) * 50;
bee.health = bee.maxHealth;
// Update the level banner to show the new level
if (levelText) {
levelText.setText("Niveau : " + currentLevel + " / " + maxLevels);
}
// Check if player has reached the max level
if (currentLevel >= maxLevels) {
// Reset to level 1 and show victory message
currentLevel = 1;
storage.currentLevel = 1;
// Remove previous levelText if it exists
if (levelText && levelText.parent) {
levelText.parent.removeChild(levelText);
}
levelText = null;
// Remove previous spidersDefeatedText if it exists
if (spidersDefeatedText && spidersDefeatedText.parent) {
spidersDefeatedText.parent.removeChild(spidersDefeatedText);
}
spidersDefeatedText = null;
initLevel(currentLevel);
// Create victory message
var victoryContainer = new Container();
victoryContainer.x = 2048 / 2;
victoryContainer.y = 2732 / 2;
var victoryBackground = LK.getAsset('battlePanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.9
});
victoryContainer.addChild(victoryBackground);
var victoryText = new Text2("Félicitations vous avez complété Bee Wars !\nA bientÎt pour de nouveaux jeu de clem27games", {
size: 80,
fill: 0xFF69B4 // Pink color
});
victoryText.anchor.set(0.5, 0.5);
victoryContainer.addChild(victoryText);
game.addChild(victoryContainer);
// Create OK button to reset game
var okButton = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 200,
tint: 0x00FF00
});
victoryContainer.addChild(okButton);
var okText = new Text2("OK", {
size: 60,
fill: 0xFFFFFF
});
okText.anchor.set(0.5, 0.5);
okText.x = 0;
okText.y = 200;
victoryContainer.addChild(okText);
// Add down handler to the container
victoryContainer.down = function (x, y, obj) {
// Check if OK button was pressed
if (x >= okButton.x - okButton.width / 2 && x <= okButton.x + okButton.width / 2 && y >= okButton.y - okButton.height / 2 && y <= okButton.y + okButton.height / 2) {
// Reset to level 1
currentLevel = 1;
storage.currentLevel = 1;
// Reset spiders defeated for new level
spidersDefeated = 0;
spidersDefeatedText.setText("Spiders: " + spidersDefeated);
initLevel(currentLevel);
game.removeChild(victoryContainer);
}
};
// Show win screen after showing message for a few seconds if player doesn't click OK
LK.setTimeout(function () {
LK.showYouWin();
}, 30000);
return;
}
// Initialize next level
LK.setTimeout(function () {
initLevel(currentLevel);
// Remove previous levelText if it exists
if (levelText && levelText.parent) {
levelText.parent.removeChild(levelText);
}
levelText = null;
// Remove previous spidersDefeatedText if it exists
if (spidersDefeatedText && spidersDefeatedText.parent) {
spidersDefeatedText.parent.removeChild(spidersDefeatedText);
}
spidersDefeatedText = null;
initLevel(currentLevel);
}, 1000);
}
// Check collision between bee and platform
function checkPlatformCollision(bee, platform) {
// Simple rectangle collision
var beeLeft = bee.x - bee.width / 2;
var beeRight = bee.x + bee.width / 2;
var beeTop = bee.y - bee.height / 2;
var beeBottom = bee.y + bee.height / 2;
var platformLeft = platform.x - platform.width / 2;
var platformRight = platform.x + platform.width / 2;
var platformTop = platform.y - platform.height / 2;
var platformBottom = platform.y + platform.height / 2;
// Check for collision
if (beeRight > platformLeft && beeLeft < platformRight && beeBottom > platformTop && beeTop < platformBottom) {
// Check if landing on top of platform
if (beeBottom > platformTop && bee.velocityY > 0 && beeTop < platformTop) {
bee.y = platformTop - bee.height / 2;
bee.velocityY = 0;
bee.onGround = true;
bee.isJumping = false;
// Check for spiders on this platform to battle
for (var i = 0; i < spiders.length; i++) {
var spider = spiders[i];
if (!spider.defeated && spider.currentPlatform === platform) {
// If we landed on a platform with a spider, start battle
LK.setTimeout(function () {
startBattle(spider);
}, 100);
break;
}
}
return true;
}
}
return false;
}
// Find and jump to the nearest platform
function findAndJumpToNearestPlatform() {
var nearestPlatform = null;
var shortestDistance = Infinity;
// Find the nearest platform
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
var horizontalDistance = Math.abs(platform.x - bee.x);
// Only consider platforms that are reasonably within reach horizontally
if (horizontalDistance < 500) {
var verticalDistance = platform.y - platform.height / 2 - bee.y;
// Prefer platforms slightly above the bee or at the same level
var distance = horizontalDistance + (verticalDistance > 0 ? verticalDistance * 2 : Math.abs(verticalDistance) * 0.5);
if (distance < shortestDistance) {
shortestDistance = distance;
nearestPlatform = platform;
}
}
}
// If we found a platform, animate jumping to it
if (nearestPlatform) {
// Stop current movement
bee.velocityX = 0;
bee.velocityY = 0;
// Play jump sound
LK.getSound('jump').play();
// Tween to the platform position with a nice arc
var targetX = nearestPlatform.x;
var targetY = nearestPlatform.y - nearestPlatform.height / 2 - bee.height / 2;
// Create an animation that looks like a jump
tween(bee, {
x: targetX,
y: targetY
}, {
duration: 800,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
bee.onGround = true;
bee.isJumping = false;
}
});
}
}
// Handle bee dragging - mouse/touch down
game.down = function (x, y, obj) {
if (gameState === "platform") {
// Check if tap is on the bee
var beeLeft = bee.x - bee.width / 2;
var beeRight = bee.x + bee.width / 2;
var beeTop = bee.y - bee.height / 2;
var beeBottom = bee.y + bee.height / 2;
if (x >= beeLeft && x <= beeRight && y >= beeTop && y <= beeBottom) {
dragTarget = bee;
// Stop current movement when starting to drag
bee.velocityX = 0;
bee.velocityY = 0;
LK.getSound('bzz').play();
}
}
};
// Handle game movement
game.move = function (x, y, obj) {
// Only process movement in platform mode
if (gameState === "platform") {
// If dragging the bee, update its position
if (dragTarget) {
dragTarget.x = x;
dragTarget.y = y;
// Reset falling flags when manually dragging
bee.fallingInVoid = false;
return;
}
// Check if bee is falling in void and rescue it with any tap
if (bee.fallingInVoid) {
findAndJumpToNearestPlatform();
return;
}
// If tap is on the top fifth of the screen, jump
if (y < 2732 / 5) {
bee.jump();
}
// If tap is in the top-mid section of the screen, move up
else if (y < 2732 / 3) {
bee.moveUp();
}
// If tap is on the right half of the screen, move right
else if (x > 2048 / 2) {
bee.moveRight();
}
// If tap is on the left half of the screen, move left
else {
bee.moveLeft();
}
}
};
// Initialize first level
initLevel(currentLevel);
// Handle touch release to stop bee movement or place bee on platform when dragging
game.up = function (x, y, obj) {
if (gameState === "platform") {
if (dragTarget) {
// Check if bee is over a platform to place it properly
var platformFound = false;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
var platformLeft = platform.x - platform.width / 2;
var platformRight = platform.x + platform.width / 2;
var platformTop = platform.y - platform.height / 2;
// If bee is above platform horizontally, place it on the platform
if (bee.x >= platformLeft && bee.x <= platformRight) {
bee.y = platformTop - bee.height / 2;
bee.velocityY = 0;
bee.onGround = true;
bee.isJumping = false;
platformFound = true;
break;
}
}
// If no platform found beneath the bee, it starts falling
if (!platformFound) {
bee.onGround = false;
bee.velocityY = 1; // Start falling gently
}
// Release drag target
dragTarget = null;
// --- Bee Wars: After drag, update extra bees followTarget ---
for (var i = 0; i < extraBees.length; i++) {
extraBees[i].followTarget = beeQueue[i];
extraBees[i]._index = i;
}
} else {
bee.stopMoving();
}
}
};
// Game update loop
game.update = function () {
// Skip update if in battle mode
if (gameState === "battle") {
return;
}
// Only update bee physics if not being dragged
if (!dragTarget) {
// Update bee
bee.update();
// Update extra bees (they follow the beeQueue)
for (var i = 0; i < extraBees.length; i++) {
extraBees[i].update();
}
}
// Draw extra bees in front of main bee
for (var i = 0; i < extraBees.length; i++) {
if (extraBees[i].parent !== game) {
game.addChild(extraBees[i]);
}
// Always keep extra bees above the bee
if (bee.parent && extraBees[i].parent) {
if (game.children.indexOf(extraBees[i]) < game.children.indexOf(bee)) {
game.removeChild(extraBees[i]);
game.addChild(extraBees[i]);
}
}
}
// Add visual indication when bee is falling in void
if (bee.fallingInVoid) {
// Flash the bee to indicate it can be rescued
if (LK.ticks % 10 < 5) {
bee.alpha = 0.5;
} else {
bee.alpha = 1.0;
}
} else {
bee.alpha = 1.0;
}
// Check for platform collisions if bee is not being dragged
if (!dragTarget) {
// Check for platform collisions
for (var i = 0; i < platforms.length; i++) {
var collided = checkPlatformCollision(bee, platforms[i]);
// Platform ML logic: count platforms passed (without spider)
if (collided) {
if (lastBeePlatform !== platforms[i]) {
// Only count if platform has no spider on it
var hasSpider = false;
for (var s = 0; s < spiders.length; s++) {
if (!spiders[s].defeated && spiders[s].currentPlatform === platforms[i]) {
hasSpider = true;
break;
}
}
if (!hasSpider) {
platformsPassed++;
platformsPassedSinceLastML++;
// Award 2 ML every 5 platforms passed (without spider)
if (platformsPassedSinceLastML >= 5) {
ml += 2;
storage.ml = ml;
if (mlText) mlText.setText("ML: " + ml);
platformsPassedSinceLastML = 0;
}
}
lastBeePlatform = platforms[i];
}
}
// Defensive: if bee is not on any platform, reset lastBeePlatform
if (!collided && lastBeePlatform === platforms[i]) {
lastBeePlatform = null;
}
checkPlatformCollision(bee, platforms[i]);
}
}
// Check for screen boundaries
if (bee.x < bee.width / 2) {
bee.x = bee.width / 2;
} else if (bee.x > 2048 - bee.width / 2) {
bee.x = 2048 - bee.width / 2;
}
// Check if bee is falling with no platform below
if (bee.y > 2732 - 400 && bee.velocityY > 0 && !bee.onGround) {
// Set a flag that bee is falling in void to allow rescue by tap
bee.fallingInVoid = true;
} else if (bee.y > 2732 + bee.height) {
// Fell off the screen
// --- Bee Wars: If main bee dies outside battle, replace with extra bee if available ---
if (extraBees.length > 0) {
// Remove main bee from game
if (bee.parent) bee.parent.removeChild(bee);
// Promote first extra bee to main bee
var newBee = extraBees.shift();
beeQueue.shift();
newBee.isActive = true;
bee = newBee;
beeQueue[0] = bee;
// Set controls to new bee
controlsUI.onLeftPressed = function () {
bee.moveLeft();
};
controlsUI.onRightPressed = function () {
bee.moveRight();
};
controlsUI.onJumpPressed = function () {
bee.jump();
};
controlsUI.onUpPressed = function () {
bee.moveUp();
};
controlsUI.onControlsReleased = function () {
bee.stopMoving();
};
// Place new bee at start position
bee.x = 150;
bee.y = 2732 / 2;
bee.velocityX = 0;
bee.velocityY = 0;
bee.onGround = true;
bee.fallingInVoid = false;
bee.alpha = 1.0;
// Defensive: update followTarget for remaining extra bees
for (var i = 0; i < extraBees.length; i++) {
extraBees[i].followTarget = beeQueue[i];
extraBees[i]._index = i;
}
// Add to game if not already
if (!bee.parent) game.addChild(bee);
return;
} else {
LK.showGameOver();
return;
}
} else {
// Reset falling flag when not in danger zone
bee.fallingInVoid = false;
}
// Check for spiders on the same platform as bee
for (var i = 0; i < spiders.length; i++) {
var spider = spiders[i];
if (!spider.defeated) {
// Check if bee and spider are on the same platform
if (spider.currentPlatform) {
var onSamePlatform = Math.abs(bee.x - spider.x) < spider.currentPlatform.width * 0.8 && Math.abs(bee.y - spider.y) < 20;
if (onSamePlatform && !spider.moving) {
// Spider should move away
spider.moveAwayFromBee(bee);
}
}
// Check for collision or shared platform to start battle
if (bee.intersects(spider) || spider.currentPlatform && bee.onGround && Math.abs(bee.x - spider.x) < spider.currentPlatform.width * 0.5) {
startBattle(spider);
return;
}
}
}
// Check if all spiders on screen are defeated to start scrolling
var visibleSpiders = false;
for (var i = 0; i < spiders.length; i++) {
if (!spiders[i].defeated && spiders[i].x < 2048) {
visibleSpiders = true;
break;
}
}
// Start level scrolling if all visible spiders are defeated and not already scrolling
if (!visibleSpiders && !levelScrolling && bee.onGround) {
startLevelScrolling();
}
// Handle platform and object movement when scrolling
if (levelScrolling) {
// Move platforms
for (var i = 0; i < platforms.length; i++) {
platforms[i].x += scrollSpeed;
// Remove platforms that have gone off screen
if (platforms[i].x < -platforms[i].width) {
game.removeChild(platforms[i]);
platforms.splice(i, 1);
i--;
}
}
// Move spiders with their platforms
for (var i = 0; i < spiders.length; i++) {
if (spiders[i].currentPlatform) {
spiders[i].x = spiders[i].currentPlatform.x;
}
}
// Move finish line
finishLine.x += scrollSpeed;
// If bee is on a platform, move it with the platform
if (bee.onGround) {
bee.x += scrollSpeed;
}
}
// Check for finish line collision
if (bee.intersects(finishLine)) {
// Check if all spiders are defeated
var allSpidersDefeated = true;
for (var i = 0; i < spiders.length; i++) {
if (!spiders[i].defeated) {
allSpidersDefeated = false;
break;
}
}
if (allSpidersDefeated) {
completeLevel();
}
}
};
tron d'arbre mignon de plateforme. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Abeille. In-Game asset. 2d. High contrast. No shadows
AraigneÌe. In-Game asset. 2d. High contrast. No shadows
Fond d'eÌcran ruche. In-Game asset. 2d. High contrast. No shadows
Fond d'eÌcran maiÌs. In-Game asset. 2d. High contrast. No shadows
Fond d'eÌcran roche. In-Game asset. 2d. High contrast. No shadows
Fond d'eÌcran campagne. In-Game asset. 2d. High contrast. No shadows
Fond d'eÌcran nid des araigneÌes. In-Game asset. 2d. High contrast. No shadows
Fond d'eÌcran foreÌt enchanteÌe. In-Game asset. 2d. High contrast. No shadows
Fond d'eÌcran muguet. In-Game asset. 2d. High contrast. No shadows
Fond d'eÌcran roses epineuses. In-Game asset. 2d. High contrast. No shadows
Fond d'eÌcran prairie manga. In-Game asset. 2d. High contrast. No shadows
Fond d'eÌcran ortis. In-Game asset. 2d. High contrast. No shadows
Frelon. In-Game asset. 2d. High contrast. No shadows
GueÌpe. In-Game asset. 2d. High contrast. No shadows
Libellule. In-Game asset. 2d. High contrast. No shadows
Oiseau. In-Game asset. 2d. High contrast. No shadows