/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { level: 1 }); /**** * Classes ****/ // Classe pour les abeilles adversaires var EnemyBee = Container.expand(function () { var self = Container.call(this); // Couleur différente selon l'index var colorId = self.colorId || 1; var assetId = 'bee_enemy' + colorId; var bee = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.width = bee.width; self.height = bee.height; self.lane = 0; self.speed = 0; self.avoidCooldown = 0; self.update = function () { // Avance automatiquement self.x += self.speed; // Petite oscillation pour donner vie bee.y = Math.sin(LK.ticks / 20 + self.lane) * 10; }; // Pour éviter un obstacle, saute sur le côté (change de voie) self.tryAvoid = function (obstacles) { if (self.avoidCooldown > 0) { self.avoidCooldown--; return; } // Si un obstacle est proche devant, tente d'éviter for (var i = 0; i < obstacles.length; i++) { var obs = obstacles[i]; if (obs.lane === self.lane && obs.x > self.x && obs.x - self.x < 180) { // Tente de changer de voie (aléatoire) var dirs = []; if (self.lane > 0) dirs.push(-1); if (self.lane < 4) dirs.push(1); if (dirs.length > 0) { var dir = dirs[Math.floor(Math.random() * dirs.length)]; self.lane += dir; self.y = laneY(self.lane); self.avoidCooldown = 30 + Math.floor(Math.random() * 20); } break; } } }; return self; }); // Classe pour l'abeille du joueur var PlayerBee = Container.expand(function () { var self = Container.call(this); var bee = self.attachAsset('bee_player', { anchorX: 0.5, anchorY: 0.5 }); self.width = bee.width; self.height = bee.height; self.lane = 2; // Par défaut, voie centrale (0-4) self.isJumping = false; self.jumpStartY = 0; self.jumpStartX = 0; self.jumpTargetY = 0; self.jumpTargetX = 0; self.jumpProgress = 0; self.jumpDuration = 10; // frames, bond plus court self.targetLane = self.lane; self.targetX = 0; self.update = function () { // Synchronise la vitesse de déplacement avec les abeilles adversaires // On prend la vitesse moyenne des ennemis pour la course actuelle var avgSpeed = 0; if (typeof enemyBees !== "undefined" && enemyBees.length > 0) { var total = 0; for (var i = 0; i < enemyBees.length; i++) { total += enemyBees[i].speed; } avgSpeed = total / enemyBees.length; } else { avgSpeed = 7 + level * 1.5; // fallback } // Gestion du bond (court et latéral) if (self.isJumping) { self.jumpProgress++; var t = self.jumpProgress / self.jumpDuration; // Interpolation linéaire pour X et Y self.x = self.jumpStartX + (self.jumpTargetX - self.jumpStartX) * t; self.y = self.jumpStartY + (self.jumpTargetY - self.jumpStartY) * t - Math.sin(Math.PI * t) * 40; if (self.jumpProgress >= self.jumpDuration) { self.isJumping = false; self.x = self.jumpTargetX; self.y = self.jumpTargetY; self.lane = self.targetLane; } } else { // Si pas en saut, avance automatiquement à la même vitesse que les ennemis self.x += avgSpeed; } }; // Prépare un bond court vers la position cible (tap ou drag) self.prepareJump = function () { if (self.isJumping) return; // Bond court : distance max 120 px par bond var dx = self.targetX - self.x; var maxDist = 120; if (Math.abs(dx) > maxDist) { self.jumpTargetX = self.x + (dx > 0 ? maxDist : -maxDist); } else { self.jumpTargetX = self.targetX; } // Cible Y = voie choisie self.jumpStartY = self.y; self.jumpStartX = self.x; self.jumpTargetY = laneY(self.targetLane); self.jumpProgress = 0; self.isJumping = true; }; // Pour compatibilité avec l'ancien code (tap simple) self.jump = function () { if (self.isJumping) return; self.targetLane = self.lane; self.targetX = self.x + 80; // bond court vers la droite self.prepareJump(); }; return self; }); // Classe pour les obstacles (arbres) var TreeObstacle = Container.expand(function () { var self = Container.call(this); var tree = self.attachAsset('tree', { anchorX: 0.5, anchorY: 1 }); self.width = tree.width; self.height = tree.height; self.lane = 0; self.update = function () { // Les obstacles ne bougent pas, mais pourraient bouger à haut niveau if (level >= 4) { // Oscillation horizontale self.x += Math.sin(LK.ticks / 40 + self.lane) * 0.7; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2e3c1c }); /**** * Game Code ****/ // Ajout de l'asset image de fond personnalisé (remplacez l'id par celui de votre image) // --- Variables globales --- // Abeille du joueur // Abeilles adversaires (4 couleurs différentes) // Obstacles (arbres) // Ligne d'arrivée var level = storage.level || 1; var lanes = [0, 1, 2, 3, 4]; // 5 voies horizontales var laneSpacing = 350; var startX = 200; var finishX = 2048 - 200; var playerBee; var enemyBees = []; var obstacles = []; var finishLine; var scoreTxt; var levelTxt; var dragNode = null; var gameOver = false; // --- Fonctions utilitaires --- function laneY(lane) { // Espace verticalement les voies return 500 + lane * laneSpacing; } // --- Initialisation du jeu --- function setupGame() { // Nettoyage game.removeChildren(); enemyBees = []; obstacles = []; gameOver = false; // Ajout de l'image de fond personnalisé (doit être le premier enfant pour être en fond) var bg = LK.getAsset('forest_bg', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(bg); // Ligne d'arrivée finishLine = LK.getAsset('finish_line', { anchorX: 0, anchorY: 0 }); finishLine.x = 0; finishLine.y = 350; game.addChild(finishLine); // Score (niveau) if (!scoreTxt) { scoreTxt = new Text2('Niveau: ' + level, { size: 90, fill: '#ff69b4' //{1f} // Rose }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); } scoreTxt.setText('Niveau: ' + level); // Affichage du niveau (en haut à droite) if (!levelTxt) { levelTxt = new Text2('', { size: 60, fill: '#ff69b4' //{1i} // Rose }); levelTxt.anchor.set(1, 0); LK.gui.topRight.addChild(levelTxt); } levelTxt.setText('Course des abeilles'); // Joueur playerBee = new PlayerBee(); playerBee.lane = 2; playerBee.x = startX; playerBee.y = laneY(playerBee.lane); game.addChild(playerBee); // Abeilles adversaires for (var i = 0; i < 4; i++) { var bee = new EnemyBee(); bee.colorId = i + 1; bee.lane = i < 2 ? i : i + 1; // Sauter la voie centrale pour le joueur bee.x = startX; bee.y = laneY(bee.lane); bee.speed = 7 + level * 1.5 + Math.random() * 2; game.addChild(bee); enemyBees.push(bee); } // Obstacles var nbObstacles = 3 + Math.floor(level * 0.7); for (var i = 0; i < nbObstacles; i++) { var obs = new TreeObstacle(); obs.lane = Math.floor(Math.random() * 5); obs.x = 600 + Math.random() * (finishX - 800); obs.y = laneY(obs.lane) + 60; game.addChild(obs); obstacles.push(obs); } // Ligne d'arrivée (visuelle) finishLine.y = laneY(0) - 80; finishLine.height = laneSpacing * 5 + 60; } // --- Contrôles joueur --- // Permet de déplacer l'abeille du joueur vers la position touchée (tap ou drag), avec un bond court à chaque appui game.down = function (x, y, obj) { if (gameOver) return; // On convertit la position touchée en coordonnées de jeu var local = game.toLocal({ x: x, y: y }); // On cherche la voie la plus proche de la position touchée var minDist = Infinity; var bestLane = playerBee.lane; for (var i = 0; i < lanes.length; i++) { var ly = laneY(lanes[i]); var dist = Math.abs(local.y - ly); if (dist < minDist) { minDist = dist; bestLane = lanes[i]; } } // On déplace l'abeille sur la voie la plus proche et on prépare le bond playerBee.targetLane = bestLane; playerBee.targetX = Math.min(local.x, finishX); // Ne pas dépasser la ligne d'arrivée playerBee.prepareJump(); }; game.move = function (x, y, obj) { if (gameOver) return; // Permet de déplacer l'abeille en glissant le doigt (drag) var local = game.toLocal({ x: x, y: y }); var minDist = Infinity; var bestLane = playerBee.lane; for (var i = 0; i < lanes.length; i++) { var ly = laneY(lanes[i]); var dist = Math.abs(local.y - ly); if (dist < minDist) { minDist = dist; bestLane = lanes[i]; } } playerBee.targetLane = bestLane; playerBee.targetX = Math.min(local.x, finishX); playerBee.prepareJump(); }; game.up = function (x, y, obj) { // Rien à faire ici }; // --- Boucle principale --- game.update = function () { if (gameOver) return; // Update player playerBee.update(); // Update ennemis for (var i = 0; i < enemyBees.length; i++) { var bee = enemyBees[i]; bee.update(); bee.tryAvoid(obstacles); } // Update obstacles for (var i = 0; i < obstacles.length; i++) { obstacles[i].update(); } // --- Collisions joueur/obstacles --- for (var i = 0; i < obstacles.length; i++) { var obs = obstacles[i]; // Collision si même voie et x proche if (playerBee.lane === obs.lane && Math.abs(playerBee.x - obs.x) < 70) { // Perdu ! LK.effects.flashScreen(0xff0000, 800); gameOver = true; storage.level = 1; LK.setTimeout(function () { LK.showGameOver(); }, 700); return; } } // --- Collisions ennemis/obstacles (ils évitent, mais si collision, ralentissent) --- for (var i = 0; i < enemyBees.length; i++) { var bee = enemyBees[i]; for (var j = 0; j < obstacles.length; j++) { var obs = obstacles[j]; if (bee.lane === obs.lane && Math.abs(bee.x - obs.x) < 70) { bee.speed *= 0.7; } } } // --- Arrivée joueur --- if (playerBee.x >= finishX) { // Gagné ! LK.effects.flashScreen(0xffff00, 800); gameOver = true; storage.level = level + 1; LK.setTimeout(function () { LK.showYouWin(); }, 700); return; } // --- Arrivée ennemis --- for (var i = 0; i < enemyBees.length; i++) { if (enemyBees[i].x >= finishX) { // Perdu ! LK.effects.flashScreen(0xff0000, 800); gameOver = true; storage.level = 1; LK.setTimeout(function () { LK.showGameOver(); }, 700); return; } } }; // --- Démarrage --- setupGame(); LK.playMusic('bee_race_music'); // --- Gestion du reset automatique par LK --- LK.on('reset', function () { level = storage.level || 1; setupGame(); });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
level: 1
});
/****
* Classes
****/
// Classe pour les abeilles adversaires
var EnemyBee = Container.expand(function () {
var self = Container.call(this);
// Couleur différente selon l'index
var colorId = self.colorId || 1;
var assetId = 'bee_enemy' + colorId;
var bee = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bee.width;
self.height = bee.height;
self.lane = 0;
self.speed = 0;
self.avoidCooldown = 0;
self.update = function () {
// Avance automatiquement
self.x += self.speed;
// Petite oscillation pour donner vie
bee.y = Math.sin(LK.ticks / 20 + self.lane) * 10;
};
// Pour éviter un obstacle, saute sur le côté (change de voie)
self.tryAvoid = function (obstacles) {
if (self.avoidCooldown > 0) {
self.avoidCooldown--;
return;
}
// Si un obstacle est proche devant, tente d'éviter
for (var i = 0; i < obstacles.length; i++) {
var obs = obstacles[i];
if (obs.lane === self.lane && obs.x > self.x && obs.x - self.x < 180) {
// Tente de changer de voie (aléatoire)
var dirs = [];
if (self.lane > 0) dirs.push(-1);
if (self.lane < 4) dirs.push(1);
if (dirs.length > 0) {
var dir = dirs[Math.floor(Math.random() * dirs.length)];
self.lane += dir;
self.y = laneY(self.lane);
self.avoidCooldown = 30 + Math.floor(Math.random() * 20);
}
break;
}
}
};
return self;
});
// Classe pour l'abeille du joueur
var PlayerBee = Container.expand(function () {
var self = Container.call(this);
var bee = self.attachAsset('bee_player', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bee.width;
self.height = bee.height;
self.lane = 2; // Par défaut, voie centrale (0-4)
self.isJumping = false;
self.jumpStartY = 0;
self.jumpStartX = 0;
self.jumpTargetY = 0;
self.jumpTargetX = 0;
self.jumpProgress = 0;
self.jumpDuration = 10; // frames, bond plus court
self.targetLane = self.lane;
self.targetX = 0;
self.update = function () {
// Synchronise la vitesse de déplacement avec les abeilles adversaires
// On prend la vitesse moyenne des ennemis pour la course actuelle
var avgSpeed = 0;
if (typeof enemyBees !== "undefined" && enemyBees.length > 0) {
var total = 0;
for (var i = 0; i < enemyBees.length; i++) {
total += enemyBees[i].speed;
}
avgSpeed = total / enemyBees.length;
} else {
avgSpeed = 7 + level * 1.5; // fallback
}
// Gestion du bond (court et latéral)
if (self.isJumping) {
self.jumpProgress++;
var t = self.jumpProgress / self.jumpDuration;
// Interpolation linéaire pour X et Y
self.x = self.jumpStartX + (self.jumpTargetX - self.jumpStartX) * t;
self.y = self.jumpStartY + (self.jumpTargetY - self.jumpStartY) * t - Math.sin(Math.PI * t) * 40;
if (self.jumpProgress >= self.jumpDuration) {
self.isJumping = false;
self.x = self.jumpTargetX;
self.y = self.jumpTargetY;
self.lane = self.targetLane;
}
} else {
// Si pas en saut, avance automatiquement à la même vitesse que les ennemis
self.x += avgSpeed;
}
};
// Prépare un bond court vers la position cible (tap ou drag)
self.prepareJump = function () {
if (self.isJumping) return;
// Bond court : distance max 120 px par bond
var dx = self.targetX - self.x;
var maxDist = 120;
if (Math.abs(dx) > maxDist) {
self.jumpTargetX = self.x + (dx > 0 ? maxDist : -maxDist);
} else {
self.jumpTargetX = self.targetX;
}
// Cible Y = voie choisie
self.jumpStartY = self.y;
self.jumpStartX = self.x;
self.jumpTargetY = laneY(self.targetLane);
self.jumpProgress = 0;
self.isJumping = true;
};
// Pour compatibilité avec l'ancien code (tap simple)
self.jump = function () {
if (self.isJumping) return;
self.targetLane = self.lane;
self.targetX = self.x + 80; // bond court vers la droite
self.prepareJump();
};
return self;
});
// Classe pour les obstacles (arbres)
var TreeObstacle = Container.expand(function () {
var self = Container.call(this);
var tree = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 1
});
self.width = tree.width;
self.height = tree.height;
self.lane = 0;
self.update = function () {
// Les obstacles ne bougent pas, mais pourraient bouger à haut niveau
if (level >= 4) {
// Oscillation horizontale
self.x += Math.sin(LK.ticks / 40 + self.lane) * 0.7;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2e3c1c
});
/****
* Game Code
****/
// Ajout de l'asset image de fond personnalisé (remplacez l'id par celui de votre image)
// --- Variables globales ---
// Abeille du joueur
// Abeilles adversaires (4 couleurs différentes)
// Obstacles (arbres)
// Ligne d'arrivée
var level = storage.level || 1;
var lanes = [0, 1, 2, 3, 4]; // 5 voies horizontales
var laneSpacing = 350;
var startX = 200;
var finishX = 2048 - 200;
var playerBee;
var enemyBees = [];
var obstacles = [];
var finishLine;
var scoreTxt;
var levelTxt;
var dragNode = null;
var gameOver = false;
// --- Fonctions utilitaires ---
function laneY(lane) {
// Espace verticalement les voies
return 500 + lane * laneSpacing;
}
// --- Initialisation du jeu ---
function setupGame() {
// Nettoyage
game.removeChildren();
enemyBees = [];
obstacles = [];
gameOver = false;
// Ajout de l'image de fond personnalisé (doit être le premier enfant pour être en fond)
var bg = LK.getAsset('forest_bg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(bg);
// Ligne d'arrivée
finishLine = LK.getAsset('finish_line', {
anchorX: 0,
anchorY: 0
});
finishLine.x = 0;
finishLine.y = 350;
game.addChild(finishLine);
// Score (niveau)
if (!scoreTxt) {
scoreTxt = new Text2('Niveau: ' + level, {
size: 90,
fill: '#ff69b4' //{1f} // Rose
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
}
scoreTxt.setText('Niveau: ' + level);
// Affichage du niveau (en haut à droite)
if (!levelTxt) {
levelTxt = new Text2('', {
size: 60,
fill: '#ff69b4' //{1i} // Rose
});
levelTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(levelTxt);
}
levelTxt.setText('Course des abeilles');
// Joueur
playerBee = new PlayerBee();
playerBee.lane = 2;
playerBee.x = startX;
playerBee.y = laneY(playerBee.lane);
game.addChild(playerBee);
// Abeilles adversaires
for (var i = 0; i < 4; i++) {
var bee = new EnemyBee();
bee.colorId = i + 1;
bee.lane = i < 2 ? i : i + 1; // Sauter la voie centrale pour le joueur
bee.x = startX;
bee.y = laneY(bee.lane);
bee.speed = 7 + level * 1.5 + Math.random() * 2;
game.addChild(bee);
enemyBees.push(bee);
}
// Obstacles
var nbObstacles = 3 + Math.floor(level * 0.7);
for (var i = 0; i < nbObstacles; i++) {
var obs = new TreeObstacle();
obs.lane = Math.floor(Math.random() * 5);
obs.x = 600 + Math.random() * (finishX - 800);
obs.y = laneY(obs.lane) + 60;
game.addChild(obs);
obstacles.push(obs);
}
// Ligne d'arrivée (visuelle)
finishLine.y = laneY(0) - 80;
finishLine.height = laneSpacing * 5 + 60;
}
// --- Contrôles joueur ---
// Permet de déplacer l'abeille du joueur vers la position touchée (tap ou drag), avec un bond court à chaque appui
game.down = function (x, y, obj) {
if (gameOver) return;
// On convertit la position touchée en coordonnées de jeu
var local = game.toLocal({
x: x,
y: y
});
// On cherche la voie la plus proche de la position touchée
var minDist = Infinity;
var bestLane = playerBee.lane;
for (var i = 0; i < lanes.length; i++) {
var ly = laneY(lanes[i]);
var dist = Math.abs(local.y - ly);
if (dist < minDist) {
minDist = dist;
bestLane = lanes[i];
}
}
// On déplace l'abeille sur la voie la plus proche et on prépare le bond
playerBee.targetLane = bestLane;
playerBee.targetX = Math.min(local.x, finishX); // Ne pas dépasser la ligne d'arrivée
playerBee.prepareJump();
};
game.move = function (x, y, obj) {
if (gameOver) return;
// Permet de déplacer l'abeille en glissant le doigt (drag)
var local = game.toLocal({
x: x,
y: y
});
var minDist = Infinity;
var bestLane = playerBee.lane;
for (var i = 0; i < lanes.length; i++) {
var ly = laneY(lanes[i]);
var dist = Math.abs(local.y - ly);
if (dist < minDist) {
minDist = dist;
bestLane = lanes[i];
}
}
playerBee.targetLane = bestLane;
playerBee.targetX = Math.min(local.x, finishX);
playerBee.prepareJump();
};
game.up = function (x, y, obj) {
// Rien à faire ici
};
// --- Boucle principale ---
game.update = function () {
if (gameOver) return;
// Update player
playerBee.update();
// Update ennemis
for (var i = 0; i < enemyBees.length; i++) {
var bee = enemyBees[i];
bee.update();
bee.tryAvoid(obstacles);
}
// Update obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].update();
}
// --- Collisions joueur/obstacles ---
for (var i = 0; i < obstacles.length; i++) {
var obs = obstacles[i];
// Collision si même voie et x proche
if (playerBee.lane === obs.lane && Math.abs(playerBee.x - obs.x) < 70) {
// Perdu !
LK.effects.flashScreen(0xff0000, 800);
gameOver = true;
storage.level = 1;
LK.setTimeout(function () {
LK.showGameOver();
}, 700);
return;
}
}
// --- Collisions ennemis/obstacles (ils évitent, mais si collision, ralentissent) ---
for (var i = 0; i < enemyBees.length; i++) {
var bee = enemyBees[i];
for (var j = 0; j < obstacles.length; j++) {
var obs = obstacles[j];
if (bee.lane === obs.lane && Math.abs(bee.x - obs.x) < 70) {
bee.speed *= 0.7;
}
}
}
// --- Arrivée joueur ---
if (playerBee.x >= finishX) {
// Gagné !
LK.effects.flashScreen(0xffff00, 800);
gameOver = true;
storage.level = level + 1;
LK.setTimeout(function () {
LK.showYouWin();
}, 700);
return;
}
// --- Arrivée ennemis ---
for (var i = 0; i < enemyBees.length; i++) {
if (enemyBees[i].x >= finishX) {
// Perdu !
LK.effects.flashScreen(0xff0000, 800);
gameOver = true;
storage.level = 1;
LK.setTimeout(function () {
LK.showGameOver();
}, 700);
return;
}
}
};
// --- Démarrage ---
setupGame();
LK.playMusic('bee_race_music');
// --- Gestion du reset automatique par LK ---
LK.on('reset', function () {
level = storage.level || 1;
setupGame();
});
Arbre. In-Game asset. 2d. High contrast. No shadows
Abeille rouge. In-Game asset. 2d. High contrast. No shadows
Abeille bleu. In-Game asset. 2d. High contrast. No shadows
Abeille verte. In-Game asset. 2d. High contrast. No shadows
Abeille orange. In-Game asset. 2d. High contrast. No shadows
Abeille jaune. In-Game asset. 2d. High contrast. No shadows
Fond d'écran forêt. In-Game asset. 2d. High contrast. No shadows