User prompt
Make the easiest, most fun and non-realistic version of Flappy Bird ever! Here’s exactly what I want: Super Easy Mode: Very slow gameplay (bird moves forward at a snail’s pace). HUGE gaps between pipes (at least 2x wider than normal). Low gravity (bird falls super slowly, like a feather). Auto-gliding (bird floats smoothly, no sudden drops). Cartoonish & Fun: Silly physics (bird bounces harmlessly off pipes, no ‘game over’). Rainbow trails or sparkles when flying. Funny sound effects (boing on bounce, party horn on score). Zero Stress: Unlimited lives (never die, just keep flying forever). Happy music (upbeat ukulele or chiptune). Smiling obstacles (pipes with googly eyes or clouds that cheer). Extra Fun: Tap to do a flip (just for visual fun, no penalty). Confetti explosion every 10 points. Make it so easy my grandma could play it blindfolded! Bonus: If possible, add a ‘Super Easy’ toggle in settings to make it even easier later!" ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Lower the gravity so the bird falls more slowly, and keep all the other easy-mode changes (slower speed, wider pipe gaps). Make it super casual!"
User prompt
Make the game slower, increase the distance between pipes, and keep it easy but fun
Code edit (1 edits merged)
Please save this source code
User prompt
Flap & Dash: Endless Flight
Initial prompt
Core Requirements: Basic Gameplay: Control a bird (or another character) that moves continuously to the right. Tap/Press to make the bird flap and avoid obstacles (pipes, buildings, etc.). Colliding with obstacles or the ground ends the game. Enhanced Features: Smoother Physics: Improve the jump/flap mechanics to feel more responsive. Procedural Levels: Randomly generated gaps and obstacles for replayability. Visual Upgrades: High-quality pixel art, smooth animations, or minimalist modern design. Particles & Effects: Add dust clouds, wing flaps, and screen shake on collisions. Difficulty Curve: Gradually increase speed and obstacle density. Additional Content: Multiple Characters: Unlockable birds/characters with unique abilities (e.g., faster fall, double jump). Themes: Day/night cycles or seasonal backgrounds. Power-ups: Temporary invincibility, score multipliers, or slow-mo. Sound Design: Background music + satisfying flap/crash sounds. UI/UX: Main menu with Start, Settings, and Character Select. Score counter + high score saving (local storage). Pause button and "Game Over" screen with a restart option. Optimization: Ensure it runs smoothly on web/mobile (60 FPS). Test for input lag (critical for a flappy-style game). Instructions for Upitop: Provide the full source code (HTML5/JavaScript, Unity, or exported executable). Include assets (sprites, sounds) and documentation if needed. Explain how to modify difficulty, art, or controls. Let me know if you need clarification or want to adjust features!"
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
// Bird (player) class
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdSprite = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = birdSprite.width * 0.5;
self.vy = 0; // vertical velocity
self.gravity = 0.22; // super low gravity for feather-like fall
self.flapStrength = -16; // gentle flap
self.alive = true;
self.rotationMax = Math.PI / 4; // 45deg
self.rotationMin = -Math.PI / 3; // -60deg
// Flap (jump)
self.flap = function () {
if (!self.alive) return;
self.vy = self.flapStrength;
LK.getSound('flap').play();
// Animate a quick upward tilt
tween(self, {
rotation: self.rotationMin
}, {
duration: 80,
easing: tween.cubicOut
});
// Particle burst
spawnParticles(self.x - 40, self.y, 8);
};
// Die
self.die = function () {
self.alive = false;
// Play hit sound
LK.getSound('hit').play();
// Flash effect
LK.effects.flashScreen(0xff0000, 400);
// Quick spin
tween(self, {
rotation: Math.PI * 2
}, {
duration: 400,
easing: tween.cubicIn
});
};
// Update per frame
self.update = function () {
if (!self.alive) return;
self.vy += self.gravity;
self.y += self.vy;
// Rotate bird based on velocity
var targetRot = Math.max(self.rotationMin, Math.min(self.rotationMax, self.vy * 0.025));
self.rotation += (targetRot - self.rotation) * 0.25;
};
return self;
});
// Ground class
var Ground = Container.expand(function () {
var self = Container.call(this);
var groundSprite = self.attachAsset('ground', {
anchorX: 0,
anchorY: 0
});
self.getSprite = function () {
return groundSprite;
};
return self;
});
// Particle class (for flapping effect)
var Particle = Container.expand(function () {
var self = Container.call(this);
var sprite = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = 0;
self.vy = 0;
self.life = 0;
self.init = function (x, y, vx, vy, life) {
self.x = x;
self.y = y;
self.vx = vx;
self.vy = vy;
self.life = life;
sprite.alpha = 1;
sprite.scaleX = sprite.scaleY = 1;
};
self.update = function () {
self.x += self.vx;
self.y += self.vy;
self.vy += 0.7; // gravity
self.life--;
sprite.alpha = Math.max(0, self.life / 20);
sprite.scaleX = sprite.scaleY = 0.7 + 0.3 * (self.life / 20);
};
return self;
});
// Pipe (obstacle) class
var Pipe = Container.expand(function () {
var self = Container.call(this);
// Top or bottom pipe
self.isTop = false;
self.passed = false; // Has the bird passed this pipe?
// Pipe body
var pipeSprite = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 0
});
// Add googly eyes and smile
var eyeL = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
color: 0xffffff,
width: 32,
height: 32
});
var eyeR = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
color: 0xffffff,
width: 32,
height: 32
});
var pupilL = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
color: 0x222222,
width: 12,
height: 12
});
var pupilR = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
color: 0x222222,
width: 12,
height: 12
});
var smile = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
color: 0xffe066,
width: 28,
height: 8
});
// Position eyes and smile
eyeL.x = -32;
eyeL.y = 38;
eyeR.x = 32;
eyeR.y = 38;
pupilL.x = -32;
pupilL.y = 38;
pupilR.x = 32;
pupilR.y = 38;
smile.x = 0;
smile.y = 68;
smile.scaleX = 1.2;
smile.scaleY = 0.7;
// Animate pupils for fun
self.update = function () {
self.x -= pipeSpeed;
var t = LK.ticks * 0.13;
pupilL.x = eyeL.x + Math.sin(t) * 4;
pupilL.y = eyeL.y + Math.cos(t) * 2;
pupilR.x = eyeR.x + Math.cos(t) * 4;
pupilR.y = eyeR.y + Math.sin(t) * 2;
smile.scaleX = 1.2 + Math.sin(t) * 0.15;
smile.scaleY = 0.7 + Math.cos(t) * 0.07;
};
self.setHeight = function (h) {
pipeSprite.height = h;
};
// For collision, use the pipeSprite
self.getSprite = function () {
return pipeSprite;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Sky blue
});
/****
* Game Code
****/
LK.playMusic('happy_uke', {
loop: true,
fade: {
start: 0,
end: 0.7,
duration: 1200
}
});
// Sound: Hit
// Sound: Score
// Sound: Flap
// Particle asset: white ellipse
// Ground asset: brown box
// Obstacle (pipe) asset: green box
// Bird (player) asset: yellow ellipse
// Game constants
var BIRD_START_X = 600;
var BIRD_START_Y = 1100;
var PIPE_GAP = 900; // HUGE gap for super easy mode
var PIPE_MIN = 350;
var PIPE_MAX = 1700;
var PIPE_INTERVAL = 1700; // much more distance between pipes
var pipeSpeed = 3.2; // very slow pipe speed
var GROUND_Y = 2732 - 120;
var PARTICLE_POOL_SIZE = 32;
// Game state
var bird;
var pipes = [];
var ground;
var score = 0;
var highScore = storage.highScore || 0;
var gameStarted = false;
var gameOver = false;
var lastPipeX = 0;
var dragNode = null;
var particles = [];
var particlePool = [];
var scoreTxt, highScoreTxt, tapTxt;
// GUI: Score display
scoreTxt = new Text2('0', {
size: 140,
fill: 0xFFF700,
font: "Impact"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// GUI: High score display
highScoreTxt = new Text2('BEST: ' + highScore, {
size: 60,
fill: 0xFFFFFF,
font: "Impact"
});
highScoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(highScoreTxt);
// GUI: Tap to start
tapTxt = new Text2('TAP TO FLAP', {
size: 100,
fill: 0xFFFFFF,
font: "Impact"
});
tapTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(tapTxt);
// Spawn ground
ground = new Ground();
ground.x = 0;
ground.y = GROUND_Y;
game.addChild(ground);
// Spawn bird
bird = new Bird();
bird.x = BIRD_START_X;
bird.y = BIRD_START_Y;
game.addChild(bird);
// Particle pool
for (var i = 0; i < PARTICLE_POOL_SIZE; i++) {
var p = new Particle();
particlePool.push(p);
}
// Reset game state
function resetGame() {
// Remove pipes
for (var i = 0; i < pipes.length; i++) {
pipes[i].destroy();
}
pipes = [];
// Reset bird
bird.x = BIRD_START_X;
bird.y = BIRD_START_Y;
bird.vy = 0;
bird.rotation = 0;
bird.alive = true;
// Reset score
score = 0;
scoreTxt.setText(score);
// Remove tap text if present
tapTxt.visible = true;
// Reset state
gameStarted = false;
gameOver = false;
lastPipeX = 1700;
// Remove all particles
for (var i = 0; i < particles.length; i++) {
particles[i].destroy();
}
particles = [];
}
// Spawn a pair of pipes (top and bottom)
function spawnPipePair(x) {
var gapY = PIPE_MIN + Math.floor(Math.random() * (PIPE_MAX - PIPE_MIN));
// Top pipe
var topPipe = new Pipe();
topPipe.isTop = true;
topPipe.x = x;
topPipe.y = gapY - PIPE_GAP - 800; // pipe height is 800
topPipe.setHeight(800);
game.addChild(topPipe);
pipes.push(topPipe);
// Bottom pipe
var bottomPipe = new Pipe();
bottomPipe.isTop = false;
bottomPipe.x = x;
bottomPipe.y = gapY;
bottomPipe.setHeight(800);
game.addChild(bottomPipe);
pipes.push(bottomPipe);
}
// Particle burst at (x, y)
function spawnParticles(x, y, count) {
for (var i = 0; i < count; i++) {
var p = particlePool.length > 0 ? particlePool.pop() : new Particle();
var angle = Math.random() * Math.PI * 2;
var speed = 7 + Math.random() * 6;
p.init(x, y, Math.cos(angle) * speed, Math.sin(angle) * speed, 20 + Math.floor(Math.random() * 10));
game.addChild(p);
particles.push(p);
}
}
// Rainbow trail particles
function spawnRainbowParticles(x, y, count) {
var rainbow = [0xff0000, 0xff7f00, 0xffff00, 0x00ff00, 0x0000ff, 0x4b0082, 0x9400d3];
for (var i = 0; i < count; i++) {
var p = particlePool.length > 0 ? particlePool.pop() : new Particle();
var angle = Math.PI + (Math.random() - 0.5) * 0.7;
var speed = 2 + Math.random() * 2;
var color = rainbow[(LK.ticks + i) % rainbow.length];
p.init(x, y, Math.cos(angle) * speed, Math.sin(angle) * speed, 18 + Math.floor(Math.random() * 6));
p.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
color: color
});
game.addChild(p);
particles.push(p);
}
}
// Confetti explosion
function spawnConfetti(x, y, count) {
var confettiColors = [0xffe066, 0xff5e5b, 0x3ecf4c, 0x5bc0eb, 0xfde74c, 0x9bc53d, 0xe55934, 0xfa7921];
for (var i = 0; i < count; i++) {
var p = particlePool.length > 0 ? particlePool.pop() : new Particle();
var angle = Math.random() * Math.PI * 2;
var speed = 7 + Math.random() * 7;
var color = confettiColors[Math.floor(Math.random() * confettiColors.length)];
p.init(x, y, Math.cos(angle) * speed, Math.sin(angle) * speed, 24 + Math.floor(Math.random() * 10));
p.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
color: color
});
game.addChild(p);
particles.push(p);
}
}
// Start game on first tap
function startGame() {
if (gameStarted) return;
tapTxt.visible = false;
gameStarted = true;
gameOver = false;
score = 0;
scoreTxt.setText(score);
// Remove all pipes
for (var i = 0; i < pipes.length; i++) {
pipes[i].destroy();
}
pipes = [];
// Spawn initial pipes
lastPipeX = 1700;
for (var i = 0; i < 4; i++) {
spawnPipePair(lastPipeX + i * PIPE_INTERVAL);
}
}
// Handle tap/flap
function handleFlap() {
if (gameOver) return;
if (!gameStarted) {
startGame();
}
bird.flap();
// Do a flip!
tween(bird, {
rotation: bird.rotation + Math.PI * 2
}, {
duration: 350,
easing: tween.cubicInOut
});
}
// Touch/click events
game.down = function (x, y, obj) {
if (gameOver) return;
handleFlap();
};
// Main update loop
game.update = function () {
// Bird update
bird.update();
// Particle update
for (var i = particles.length - 1; i >= 0; i--) {
var p = particles[i];
p.update();
if (p.life <= 0) {
p.destroy();
particlePool.push(p);
particles.splice(i, 1);
}
}
// Rainbow/sparkle trail: spawn every 2 frames while flying
if (gameStarted && LK.ticks % 2 === 0) {
spawnRainbowParticles(bird.x - 50, bird.y, 1);
}
// If not started, bird hovers
if (!gameStarted) {
bird.y += Math.sin(LK.ticks / 20) * 1.2;
return;
}
// Pipes update
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;
}
// Score: only for bottom pipes
if (!pipe.passed && !pipe.isTop && pipe.x + 90 < bird.x) {
pipe.passed = true;
score++;
scoreTxt.setText(score);
LK.getSound('score').play();
// Confetti explosion every 10 points
if (score > 0 && score % 10 === 0) {
spawnConfetti(bird.x, bird.y - 60, 32);
}
// Update high score
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('BEST: ' + highScore);
}
}
}
// Spawn new pipes
if (pipes.length > 0) {
var lastPipe = pipes[pipes.length - 1];
if (lastPipe.x < 2048 - PIPE_INTERVAL) {
lastPipeX += PIPE_INTERVAL;
spawnPipePair(lastPipeX);
}
}
// Collision: ground
if (bird.y + bird.radius > GROUND_Y) {
if (!gameOver) {
bird.y = GROUND_Y - bird.radius;
bird.die();
endGame();
}
}
// Collision: pipes
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
var sprite = pipe.getSprite();
// Simple AABB collision
var bx = bird.x,
by = bird.y,
br = bird.radius * 0.82;
var px = pipe.x - sprite.width * 0.5,
py = pipe.y,
pw = sprite.width,
ph = sprite.height;
if (bx + br > px && bx - br < px + pw && by + br > py && by - br < py + ph) {
// Silly bounce: reverse vertical velocity, play boing sound, and do a quick scale animation
if (bird.vy > 0) {
bird.vy = -Math.abs(bird.vy) * 0.7 - 8 - Math.random() * 6;
} else {
bird.vy = Math.abs(bird.vy) * 0.7 + 8 + Math.random() * 6;
}
LK.getSound('hit').play();
tween(bird, {
scaleX: 1.3,
scaleY: 0.7
}, {
duration: 80,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(bird, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.cubicIn
});
}
});
// Rainbow trail burst
spawnRainbowParticles(bird.x, bird.y, 10);
// No game over!
}
}
};
// End game
function endGame() {
gameOver = true;
tapTxt.setText('GAME OVER\nTAP TO RESTART');
tapTxt.visible = true;
LK.showGameOver();
// Reset after popup
LK.setTimeout(function () {
resetGame();
}, 800);
}
// On game over popup close, reset game
LK.on('gameover', function () {
resetGame();
});
// On you win (not used in endless, but for completeness)
LK.on('youwin', function () {
resetGame();
});
// On resize, keep tap text centered (handled by LK.gui, but for safety)
LK.on('resize', function () {
tapTxt.anchor.set(0.5, 0.5);
});
// Initial reset
resetGame(); ===================================================================
--- original.js
+++ change.js
@@ -17,10 +17,10 @@
anchorY: 0.5
});
self.radius = birdSprite.width * 0.5;
self.vy = 0; // vertical velocity
- self.gravity = 1.1; // gravity per frame (lowered for super casual mode)
- self.flapStrength = -38; // negative = up
+ self.gravity = 0.22; // super low gravity for feather-like fall
+ self.flapStrength = -16; // gentle flap
self.alive = true;
self.rotationMax = Math.PI / 4; // 45deg
self.rotationMin = -Math.PI / 3; // -60deg
// Flap (jump)
@@ -115,19 +115,75 @@
var pipeSprite = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 0
});
+ // Add googly eyes and smile
+ var eyeL = self.attachAsset('particle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0xffffff,
+ width: 32,
+ height: 32
+ });
+ var eyeR = self.attachAsset('particle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0xffffff,
+ width: 32,
+ height: 32
+ });
+ var pupilL = self.attachAsset('particle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0x222222,
+ width: 12,
+ height: 12
+ });
+ var pupilR = self.attachAsset('particle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0x222222,
+ width: 12,
+ height: 12
+ });
+ var smile = self.attachAsset('particle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0xffe066,
+ width: 28,
+ height: 8
+ });
+ // Position eyes and smile
+ eyeL.x = -32;
+ eyeL.y = 38;
+ eyeR.x = 32;
+ eyeR.y = 38;
+ pupilL.x = -32;
+ pupilL.y = 38;
+ pupilR.x = 32;
+ pupilR.y = 38;
+ smile.x = 0;
+ smile.y = 68;
+ smile.scaleX = 1.2;
+ smile.scaleY = 0.7;
+ // Animate pupils for fun
+ self.update = function () {
+ self.x -= pipeSpeed;
+ var t = LK.ticks * 0.13;
+ pupilL.x = eyeL.x + Math.sin(t) * 4;
+ pupilL.y = eyeL.y + Math.cos(t) * 2;
+ pupilR.x = eyeR.x + Math.cos(t) * 4;
+ pupilR.y = eyeR.y + Math.sin(t) * 2;
+ smile.scaleX = 1.2 + Math.sin(t) * 0.15;
+ smile.scaleY = 0.7 + Math.cos(t) * 0.07;
+ };
self.setHeight = function (h) {
pipeSprite.height = h;
};
// For collision, use the pipeSprite
self.getSprite = function () {
return pipeSprite;
};
- // Update per frame
- self.update = function () {
- self.x -= pipeSpeed;
- };
return self;
});
/****
@@ -139,10 +195,16 @@
/****
* Game Code
****/
-// LK.init.music('bgmusic', {volume: 0.5});
-// Music (optional, not played in MVP)
+LK.playMusic('happy_uke', {
+ loop: true,
+ fade: {
+ start: 0,
+ end: 0.7,
+ duration: 1200
+ }
+});
// Sound: Hit
// Sound: Score
// Sound: Flap
// Particle asset: white ellipse
@@ -151,13 +213,13 @@
// Bird (player) asset: yellow ellipse
// Game constants
var BIRD_START_X = 600;
var BIRD_START_Y = 1100;
-var PIPE_GAP = 420; // wide gap for easy mode
+var PIPE_GAP = 900; // HUGE gap for super easy mode
var PIPE_MIN = 350;
var PIPE_MAX = 1700;
-var PIPE_INTERVAL = 1050; // increased distance between pipes for easy mode
-var pipeSpeed = 9; // slower pipe speed for easy mode
+var PIPE_INTERVAL = 1700; // much more distance between pipes
+var pipeSpeed = 3.2; // very slow pipe speed
var GROUND_Y = 2732 - 120;
var PARTICLE_POOL_SIZE = 32;
// Game state
var bird;
@@ -269,8 +331,44 @@
game.addChild(p);
particles.push(p);
}
}
+// Rainbow trail particles
+function spawnRainbowParticles(x, y, count) {
+ var rainbow = [0xff0000, 0xff7f00, 0xffff00, 0x00ff00, 0x0000ff, 0x4b0082, 0x9400d3];
+ for (var i = 0; i < count; i++) {
+ var p = particlePool.length > 0 ? particlePool.pop() : new Particle();
+ var angle = Math.PI + (Math.random() - 0.5) * 0.7;
+ var speed = 2 + Math.random() * 2;
+ var color = rainbow[(LK.ticks + i) % rainbow.length];
+ p.init(x, y, Math.cos(angle) * speed, Math.sin(angle) * speed, 18 + Math.floor(Math.random() * 6));
+ p.attachAsset('particle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: color
+ });
+ game.addChild(p);
+ particles.push(p);
+ }
+}
+// Confetti explosion
+function spawnConfetti(x, y, count) {
+ var confettiColors = [0xffe066, 0xff5e5b, 0x3ecf4c, 0x5bc0eb, 0xfde74c, 0x9bc53d, 0xe55934, 0xfa7921];
+ for (var i = 0; i < count; i++) {
+ var p = particlePool.length > 0 ? particlePool.pop() : new Particle();
+ var angle = Math.random() * Math.PI * 2;
+ var speed = 7 + Math.random() * 7;
+ var color = confettiColors[Math.floor(Math.random() * confettiColors.length)];
+ p.init(x, y, Math.cos(angle) * speed, Math.sin(angle) * speed, 24 + Math.floor(Math.random() * 10));
+ p.attachAsset('particle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: color
+ });
+ game.addChild(p);
+ particles.push(p);
+ }
+}
// Start game on first tap
function startGame() {
if (gameStarted) return;
tapTxt.visible = false;
@@ -295,8 +393,15 @@
if (!gameStarted) {
startGame();
}
bird.flap();
+ // Do a flip!
+ tween(bird, {
+ rotation: bird.rotation + Math.PI * 2
+ }, {
+ duration: 350,
+ easing: tween.cubicInOut
+ });
}
// Touch/click events
game.down = function (x, y, obj) {
if (gameOver) return;
@@ -315,8 +420,12 @@
particlePool.push(p);
particles.splice(i, 1);
}
}
+ // Rainbow/sparkle trail: spawn every 2 frames while flying
+ if (gameStarted && LK.ticks % 2 === 0) {
+ spawnRainbowParticles(bird.x - 50, bird.y, 1);
+ }
// If not started, bird hovers
if (!gameStarted) {
bird.y += Math.sin(LK.ticks / 20) * 1.2;
return;
@@ -336,8 +445,12 @@
pipe.passed = true;
score++;
scoreTxt.setText(score);
LK.getSound('score').play();
+ // Confetti explosion every 10 points
+ if (score > 0 && score % 10 === 0) {
+ spawnConfetti(bird.x, bird.y - 60, 32);
+ }
// Update high score
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
@@ -373,12 +486,34 @@
py = pipe.y,
pw = sprite.width,
ph = sprite.height;
if (bx + br > px && bx - br < px + pw && by + br > py && by - br < py + ph) {
- if (!gameOver) {
- bird.die();
- endGame();
+ // Silly bounce: reverse vertical velocity, play boing sound, and do a quick scale animation
+ if (bird.vy > 0) {
+ bird.vy = -Math.abs(bird.vy) * 0.7 - 8 - Math.random() * 6;
+ } else {
+ bird.vy = Math.abs(bird.vy) * 0.7 + 8 + Math.random() * 6;
}
+ LK.getSound('hit').play();
+ tween(bird, {
+ scaleX: 1.3,
+ scaleY: 0.7
+ }, {
+ duration: 80,
+ easing: tween.cubicOut,
+ onFinish: function onFinish() {
+ tween(bird, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 120,
+ easing: tween.cubicIn
+ });
+ }
+ });
+ // Rainbow trail burst
+ spawnRainbowParticles(bird.x, bird.y, 10);
+ // No game over!
}
}
};
// End game