User prompt
AmeĢliore le systeĢme des abeilles secondaires : fait en sorte que lorsqu'une abeille secondaire remplace l'abeille principale, le stock d'abeilles secondaires libeĢre une place, laissant le joueur acheter une nouvelle abeille secondaire a chaque fois qu'une place se libeĢre āŖš” Consider importing and using the following plugins: @upit/storage.v1
User prompt
CorrigeĢ les probleĢmes!!!!!
User prompt
CorrigeĢ les probleĢmes!!!!!
User prompt
CorrigeĢ les probleĢmes
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var beeLeft = bee.x - bee.width / 2;' Line Number: 3482
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var beeLeft = bee.x - bee.width / 2;' Line Number: 3482
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var beeLeft = bee.x - bee.width / 2;' Line Number: 3478
User prompt
CreĢe une page de lancement pour bee wars! cette page de lancement a un fond repreĢsentant des abeilles mignonnes (je personnaliserai moi meĢme le fond avec mon propre asset), un text rose a police mignonne disant "Bienvenue sur Bee Wars! PreĢt(e) a combattre ?" Puis une barre de chargement progresse de 0% a 100%, Puis quand la barre de chargement est a 100%, Un boutton jaune a texte noir "jouer" apparaiĢt et quand le joueur appuie dessus il acceĢde au jeu! āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Fait en sorte que le joueur puisse deĢrouler l'eĢcran de la boutique pour voir tout les choix de personnalisation de fond
User prompt
Ajoute les assets pour les nouveaux ennemis, et regles les probleĢmes en rapport avec les nouveaux ennemis !
User prompt
Ajoute ces fonctionnaliteĢs a bee wars : - la fin du jeu doit deĢsormais eĢtre fixeĢ au niveau 17 500 (oui je ne suis pas folle mdr, bee wars est deĢsormais un jeu que les joueurs peuvent jouer et suivre durant des anneĢes) - ajouter de nouveaux fonds personnaliseĢs dans bee wars : 1) foreĢt enchanteĢe (prix : 185 ml) 2) muguet (prix : 200 ml) 3) roses equineuses (prix : 170 ml) 4) prairie manga (prix : 220 ml) 5) ortis (prix : 240 ml) - ajouter 75 nouvelles questions pour les quizz sur les araigneĢes et les abeilles - ajouter des ennemis suppleĢmentaires aux comportements impreĢvisibles (pour eĢviter que le joueur se lasse dans les gros niveaux) : Frelons (aĢ partir du niveau 100) : les frelons sont de nouveaux ennemis, ils ont aleĢatoirement entre 300 et 600 points de vie au deĢbut du combat, mais attention, les frelons sont capables de se reviltaliser (reĢcupeĢrer 35% de leurs points de vie originaux) de façon aleĢatoire quand ils tombent en bas des moins de 100 points de vie (vaincre un frelon = eĢquivalent de 10 araigneĢes vaincus) GueĢpes (aĢ partir du niveau 444) : ont aleĢatoirement entre 700 et 6 000 points de vie, sont capables d'invoquer aleĢatoirement un frelon quand elles descendent en bas des 500 points de vie! (vaincre une gueĢpe = eĢquivalent de 20 araigneĢes vaincus) Libellules (aĢ partir du niveau 750) : ont aleĢatoirement entre 1000 et 15 000 points de vie! (vaincre une libellule = eĢquivalent de 30 araigneĢes vaincus) Oiseaux (a partir du niveau 5 000) ; ont aleĢatoirement entre 6 000 et 26 000 points de vies! (Vaincre un oiseau = eĢquivalent de 70 araigneĢes vaincus) āŖš” Consider importing and using the following plugins: @upit/storage.v1
User prompt
Ajoute 60 nouvelles questions de mini-quizz possibles
User prompt
Ajoute ces fonctionnaliteĢs a bee wars : - ajouts de sons d'animations (bzz quand l'abeille se deĢplace, coups de fusils quand une araigneĢe est vaincu) - mini quizz de question aleĢatoire sur la vie des abeilles ou des araigneĢes, lors des combats avec les araigneĢes (apreĢs 4 araigneĢes preĢceĢdentes vaincus si le joueur est niveau infeĢrieur a 10, et apreĢs 7 araigneĢes preĢceĢdentes vaincu si le joueur est niveau supeĢrieur a 10l pour avoir un bonus de deĢgaĢt si le joueur reĢpond correctement aĢ la question du mini quizz , Un eĢcran avec la question du quizz et 3 choix possibles s'ouvre, Le joueur doit appuyer sur la bonne reĢponse, S'il se trompe, ça ne fait pas de deĢgaĢts suppleĢmentaires, et le joueur vaint l'araigneĢe normalement, Mais s'il reĢpond correctement, le joueur aĢ un bonus de deĢgaĢt pendant les 2 araigneĢes suivantes : il infligera 20% de deĢgaĢts suppleĢmentaires aux araigneĢes aĢ chaque coup Mais cet effet sera deĢsactiveĢ au bout de 2 araigneĢes apreĢs celle de laquelle il a reĢpondu au mini-quizz le joueur doit avoir une mini question de quizz a reĢpondre tout les 4 araigneĢes (s'il est niveau infeĢrieur a 10, et tout les 7 araigneĢes s'il est niveau supeĢrieur aĢ 10), Le joueur doit bien-suĢr avoir le choix entre faire un mini quizz ou jouer son tour sans quizz sur l'araigneĢe , Le jeu doit afficher un eĢcran lui demandant si oui ou non il veut faire un mini quizz pour se tour aux moments venus avant que le joueur fasse une petite question de quizz, il appuie sur oui ou non, si il appuie sur oui, il doit reĢpondre a la question du mini quizz, S'il reĢpond non, l'eĢcran se ferme et il peut continuer aĢ jouer au jeu, jusqu'au prochain moment de quizz , ou il a le choix pareil
User prompt
Ajoute ces fonctionnaliteĢs a bee wars : - ajouts de sons d'animations (bzz quand l'abeille se deĢplace, coups de fusils quand une araigneĢe est vaincu) - mini quizz de question aleĢatoire sur la vie des abeilles ou des araigneĢes, lors des combats avec les araigneĢes (apreĢs 4 araigneĢes preĢceĢdentes vaincus si le joueur est niveau infeĢrieur a 10, et apreĢs 7 araigneĢes preĢceĢdentes vaincu si le joueur est niveau supeĢrieur a 10l pour avoir un bonus de deĢgaĢt si le joueur reĢpond correctement aĢ la question du mini quizz , Un eĢcran avec la question du quizz et 3 choix possibles s'ouvre, Le joueur doit appuyer sur la bonne reĢponse, S'il se trompe, ça ne fait pas de deĢgaĢts suppleĢmentaires, et le joueur vaint l'araigneĢe normalement, Mais s'il reĢpond correctement, le joueur aĢ un bonus de deĢgaĢt pendant les 2 araigneĢes suivantes : il infligera 20% de deĢgaĢts suppleĢmentaires aux araigneĢes aĢ chaque coup Mais cet effet sera deĢsactiveĢ au bout de 2 araigneĢes apreĢs celle de laquelle il a reĢpondu au mini-quizz le joueur doit avoir une mini question de quizz a reĢpondre tout les 4 araigneĢes (s'il est niveau infeĢrieur a 10, et tout les 7 araigneĢes s'il est niveau supeĢrieur aĢ 10), Le joueur doit bien-suĢr avoir le choix entre faire un mini quizz ou jouer son tour sans quizz sur l'araigneĢe , Le jeu doit afficher un eĢcran lui demandant si oui ou non il veut faire un mini quizz pour se tour aux moments venus avant que le joueur fasse une petite question de quizz, il appuie sur oui ou non, si il appuie sur oui, il doit reĢpondre a la question du mini quizz, S'il reĢpond non, l'eĢcran se ferme et il peut continuer aĢ jouer au jeu, jusqu'au prochain moment de quizz , ou il a le choix pareil āŖš” Consider importing and using the following plugins: @upit/storage.v1
User prompt
Supprime le boutton reset
User prompt
Regles les probleĢmes de points de vie (NaN non deĢfinie sur les araigneĢes), pour que les points de vies s'affichent correctement
User prompt
Please fix the bug: 'TypeError: spider.moveAwayFromBee is not a function' in or related to this line: 'spider.moveAwayFromBee(bee);' Line Number: 488
User prompt
Ajoute ces fonctionnaliteĢs a Bee wars : - Certaines araigneĢes peuvent se diviser en 2 autres araigneĢes distinctes mais avec plus de points de vies, dans ce cas l'abeille devra les combattre/vaincre l'une apreĢs l'autre, et ces araigneĢes la infligeront plus de deĢgaĢts a l'abeille a chaque tour qu'une araigneĢe normale (aleĢatoirement entre 15 et 50 points de deĢgaĢts a chaque tour), Seule les araigneĢes de fin de niveau, ou les araigneĢes qui n'ont bientoĢt plus de points de vie peuvent faire cela, Mais elle ne le font pas toujours, ça doit eĢtre aleĢatoire - le nombre d'araigneĢes requises pour passer d'un niveau a un autre doit doubler , meĢme pour les niveaux 1 a 10 (5 araigneĢe pour passer du niveau 1 au niveau 2, Puis 10 pour passer au niveau 3, etc...), seule les araigneĢes vaincus individuellement en tour par tour doivent eĢtre compteĢ - ajouter un systeĢme de personnalisation du fond du jeu (les joueurs peuvent acheter un fond personnaliseĢ pour le jeu, ce qui modifie le fond du jeu , ciel par deĢfaut), Ils peuvent choisir entre : - ruche (fond repreĢsentant des alveĢoles), (couĢte 30 ml) - campagnes (couĢte 60 ml) - roche (fond rochers) (couĢte 86 ml) - nid des araigneĢes (couĢte 100 ml) - maiĢs (fond de maiĢs) (couĢte 125 ml) Chaque changement de fond couĢte des ml. Le joueur peut changer son fond en accedant a un boutton bleu parameĢtressitue juste en bas du boutton de la boutique , Le jeu lui donne alors la liste des fond en lui demandant alors quel fond le joueur souhaite, Le joueur peut alors choisir son fond en appuyant sur "celui ci" en face du nom du fond dans la liste , Le jeu remplace alors le fond du jeu par deĢfaut par le fond choisis Le fond du jeu personnaliseĢ par le joueur reste de façon permanente meĢme fur a mesure des niveaux, mais le joueur peut en changer quand il le souhaite āŖš” Consider importing and using the following plugins: @upit/storage.v1
User prompt
Ajoute ces fonctionnaliteĢs a Bee wars : - Certaines araigneĢes peuvent se diviser en 2 autres araigneĢes distinctes mais avec plus de points de vies, dans ce cas l'abeille devra les combattre/vaincre l'une apreĢs l'autre, et ces araigneĢes la infligeront plus de deĢgaĢts a l'abeille a chaque tour qu'une araigneĢe normale (aleĢatoirement entre 15 et 50 points de deĢgaĢts a chaque tour), Seule les araigneĢes de fin de niveau, ou les araigneĢes qui n'ont bientoĢt plus de points de vie peuvent faire cela, Mais elle ne le font pas toujours, ça doit eĢtre aleĢatoire - le nombre d'araigneĢes requises pour passer d'un niveau a un autre doit doubler , meĢme pour les niveaux 1 a 10 (5 araigneĢe pour passer du niveau 1 au niveau 2, Puis 10 pour passer au niveau 3, etc...), seule les araigneĢes vaincus individuellement en tour par tour doivent eĢtre compteĢ - ajouter un systeĢme de personnalisation du fond du jeu (les joueurs peuvent acheter un fond personnaliseĢ pour le jeu, ce qui modifie le fond du jeu , ciel par deĢfaut), Ils peuvent choisir entre : - ruche (fond repreĢsentant des alveĢoles), (couĢte 30 ml) - campagnes (couĢte 60 ml) - roche (fond rochers) (couĢte 86 ml) - nid des araigneĢes (couĢte 100 ml) - maiĢs (fond de maiĢs) (couĢte 125 ml) Chaque changement de fond couĢte des ml. Le joueur peut changer son fond en accedant a un boutton bleu parameĢtressitue juste en bas du boutton de la boutique , Le jeu lui donne alors la liste des fond en lui demandant alors quel fond le joueur souhaite, Le joueur peut alors choisir son fond en appuyant sur "celui ci" en face du nom du fond dans la liste , Le jeu remplace alors le fond du jeu par deĢfaut par le fond choisis Le fond du jeu personnaliseĢ par le joueur reste de façon permanente meĢme fur a mesure des niveaux, mais le joueur peut en changer quand il le souhaite āŖš” Consider importing and using the following plugins: @upit/storage.v1
User prompt
Ajoute ces fonctionnaliteĢs a Bee wars : - Certaines araigneĢes peuvent se diviser en 2 autres araigneĢes distinctes mais avec plus de points de vies, dans ce cas l'abeille devra les combattre/vaincre l'une apreĢs l'autre, et ces araigneĢes la infligeront plus de deĢgaĢts a l'abeille a chaque tour qu'une araigneĢe normale (aleĢatoirement entre 15 et 50 points de deĢgaĢts a chaque tour), Seule les araigneĢes de fin de niveau, ou les araigneĢes qui n'ont bientoĢt plus de points de vie peuvent faire cela, Mais elle ne le font pas toujours, ça doit eĢtre aleĢatoire - le nombre d'araigneĢes requises pour passer d'un niveau a un autre doit doubler , meĢme pour les niveaux 1 a 10 (5 araigneĢe pour passer du niveau 1 au niveau 2, Puis 10 pour passer au niveau 3, etc...), seule les araigneĢes vaincus individuellement en tour par tour doivent eĢtre compteĢ - ajouter un systeĢme de personnalisation du fond du jeu (les joueurs peuvent acheter un fond personnaliseĢ pour le jeu, ce qui modifie le fond du jeu , ciel par deĢfaut), Ils peuvent choisir entre : - ruche (fond repreĢsentant des alveĢoles), (couĢte 30 ml) - campagnes (couĢte 60 ml) - roche (fond rochers) (couĢte 86 ml) - nid des araigneĢes (couĢte 100 ml) - maiĢs (fond de maiĢs) (couĢte 125 ml) Chaque changement de fond couĢte des ml. Le joueur peut changer son fond en accedant a un boutton bleu parameĢtressitue juste en bas du boutton de la boutique , Le jeu lui donne alors la liste des fond en lui demandant alors quel fond le joueur souhaite, Le joueur peut alors choisir son fond en appuyant sur "celui ci" en face du nom du fond dans la liste , Le jeu remplace alors le fond du jeu par deĢfaut par le fond choisis Le fond du jeu personnaliseĢ par le joueur reste de façon permanente meĢme fur a mesure des niveaux, mais le joueur peut en changer quand il le souhaite āŖš” Consider importing and using the following plugins: @upit/storage.v1
User prompt
Ajoute ces fonctionnaliteĢs a Bee wars : - Certaines araigneĢes peuvent se diviser en 2 autres araigneĢes distinctes mais avec plus de points de vies, dans ce cas l'abeille devra les combattre/vaincre l'une apreĢs l'autre, et ces araigneĢes la infligeront plus de deĢgaĢts a l'abeille a chaque tour qu'une araigneĢe normale (aleĢatoirement entre 15 et 50 points de deĢgaĢts a chaque tour), Seule les araigneĢes de fin de niveau, ou les araigneĢes qui n'ont bientoĢt plus de points de vie peuvent faire cela, Mais elle ne le font pas toujours, ça doit eĢtre aleĢatoire - le nombre d'araigneĢes requises pour passer d'un niveau a un autre doit doubler , meĢme pour les niveaux 1 a 10 (5 araigneĢe pour passer du niveau 1 au niveau 2, Puis 10 pour passer au niveau 3, etc...), seule les araigneĢes vaincus individuellement en tour par tour doivent eĢtre compteĢ - ajouter un systeĢme de personnalisation du fond du jeu (les joueurs peuvent acheter un fond personnaliseĢ pour le jeu, ce qui modifie le fond du jeu , ciel par deĢfaut), Ils peuvent choisir entre : - ruche (fond repreĢsentant des alveĢoles), (couĢte 30 ml) - campagnes (couĢte 60 ml) - roche (fond rochers) (couĢte 86 ml) - nid des araigneĢes (couĢte 100 ml) - maiĢs (fond de maiĢs) (couĢte 125 ml) Chaque changement de fond couĢte des ml. Le joueur peut changer son fond en accedant a un boutton bleu parameĢtressitue juste en bas du boutton de la boutique , Le jeu lui donne alors la liste des fond en lui demandant alors quel fond le joueur souhaite, Le joueur peut alors choisir son fond en appuyant sur "celui ci" en face du nom du fond dans la liste , Le jeu remplace alors le fond du jeu par deĢfaut par le fond choisis Le fond du jeu personnaliseĢ par le joueur reste de façon permanente meĢme fur a mesure des niveaux, mais le joueur peut en changer quand il le souhaite
User prompt
Mets a jour le jeu pour eĢviter les sautements de niveaux : un seul niveau gagneĢs/atteint a la fois
User prompt
Ajoute ces fonctionnaliteĢs a bee wars : - ruche voisine : De temps en temps, aleĢatoirement dans le jeu , Des ruches apparaissent sur les plateformes, Quand l'abeille rentre en contact avec ces ruches la, Le joueur peut acheter une abeille suppleĢmentaire pour le jeu (couĢte 50 ml) : L'abeille suppleĢmentaire est une abeille, qui, en tant , normal avance sur la plateforme automatiquement a la suite de l'abeille principale, mais l'abeille suppleĢmentaire ne combat pas les araigneĢes et ne perd pas de points de vies Mais si l'abeille principale viens aĢ mourir (ne plus avoir de points de vies), L'abeille suppleĢmentaire prend sa place, et le joueur peut continuer aĢ jouer avec l'abeille suppleĢmentaire sur la plateforme, pour les combats (l'abeille suppleĢmentaire a donc le meĢme systeĢme de points de vie que l'abeille principale), si le joueur rencontre une ruche et a deĢjaĢ une abeille suppleĢmentaire, il peut en acheter une autre (ou deĢcliner l'abeille suppleĢmentaire), le joueur peut avoir jusqu'aĢ 6 abeilles suppleĢmentaires en jeu, les abeilles suppleĢmentaires sont petites en taille
User prompt
Ajoute les assets requis pour les ruches et les abeilles suppleĢmentaires etc
User prompt
Ajoute ces fonctionnaliteĢs a bee wars : - ruche voisine : De temps en temps, aleĢatoirement dans le jeu , Des ruches apparaissent sur les plateformes, Quand l'abeille rentre en contact avec ces ruches la, Le joueur peut acheter une abeille suppleĢmentaire pour le jeu (couĢte 50 ml) : L'abeille suppleĢmentaire est une abeille, qui, en tant , normal avance sur la plateforme automatiquement a la suite de l'abeille principale, mais l'abeille suppleĢmentaire ne combat pas les araigneĢes et ne perd pas de points de vies Mais si l'abeille principale viens aĢ mourir (ne plus avoir de points de vies), L'abeille suppleĢmentaire prend sa place, et le joueur peut continuer aĢ jouer avec l'abeille suppleĢmentaire sur la plateforme, pour les combats (l'abeille suppleĢmentaire a donc le meĢme systeĢme de points de vie que l'abeille principale), si le joueur rencontre une ruche et a deĢjaĢ une abeille suppleĢmentaire, il peut en acheter une autre (ou deĢcliner l'abeille suppleĢmentaire), le joueur peut avoir jusqu'aĢ 6 abeilles suppleĢmentaires en jeu, les abeilles suppleĢmentaires sont petites en taille
/****
* 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
}
};
self.jump = function () {
if (self.onGround) {
self.velocityY = self.jumpForce;
self.onGround = false;
self.isJumping = true;
LK.getSound('jump').play();
}
};
self.moveLeft = function () {
self.velocityX = -self.speed;
};
self.moveRight = function () {
self.velocityX = self.speed;
};
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 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;
});
// 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;
});
// 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;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue background
});
/****
* Game Code
****/
// Custom background images
// Replace id with actual asset id if available
// Replace id with actual asset id if available
// --- Bee Wars: Assets for neighbor hives and extra bees ---
// Show dialog to buy extra bee from neighbor hive
function showNeighborHiveDialog(hive) {
// Only allow up to 6 extra bees
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 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 ?", {
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);
// Remove hive from game
if (hive && hive.parent) hive.parent.removeChild(hive);
var idx = neighborHives.indexOf(hive);
if (idx >= 0) neighborHives.splice(idx, 1);
// Remove dialog
if (panel.parent) panel.parent.removeChild(panel);
} 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 = 100;
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";
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++) {
// Only end-of-level spiders or low-health spiders can be dividing spiders, and only sometimes (random)
var isEndOfLevel = i === spiderCount - 1;
var isLowHealth = level > 2 && Math.random() < 0.25;
var makeDividing = (isEndOfLevel || isLowHealth) && Math.random() < 0.7; // 70% chance for end, 25% for low health
var spider;
if (makeDividing) {
spider = new DividingSpider();
} else {
spider = new Spider();
}
// Update spider's max health based on level (20 more health per level)
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.7,
scaleY: 0.7,
alpha: 0.97
});
bgPanel.addChild(bg);
var title = new Text2("Choisis ton fond :", {
size: 60,
fill: 0x000000
});
title.anchor.set(0.5, 0);
title.y = -bg.height * 0.3 + 40;
bgPanel.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"
}];
var yStart = -bg.height * 0.15;
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;
bgPanel.addChild(btn);
bgPanel.addChild(txt);
bgPanel.addChild(selectBtn);
bgPanel.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);
}
// 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;
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);
};
// Create reset button just below the level banner (score banner), centered on the banner
var resetButton = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.0,
scaleX: 0.5,
scaleY: 0.5,
x: levelText.x,
y: levelText.y + levelText.height + mlText.height + boutiqueButton.height * boutiqueButton.scaleY + 40,
// 40px below the boutique button
tint: 0xFF4444
});
var resetText = new Text2("Reset", {
size: 30,
fill: 0xFFFFFF
});
resetText.anchor.set(0.5, 0.5);
resetText.x = levelText.x;
resetText.y = resetButton.y + resetButton.height * resetButton.scaleY / 2;
// Add to the same UI container as the levelText (top banner)
LK.gui.top.addChild(resetButton);
LK.gui.top.addChild(resetText);
// Make reset button interactive and always tappable
resetButton.interactive = true;
resetButton.down = function (x, y, obj) {
// Always allow reset, regardless of game state, and always check bounds
// Use correct bounds for scaled button
var btnLeft = resetButton.x - resetButton.width * resetButton.scaleX / 2;
var btnRight = resetButton.x + resetButton.width * resetButton.scaleX / 2;
var btnTop = resetButton.y;
var btnBottom = resetButton.y + resetButton.height * resetButton.scaleY;
if (x >= btnLeft && x <= btnRight && y >= btnTop && y <= btnBottom) {
// Show confirmation popup
if (typeof window._resetConfirmPanel !== "undefined" && window._resetConfirmPanel && window._resetConfirmPanel.parent) {
// Already open, do nothing
return;
}
// Defensive: only allow one confirmation panel at a time
var resetConfirmPanel = new Container();
window._resetConfirmPanel = resetConfirmPanel;
resetConfirmPanel.x = 2048 / 2;
resetConfirmPanel.y = 2732 / 2;
// Background
var bg = LK.getAsset('battlePanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.5,
alpha: 0.98
});
resetConfirmPanel.addChild(bg);
// Confirmation text
var confirmText = new Text2("Ćtes-vous sĆ»r de rĆ©initialiser votre progression depuis le dĆ©but ?", {
size: 55,
fill: 0x000000
});
confirmText.anchor.set(0.5, 0.5);
confirmText.x = 0;
confirmText.y = -60;
resetConfirmPanel.addChild(confirmText);
// Oui button
var yesBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
x: -180,
y: 80,
tint: 0xFF4444
});
var yesText = new Text2("Oui", {
size: 40,
fill: 0xFFFFFF
});
yesText.anchor.set(0.5, 0.5);
yesText.x = -180;
yesText.y = 80;
resetConfirmPanel.addChild(yesBtn);
resetConfirmPanel.addChild(yesText);
// Non button
var noBtn = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
x: 180,
y: 80,
tint: 0x00AA00
});
var noText = new Text2("Non", {
size: 40,
fill: 0xFFFFFF
});
noText.anchor.set(0.5, 0.5);
noText.x = 180;
noText.y = 80;
resetConfirmPanel.addChild(noBtn);
resetConfirmPanel.addChild(noText);
// Add to GUI overlay (centered)
LK.gui.addChild(resetConfirmPanel);
// Handler for Oui
yesBtn.interactive = true;
yesBtn.down = function (xx, yy, obj2) {
// Remove confirmation panel
if (resetConfirmPanel && resetConfirmPanel.parent) {
resetConfirmPanel.parent.removeChild(resetConfirmPanel);
}
window._resetConfirmPanel = null;
// RƩinitialise toutes les donnƩes de progression du joueur dans le storage
currentLevel = 1;
storage.currentLevel = 1;
spidersDefeated = 0;
LK.setScore(0);
ml = 0;
storage.ml = 0;
// Supprime toutes les autres clƩs de progression personnalisƩes si prƩsentes
if (typeof storage.spidersDefeated !== "undefined") {
storage.spidersDefeated = 0;
}
if (typeof storage.inventory !== "undefined") {
storage.inventory = {};
}
if (typeof storage.beeUpgrades !== "undefined") {
storage.beeUpgrades = {};
}
if (typeof storage.lastLevel !== "undefined") {
storage.lastLevel = 1;
}
if (typeof storage.boutiquePurchases !== "undefined") {
storage.boutiquePurchases = {};
}
// Ajoutez ici toute autre clé de progression personnalisée à réinitialiser si besoin
// Affiche un vrai game over pour réinitialiser complètement l'état du jeu
LK.showGameOver({
message: "Progression rƩinitialisƩe !"
});
};
// Handler for Non
noBtn.interactive = true;
noBtn.down = function (xx, yy, obj2) {
if (resetConfirmPanel && resetConfirmPanel.parent) {
resetConfirmPanel.parent.removeChild(resetConfirmPanel);
}
window._resetConfirmPanel = null;
};
}
};
// 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;
}
// Player attacks in battle
function playerAttack() {
var damage = 20 + Math.floor(Math.random() * 10); // 20-29 damage
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) {
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;
// 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) {
spidersDefeated++;
game.battleState.currentSpider.countedAsDefeated = true;
spidersDefeatedText.setText("Spiders: " + spidersDefeated);
// Award 1 ML per spider defeated
ml += 1;
storage.ml = ml;
if (mlText) mlText.setText("ML: " + ml);
}
// 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 100 levels
var maxLevels = 100;
// 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 spider
var spider = new Spider();
// Update spider's max health based on current level (20 more health per level)
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;
}
}
};
// 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();
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -253,8 +253,16 @@
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
};
@@ -269,8 +277,9 @@
// 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
@@ -517,11 +526,12 @@
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.health = 50;
- self.maxHealth = 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;
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