User prompt
Je veux personnalisé le fond du jeu avec mon propre asset
User prompt
Ajoute une musique de fond en boucle au jeu
User prompt
Le nombre de tuyaux a passer avant le niveau suivant doit doubler a chaque niveau par rapport au niveau précédent
Code edit (1 edits merged)
Please save this source code
User prompt
Jahia Flappy
Initial prompt
Crée "Jahia Flappy" un jeu Flappy bird sous qu'au lieu de L'oiseau, c'est Jahia l'abeille qui doit passer entre des tuyaux roses le fond du jeu doit être une forêt, le jeu est un jeu de plateforme sur lequel le joueur doit taper pour maintenir Jahia en l'air et la faire passer entre des tuyaux, Les différences avec le Flappy bird classique, Est que dans Jahia Flappy, il y a un système de niveaux : le nombre de tuyaux passés par Jahia est compté, et plus Jahia passe de tuyaux sans entrer en collisions avec eux, plus elle peut monter de niveau, Faut passer 3 tuyaux pour passer du niveau 1 au niveau 2, Puis à chaque fois ça double par rapport au niveau précédent Le niveau actuel du joueur et son nombre de tuyaux restants avant d'atteindre le niveau supérieur est affiché a l'écran (les tuyaux seront roses avec des graphismes de fleurs) Plus le niveau est élevé, plus des complications supplémentaires s'ajoutent : A partir du niveau 3, des guêpes apparaissent aléatoirement à côté des tuyaux et si Jahia/le joueur entre en collision avec elles, il doit recommencer le jeu depuis le début, Il y a qu'une seule guêpe entre le niveau 3 et 5, puis 2 du niveau 5 a 7, Puis 3 etc...comme ça une se rajoute tout les 2 niveaux A partir du niveau 20, des pesticides représentés par des signes dangereux voleront aléatoirement dans le ciel, si Jahia/le joueur les touchent il recommence le jeu depuis le début
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Jahia (the bee) class var Jahia = Container.expand(function () { var self = Container.call(this); // Attach bee asset (yellow ellipse with black stripes) var beeBody = self.attachAsset('jahiaBody', { anchorX: 0.5, anchorY: 0.5 }); // Add stripes as separate shapes var stripe1 = self.attachAsset('jahiaStripe1', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -20 }); var stripe2 = self.attachAsset('jahiaStripe2', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); var stripe3 = self.attachAsset('jahiaStripe3', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 20 }); // Add wings var wingL = self.attachAsset('jahiaWingL', { anchorX: 0.5, anchorY: 0.5, x: -40, y: -30 }); var wingR = self.attachAsset('jahiaWingR', { anchorX: 0.5, anchorY: 0.5, x: 40, y: -30 }); self.vy = 0; // vertical speed self.gravity = 1.5; // gravity self.flapStrength = -32; // upward velocity on tap self.alive = true; self.update = function () { if (!self.alive) return; self.vy += self.gravity; self.y += self.vy; // Clamp rotation based on vy self.rotation = Math.max(-0.5, Math.min(1.0, self.vy / 40)); // Prevent bee from going off the top if (self.y < beeMinY) { self.y = beeMinY; self.vy = 0; } // If bee falls below screen, trigger game over if (self.y > beeMaxY) { self.y = beeMaxY; self.vy = 0; self.die(); } }; self.flap = function () { if (!self.alive) return; self.vy = self.flapStrength; // Animate wings tween(wingL, { rotation: -0.7 }, { duration: 80, easing: tween.cubicOut, onFinish: function onFinish() { tween(wingL, { rotation: 0 }, { duration: 120, easing: tween.cubicIn }); } }); tween(wingR, { rotation: 0.7 }, { duration: 80, easing: tween.cubicOut, onFinish: function onFinish() { tween(wingR, { rotation: 0 }, { duration: 120, easing: tween.cubicIn }); } }); }; self.die = function () { if (!self.alive) return; self.alive = false; LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); }; return self; }); // Pesticide enemy class var Pesticide = Container.expand(function () { var self = Container.call(this); var pestBody = self.attachAsset('pestBody', { anchorX: 0.5, anchorY: 0.5 }); var pestSpray = self.attachAsset('pestSpray', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 40 }); self.vx = -pestSpeed; self.vy = Math.random() > 0.5 ? 2 : -2; self.update = function () { self.x += self.vx; self.y += self.vy; // Bounce off top/bottom if (self.y < beeMinY + 80 || self.y > beeMaxY - 80) { self.vy *= -1; } }; return self; }); // Pipe class (top or bottom) var Pipe = Container.expand(function () { var self = Container.call(this); // Attach pipe asset (pink box with flower) var pipeBody = self.attachAsset('pipeBody', { anchorX: 0.5, anchorY: 0.0 }); var flower = self.attachAsset('pipeFlower', { anchorX: 0.5, anchorY: 0.0, y: -40 }); self.passed = false; // Has bee passed this pipe pair? self.update = function () { self.x -= pipeSpeed; }; return self; }); // Wasp enemy class var Wasp = Container.expand(function () { var self = Container.call(this); var waspBody = self.attachAsset('waspBody', { anchorX: 0.5, anchorY: 0.5 }); var waspWingL = self.attachAsset('waspWingL', { anchorX: 0.5, anchorY: 0.5, x: -30, y: -20 }); var waspWingR = self.attachAsset('waspWingR', { anchorX: 0.5, anchorY: 0.5, x: 30, y: -20 }); self.vx = -waspSpeed; self.amp = 60 + Math.random() * 40; self.phase = Math.random() * Math.PI * 2; self.update = function () { self.x += self.vx; self.y += Math.sin(LK.ticks / 20 + self.phase) * 2; // Animate wings waspWingL.rotation = Math.sin(LK.ticks / 3) * 0.5; waspWingR.rotation = -Math.sin(LK.ticks / 3) * 0.5; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xbee6e0 // Soft blue-green for forest sky }); /**** * Game Code ****/ // Custom forest background asset (replace 'your_forest_asset_id' with your actual asset id) // Game constants var beeStartX = 500; var beeStartY = 1366; var beeMinY = 120; var beeMaxY = 2732 - 120; var pipeGap = 420; var pipeMinY = 350; var pipeMaxY = 2732 - 350 - pipeGap; var pipeSpeed = 16; var waspSpeed = 18; var pestSpeed = 20; var pipeInterval = 120; // frames between pipes var pipes = []; var wasps = []; var pests = []; var nextPipeTick = 0; var nextWaspTick = 0; var nextPestTick = 0; var score = 0; var level = 1; var pipesToNextLevel = 3; var pipesPassedThisLevel = 0; var gameStarted = false; // Add forest background image behind all gameplay elements var forestBg = LK.getAsset('forestBg', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(forestBg); // Create bee var jahia = new Jahia(); game.addChild(jahia); jahia.x = beeStartX; jahia.y = beeStartY; // Play looping background music LK.playMusic('bgmusic'); // GUI: Score, Level, Pipes to next level var scoreTxt = new Text2('0', { size: 120, fill: 0xFFF000 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var levelTxt = new Text2('Niveau 1', { size: 70, fill: 0xFFFFFF }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); levelTxt.y = 130; var nextLevelTxt = new Text2('Tuyaux avant niveau suivant: 3', { size: 60, fill: 0xFFFFFF }); nextLevelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(nextLevelTxt); nextLevelTxt.y = 220; // Helper: create a pipe pair (top and bottom) function createPipePair() { var gapY = pipeMinY + Math.random() * (pipeMaxY - pipeMinY); // Top pipe var topPipe = new Pipe(); topPipe.x = 2048 + 120; topPipe.y = gapY - pipeGap / 2 - 600; // pipe height is 600 topPipe.isTop = true; game.addChild(topPipe); pipes.push(topPipe); // Bottom pipe var bottomPipe = new Pipe(); bottomPipe.x = 2048 + 120; bottomPipe.y = gapY + pipeGap / 2; bottomPipe.isTop = false; game.addChild(bottomPipe); pipes.push(bottomPipe); } // Helper: create a wasp function createWasp() { var y = beeMinY + 100 + Math.random() * (beeMaxY - beeMinY - 200); var wasp = new Wasp(); wasp.x = 2048 + 120; wasp.y = y; game.addChild(wasp); wasps.push(wasp); } // Helper: create a pesticide function createPesticide() { var y = beeMinY + 100 + Math.random() * (beeMaxY - beeMinY - 200); var pest = new Pesticide(); pest.x = 2048 + 120; pest.y = y; game.addChild(pest); pests.push(pest); } // Start game on first tap function startGame() { if (gameStarted) return; gameStarted = true; jahia.flap(); } // Tap to flap game.down = function (x, y, obj) { if (!jahia.alive) return; if (!gameStarted) { startGame(); return; } jahia.flap(); }; // Main update loop game.update = function () { if (!jahia.alive) return; // Only start spawning pipes after first tap if (!gameStarted) return; // Update bee jahia.update(); // Spawn pipes if (LK.ticks >= nextPipeTick) { createPipePair(); nextPipeTick = LK.ticks + pipeInterval; } // Update pipes for (var i = pipes.length - 1; i >= 0; i--) { var pipe = pipes[i]; pipe.update(); // Remove pipes off screen if (pipe.x < -200) { pipe.destroy(); pipes.splice(i, 1); continue; } // Collision with bee if (jahia.intersects(pipe)) { jahia.die(); return; } // Score: only on bottom pipe, once per pair if (!pipe.passed && !pipe.isTop && pipe.x + 80 < jahia.x) { pipe.passed = true; score += 1; pipesPassedThisLevel += 1; LK.setScore(score); scoreTxt.setText(score); // Level up if (pipesPassedThisLevel >= pipesToNextLevel) { level += 1; pipesPassedThisLevel = 0; levelTxt.setText('Niveau ' + level); // Double the number of pipes needed for next level, starting from 3 for level 1 if (level === 1) { pipesToNextLevel = 3; } else { pipesToNextLevel = pipesToNextLevel * 2; } // Increase difficulty if (level < 10) { pipeSpeed += 1; } else if (level < 20) { pipeSpeed += 0.5; } // More frequent pipes if (pipeInterval > 70) { pipeInterval -= 4; } } nextLevelTxt.setText('Tuyaux avant niveau suivant: ' + (pipesToNextLevel - pipesPassedThisLevel)); } } // Spawn wasps from level 5 if (level >= 5 && LK.ticks >= nextWaspTick) { createWasp(); nextWaspTick = LK.ticks + Math.max(90, 300 - level * 10); } // Update wasps for (var i = wasps.length - 1; i >= 0; i--) { var wasp = wasps[i]; wasp.update(); if (wasp.x < -200) { wasp.destroy(); wasps.splice(i, 1); continue; } if (jahia.intersects(wasp)) { jahia.die(); return; } } // Spawn pesticides from level 20 if (level >= 20 && LK.ticks >= nextPestTick) { createPesticide(); nextPestTick = LK.ticks + Math.max(120, 400 - (level - 20) * 8); } // Update pesticides for (var i = pests.length - 1; i >= 0; i--) { var pest = pests[i]; pest.update(); if (pest.x < -200) { pest.destroy(); pests.splice(i, 1); continue; } if (jahia.intersects(pest)) { jahia.die(); return; } } }; // Reset game state on game over (handled by LK, but clear arrays for safety) game.onDestroy = function () { pipes = []; wasps = []; pests = []; score = 0; level = 1; pipesPassedThisLevel = 0; pipesToNextLevel = 3; pipeSpeed = 16; pipeInterval = 120; gameStarted = false; }; /**** * Asset Definitions (for LK static analysis) ****/ // Bee body (yellow ellipse) // Bee stripes (black boxes) // Bee wings (white ellipses) // Pipe body (pink box) // Pipe flower (small yellow ellipse) // Wasp body (black/yellow ellipse) // Pesticide (green box with white spray)
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Jahia (the bee) class
var Jahia = Container.expand(function () {
var self = Container.call(this);
// Attach bee asset (yellow ellipse with black stripes)
var beeBody = self.attachAsset('jahiaBody', {
anchorX: 0.5,
anchorY: 0.5
});
// Add stripes as separate shapes
var stripe1 = self.attachAsset('jahiaStripe1', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -20
});
var stripe2 = self.attachAsset('jahiaStripe2', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
var stripe3 = self.attachAsset('jahiaStripe3', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 20
});
// Add wings
var wingL = self.attachAsset('jahiaWingL', {
anchorX: 0.5,
anchorY: 0.5,
x: -40,
y: -30
});
var wingR = self.attachAsset('jahiaWingR', {
anchorX: 0.5,
anchorY: 0.5,
x: 40,
y: -30
});
self.vy = 0; // vertical speed
self.gravity = 1.5; // gravity
self.flapStrength = -32; // upward velocity on tap
self.alive = true;
self.update = function () {
if (!self.alive) return;
self.vy += self.gravity;
self.y += self.vy;
// Clamp rotation based on vy
self.rotation = Math.max(-0.5, Math.min(1.0, self.vy / 40));
// Prevent bee from going off the top
if (self.y < beeMinY) {
self.y = beeMinY;
self.vy = 0;
}
// If bee falls below screen, trigger game over
if (self.y > beeMaxY) {
self.y = beeMaxY;
self.vy = 0;
self.die();
}
};
self.flap = function () {
if (!self.alive) return;
self.vy = self.flapStrength;
// Animate wings
tween(wingL, {
rotation: -0.7
}, {
duration: 80,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(wingL, {
rotation: 0
}, {
duration: 120,
easing: tween.cubicIn
});
}
});
tween(wingR, {
rotation: 0.7
}, {
duration: 80,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(wingR, {
rotation: 0
}, {
duration: 120,
easing: tween.cubicIn
});
}
});
};
self.die = function () {
if (!self.alive) return;
self.alive = false;
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
};
return self;
});
// Pesticide enemy class
var Pesticide = Container.expand(function () {
var self = Container.call(this);
var pestBody = self.attachAsset('pestBody', {
anchorX: 0.5,
anchorY: 0.5
});
var pestSpray = self.attachAsset('pestSpray', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 40
});
self.vx = -pestSpeed;
self.vy = Math.random() > 0.5 ? 2 : -2;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
// Bounce off top/bottom
if (self.y < beeMinY + 80 || self.y > beeMaxY - 80) {
self.vy *= -1;
}
};
return self;
});
// Pipe class (top or bottom)
var Pipe = Container.expand(function () {
var self = Container.call(this);
// Attach pipe asset (pink box with flower)
var pipeBody = self.attachAsset('pipeBody', {
anchorX: 0.5,
anchorY: 0.0
});
var flower = self.attachAsset('pipeFlower', {
anchorX: 0.5,
anchorY: 0.0,
y: -40
});
self.passed = false; // Has bee passed this pipe pair?
self.update = function () {
self.x -= pipeSpeed;
};
return self;
});
// Wasp enemy class
var Wasp = Container.expand(function () {
var self = Container.call(this);
var waspBody = self.attachAsset('waspBody', {
anchorX: 0.5,
anchorY: 0.5
});
var waspWingL = self.attachAsset('waspWingL', {
anchorX: 0.5,
anchorY: 0.5,
x: -30,
y: -20
});
var waspWingR = self.attachAsset('waspWingR', {
anchorX: 0.5,
anchorY: 0.5,
x: 30,
y: -20
});
self.vx = -waspSpeed;
self.amp = 60 + Math.random() * 40;
self.phase = Math.random() * Math.PI * 2;
self.update = function () {
self.x += self.vx;
self.y += Math.sin(LK.ticks / 20 + self.phase) * 2;
// Animate wings
waspWingL.rotation = Math.sin(LK.ticks / 3) * 0.5;
waspWingR.rotation = -Math.sin(LK.ticks / 3) * 0.5;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xbee6e0 // Soft blue-green for forest sky
});
/****
* Game Code
****/
// Custom forest background asset (replace 'your_forest_asset_id' with your actual asset id)
// Game constants
var beeStartX = 500;
var beeStartY = 1366;
var beeMinY = 120;
var beeMaxY = 2732 - 120;
var pipeGap = 420;
var pipeMinY = 350;
var pipeMaxY = 2732 - 350 - pipeGap;
var pipeSpeed = 16;
var waspSpeed = 18;
var pestSpeed = 20;
var pipeInterval = 120; // frames between pipes
var pipes = [];
var wasps = [];
var pests = [];
var nextPipeTick = 0;
var nextWaspTick = 0;
var nextPestTick = 0;
var score = 0;
var level = 1;
var pipesToNextLevel = 3;
var pipesPassedThisLevel = 0;
var gameStarted = false;
// Add forest background image behind all gameplay elements
var forestBg = LK.getAsset('forestBg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(forestBg);
// Create bee
var jahia = new Jahia();
game.addChild(jahia);
jahia.x = beeStartX;
jahia.y = beeStartY;
// Play looping background music
LK.playMusic('bgmusic');
// GUI: Score, Level, Pipes to next level
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFF000
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var levelTxt = new Text2('Niveau 1', {
size: 70,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
levelTxt.y = 130;
var nextLevelTxt = new Text2('Tuyaux avant niveau suivant: 3', {
size: 60,
fill: 0xFFFFFF
});
nextLevelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(nextLevelTxt);
nextLevelTxt.y = 220;
// Helper: create a pipe pair (top and bottom)
function createPipePair() {
var gapY = pipeMinY + Math.random() * (pipeMaxY - pipeMinY);
// Top pipe
var topPipe = new Pipe();
topPipe.x = 2048 + 120;
topPipe.y = gapY - pipeGap / 2 - 600; // pipe height is 600
topPipe.isTop = true;
game.addChild(topPipe);
pipes.push(topPipe);
// Bottom pipe
var bottomPipe = new Pipe();
bottomPipe.x = 2048 + 120;
bottomPipe.y = gapY + pipeGap / 2;
bottomPipe.isTop = false;
game.addChild(bottomPipe);
pipes.push(bottomPipe);
}
// Helper: create a wasp
function createWasp() {
var y = beeMinY + 100 + Math.random() * (beeMaxY - beeMinY - 200);
var wasp = new Wasp();
wasp.x = 2048 + 120;
wasp.y = y;
game.addChild(wasp);
wasps.push(wasp);
}
// Helper: create a pesticide
function createPesticide() {
var y = beeMinY + 100 + Math.random() * (beeMaxY - beeMinY - 200);
var pest = new Pesticide();
pest.x = 2048 + 120;
pest.y = y;
game.addChild(pest);
pests.push(pest);
}
// Start game on first tap
function startGame() {
if (gameStarted) return;
gameStarted = true;
jahia.flap();
}
// Tap to flap
game.down = function (x, y, obj) {
if (!jahia.alive) return;
if (!gameStarted) {
startGame();
return;
}
jahia.flap();
};
// Main update loop
game.update = function () {
if (!jahia.alive) return;
// Only start spawning pipes after first tap
if (!gameStarted) return;
// Update bee
jahia.update();
// Spawn pipes
if (LK.ticks >= nextPipeTick) {
createPipePair();
nextPipeTick = LK.ticks + pipeInterval;
}
// Update pipes
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
pipe.update();
// Remove pipes off screen
if (pipe.x < -200) {
pipe.destroy();
pipes.splice(i, 1);
continue;
}
// Collision with bee
if (jahia.intersects(pipe)) {
jahia.die();
return;
}
// Score: only on bottom pipe, once per pair
if (!pipe.passed && !pipe.isTop && pipe.x + 80 < jahia.x) {
pipe.passed = true;
score += 1;
pipesPassedThisLevel += 1;
LK.setScore(score);
scoreTxt.setText(score);
// Level up
if (pipesPassedThisLevel >= pipesToNextLevel) {
level += 1;
pipesPassedThisLevel = 0;
levelTxt.setText('Niveau ' + level);
// Double the number of pipes needed for next level, starting from 3 for level 1
if (level === 1) {
pipesToNextLevel = 3;
} else {
pipesToNextLevel = pipesToNextLevel * 2;
}
// Increase difficulty
if (level < 10) {
pipeSpeed += 1;
} else if (level < 20) {
pipeSpeed += 0.5;
}
// More frequent pipes
if (pipeInterval > 70) {
pipeInterval -= 4;
}
}
nextLevelTxt.setText('Tuyaux avant niveau suivant: ' + (pipesToNextLevel - pipesPassedThisLevel));
}
}
// Spawn wasps from level 5
if (level >= 5 && LK.ticks >= nextWaspTick) {
createWasp();
nextWaspTick = LK.ticks + Math.max(90, 300 - level * 10);
}
// Update wasps
for (var i = wasps.length - 1; i >= 0; i--) {
var wasp = wasps[i];
wasp.update();
if (wasp.x < -200) {
wasp.destroy();
wasps.splice(i, 1);
continue;
}
if (jahia.intersects(wasp)) {
jahia.die();
return;
}
}
// Spawn pesticides from level 20
if (level >= 20 && LK.ticks >= nextPestTick) {
createPesticide();
nextPestTick = LK.ticks + Math.max(120, 400 - (level - 20) * 8);
}
// Update pesticides
for (var i = pests.length - 1; i >= 0; i--) {
var pest = pests[i];
pest.update();
if (pest.x < -200) {
pest.destroy();
pests.splice(i, 1);
continue;
}
if (jahia.intersects(pest)) {
jahia.die();
return;
}
}
};
// Reset game state on game over (handled by LK, but clear arrays for safety)
game.onDestroy = function () {
pipes = [];
wasps = [];
pests = [];
score = 0;
level = 1;
pipesPassedThisLevel = 0;
pipesToNextLevel = 3;
pipeSpeed = 16;
pipeInterval = 120;
gameStarted = false;
};
/****
* Asset Definitions (for LK static analysis)
****/
// Bee body (yellow ellipse)
// Bee stripes (black boxes)
// Bee wings (white ellipses)
// Pipe body (pink box)
// Pipe flower (small yellow ellipse)
// Wasp body (black/yellow ellipse)
// Pesticide (green box with white spray)