User prompt
give the bird and control by mouse
User prompt
give the shape and animations also ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Flap or Flop
User prompt
make the game of flap or flop
User prompt
Please continue polishing my design document.
Initial prompt
make the game flap or flop
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.targetY = 2732 / 2;
self.currentPath = 'center';
self.update = function () {
// Smooth movement towards target position
var diff = self.targetY - self.y;
self.y += diff * 0.1;
// Enhanced floating animation
var floatOffset = Math.sin(LK.ticks * 0.05) * 15;
var currentY = self.y;
self.y = currentY + floatOffset;
// Wing flap simulation with rotation
if (!birdGraphics.isFlapping) {
birdGraphics.rotation = Math.sin(LK.ticks * 0.2) * 0.15;
}
// Scale breathing effect
var breathScale = 1 + Math.sin(LK.ticks * 0.08) * 0.05;
birdGraphics.scaleX = breathScale;
birdGraphics.scaleY = breathScale;
};
self.setPath = function (path) {
self.currentPath = path;
var newTargetY;
if (path === 'left') {
newTargetY = 2732 * 0.3;
} else if (path === 'right') {
newTargetY = 2732 * 0.7;
} else {
newTargetY = 2732 / 2;
}
// Animate bird to new position with bounce effect
tween(self, {
targetY: newTargetY
}, {
duration: 400,
easing: tween.easeOut
});
// Add slight tilt animation based on direction
var targetRotation = 0;
if (path === 'left') {
targetRotation = -0.2;
} else if (path === 'right') {
targetRotation = 0.2;
}
tween(birdGraphics, {
rotation: targetRotation
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(birdGraphics, {
rotation: 0
}, {
duration: 300,
easing: tween.easeOut
});
}
});
};
return self;
});
var Obstacle = Container.expand(function (gapSide) {
var self = Container.call(this);
self.gapSide = gapSide || 'both';
self.speed = -gameSpeed;
self.passed = false;
var gapSize = 350;
// Create obstacles based on gap configuration
if (self.gapSide === 'left' || self.gapSide === 'both') {
// Top obstacle for left gap
var topLeft = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1,
x: 0,
y: 2732 * 0.3 - gapSize / 2
});
// Bottom obstacle for left gap
var bottomLeft = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0,
x: 0,
y: 2732 * 0.3 + gapSize / 2
});
}
if (self.gapSide === 'right' || self.gapSide === 'both') {
// Top obstacle for right gap
var topRight = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1,
x: 0,
y: 2732 * 0.7 - gapSize / 2
});
// Bottom obstacle for right gap
var bottomRight = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0,
x: 0,
y: 2732 * 0.7 + gapSize / 2
});
}
// Add middle obstacle if only one gap
if (self.gapSide === 'left') {
var rightBlock = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 2732 * 0.7,
height: 800
});
}
if (self.gapSide === 'right') {
var leftBlock = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 2732 * 0.3,
height: 800
});
}
// Start obstacles scaled down for entrance animation
self.scaleX = 0.1;
self.scaleY = 0.1;
// Animate entrance
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.bounceOut
});
self.update = function () {
self.x += self.speed;
};
return self;
});
var PathIndicator = Container.expand(function (side) {
var self = Container.call(this);
var indicator = self.attachAsset('pathIndicator', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
self.side = side;
if (side === 'left') {
self.y = 2732 * 0.3;
} else {
self.y = 2732 * 0.7;
}
// Start pulsing animation
tween(indicator, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.6
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(indicator, {
scaleX: 0.8,
scaleY: 0.8,
alpha: 0.2
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
self.update = function () {
self.x += -gameSpeed;
// Fade out as it moves
if (self.x < 1000) {
indicator.alpha = Math.max(0, indicator.alpha - 0.02);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var bird;
var obstacles = [];
var pathIndicators = [];
var gameSpeed = 8;
var obstacleSpawnTimer = 0;
var obstacleSpawnDelay = 180; // 3 seconds at 60fps
var nextObstacleGap = 'both';
// UI Elements
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create bird
bird = game.addChild(new Bird());
bird.x = 300;
bird.y = 2732 / 2;
// Mouse controls - bird follows mouse Y position
game.move = function (x, y, obj) {
// Convert mouse Y position to bird path
var centerY = 2732 / 2;
var threshold = 200;
var currentPath;
if (y < centerY - threshold) {
currentPath = 'left';
} else if (y > centerY + threshold) {
currentPath = 'right';
} else {
currentPath = 'center';
}
// Only change path if it's different from current
if (bird.currentPath !== currentPath) {
bird.setPath(currentPath);
// Add flap animation on path change
var birdGraphics = bird.children[0];
birdGraphics.isFlapping = true;
tween(birdGraphics, {
scaleY: 1.3
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(birdGraphics, {
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
birdGraphics.isFlapping = false;
}
});
}
});
LK.getSound('flap').play();
}
};
// Generate random gap configuration
function getRandomGapConfig() {
var configs = ['left', 'right', 'both'];
return configs[Math.floor(Math.random() * configs.length)];
}
// Check collision between bird and obstacles
function checkCollisions() {
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (bird.intersects(obstacle)) {
// Game over
LK.getSound('collision').play();
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
return true;
}
// Check if bird passed obstacle for scoring
if (!obstacle.passed && obstacle.x < bird.x - 100) {
obstacle.passed = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
LK.getSound('score').play();
// Animate score text
tween(scoreTxt, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
});
// Increase speed every 5 points
if (LK.getScore() % 5 === 0) {
gameSpeed += 0.5;
obstacleSpawnDelay = Math.max(120, obstacleSpawnDelay - 5);
}
}
}
return false;
}
// Spawn new obstacle
function spawnObstacle() {
var gapConfig = getRandomGapConfig();
var newObstacle = new Obstacle(gapConfig);
newObstacle.x = 2048 + 200;
obstacles.push(newObstacle);
game.addChild(newObstacle);
// Add path indicators
if (gapConfig === 'left' || gapConfig === 'both') {
var leftIndicator = new PathIndicator('left');
leftIndicator.x = 2048 + 100;
pathIndicators.push(leftIndicator);
game.addChild(leftIndicator);
}
if (gapConfig === 'right' || gapConfig === 'both') {
var rightIndicator = new PathIndicator('right');
rightIndicator.x = 2048 + 100;
pathIndicators.push(rightIndicator);
game.addChild(rightIndicator);
}
}
// Main game loop
game.update = function () {
// Spawn obstacles
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= obstacleSpawnDelay) {
spawnObstacle();
obstacleSpawnTimer = 0;
}
// Update and clean up obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.x < -300) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
// Update and clean up path indicators
for (var j = pathIndicators.length - 1; j >= 0; j--) {
var indicator = pathIndicators[j];
if (indicator.x < -200 || indicator.children[0].alpha <= 0) {
indicator.destroy();
pathIndicators.splice(j, 1);
}
}
// Check for collisions
checkCollisions();
// Keep bird in bounds
if (bird.y < 50) bird.y = 50;
if (bird.y > 2732 - 50) bird.y = 2732 - 50;
}; ===================================================================
--- original.js
+++ change.js
@@ -216,39 +216,46 @@
// Create bird
bird = game.addChild(new Bird());
bird.x = 300;
bird.y = 2732 / 2;
-// Touch controls
-game.down = function (x, y, obj) {
- if (x < 2048 / 2) {
- // Left side tapped
- bird.setPath('left');
- LK.getSound('flap').play();
+// Mouse controls - bird follows mouse Y position
+game.move = function (x, y, obj) {
+ // Convert mouse Y position to bird path
+ var centerY = 2732 / 2;
+ var threshold = 200;
+ var currentPath;
+ if (y < centerY - threshold) {
+ currentPath = 'left';
+ } else if (y > centerY + threshold) {
+ currentPath = 'right';
} else {
- // Right side tapped
- bird.setPath('right');
+ currentPath = 'center';
+ }
+ // Only change path if it's different from current
+ if (bird.currentPath !== currentPath) {
+ bird.setPath(currentPath);
+ // Add flap animation on path change
+ var birdGraphics = bird.children[0];
+ birdGraphics.isFlapping = true;
+ tween(birdGraphics, {
+ scaleY: 1.3
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(birdGraphics, {
+ scaleY: 1
+ }, {
+ duration: 150,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ birdGraphics.isFlapping = false;
+ }
+ });
+ }
+ });
LK.getSound('flap').play();
}
- // Add flap animation
- var birdGraphics = bird.children[0];
- birdGraphics.isFlapping = true;
- tween(birdGraphics, {
- scaleY: 1.3
- }, {
- duration: 100,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- tween(birdGraphics, {
- scaleY: 1
- }, {
- duration: 150,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- birdGraphics.isFlapping = false;
- }
- });
- }
- });
};
// Generate random gap configuration
function getRandomGapConfig() {
var configs = ['left', 'right', 'both'];