User prompt
El terreno sea un poco más largo
User prompt
Agrega física al pájaro para que salte un poco más
User prompt
Que los birds sean un poco grandes pero no tan grandes
User prompt
Que no sea difícil pasar los obstáculos
User prompt
Los obstáculos que sean un poco más fácil de pasar y que los tubos sean largos
User prompt
Los obstáculos que estén un poco alejados para que de tiempo de pasarlo
User prompt
Mejora la colicion al morir y mejora los obstáculos donde aparecen
User prompt
Ahora hazlo un poco más grande el juego
User prompt
Cada vez que doy tap to play muero arreglalo y has que al dar tap to play comienze el juego parecido a flappy bird ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Al tocar play no muera corrige el error
User prompt
Arregla ese error que es al tocar la pantalla me muero pon un botón que diga play para comenzar el juego
User prompt
Un botón para cambiar de personaje ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Crea un menú o menu de carga que diga play y que entre en la pantalla ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
La generación de terreno que sea más realista y los obstáculos también y corrige el sistema de puntos cada vez que me da un punto me muero ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught TypeError: storage.getInt is not a function' in or related to this line: 'var bestScore = storage.getInt('highScore', 0);' Line Number: 236 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Que tenga un menú y pantalla un poco más chico para que sea un juego de celular
Code edit (1 edits merged)
Please save this source code
User prompt
Flappy Wings
Initial prompt
Has un juego como Flappy Bird
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bird = Container.expand(function (characterIndex) { var self = Container.call(this); var assetName = characterAssets[characterIndex - 1] || 'bird'; var birdGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.velocity = 0; self.gravity = 0.8; self.flapPower = -12; self.maxVelocity = 15; self.minVelocity = -15; self.flap = function () { self.velocity = self.flapPower; LK.getSound('flap').play(); // Add slight rotation animation tween(birdGraphics, { rotation: -0.3 }, { duration: 100 }); tween(birdGraphics, { rotation: 0.5 }, { duration: 200, onFinish: function onFinish() { tween(birdGraphics, { rotation: 0 }, { duration: 300 }); } }); }; self.update = function () { // Apply gravity self.velocity += self.gravity; // Limit velocity if (self.velocity > self.maxVelocity) self.velocity = self.maxVelocity; if (self.velocity < self.minVelocity) self.velocity = self.minVelocity; // Update position self.y += self.velocity; // Rotate bird based on velocity var targetRotation = Math.max(-0.5, Math.min(0.8, self.velocity * 0.05)); birdGraphics.rotation = targetRotation; }; return self; }); var Pipe = Container.expand(function () { var self = Container.call(this); self.speed = -4; self.scored = false; // Create top pipe body self.topPipeBody = self.attachAsset('pipeBody', { anchorX: 0.5, anchorY: 1 }); // Create top pipe cap self.topPipeCap = self.attachAsset('pipeTop', { anchorX: 0.5, anchorY: 1 }); // Create bottom pipe body self.bottomPipeBody = self.attachAsset('pipeBody', { anchorX: 0.5, anchorY: 0 }); // Create bottom pipe cap self.bottomPipeCap = self.attachAsset('pipeTop', { anchorX: 0.5, anchorY: 0 }); self.setGap = function (centerY, gapSize) { self.topPipeBody.y = centerY - gapSize / 2; self.topPipeCap.y = centerY - gapSize / 2; self.bottomPipeBody.y = centerY + gapSize / 2; self.bottomPipeCap.y = centerY + gapSize / 2; }; self.update = function () { self.x += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game variables var bird; var pipes = []; var ground; var gameStarted = false; var gameOver = false; var gameState = 'menu'; // 'menu', 'playing', 'gameOver' var pipeSpawnTimer = 0; var pipeSpawnInterval = 90; // frames var gapSize = 300; // Increased for larger game area var baseGapSize = 300; var basePipeInterval = 90; var scrollSpeed = 4; // Character selection var currentCharacter = storage.selectedCharacter || 1; var characterAssets = ['bird', 'bird2', 'bird3', 'bird4']; var totalCharacters = 4; // Increased game dimensions var GAME_WIDTH = 1800; // Increased from 1536 var GAME_HEIGHT = 2400; // Increased from 2048 // UI Elements var scoreTxt = new Text2('0', { size: 70, // Slightly smaller for mobile fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Menu elements var titleTxt = new Text2('FLAPPY WINGS', { size: 80, fill: 0xFFD700 }); titleTxt.anchor.set(0.5, 0.5); titleTxt.x = GAME_WIDTH / 2; titleTxt.y = -100; // Start above screen titleTxt.alpha = 0; // Start invisible game.addChild(titleTxt); // Animate title entrance tween(titleTxt, { y: GAME_HEIGHT / 2 - 300, alpha: 1 }, { duration: 1000, easing: tween.bounceOut }); var playButtonTxt = new Text2('TAP TO PLAY', { size: 50, fill: 0xFFFFFF }); playButtonTxt.anchor.set(0.5, 0.5); playButtonTxt.x = -200; // Start off screen left playButtonTxt.y = GAME_HEIGHT / 2 - 100; playButtonTxt.alpha = 0; // Start invisible game.addChild(playButtonTxt); // Animate play button entrance with delay LK.setTimeout(function () { tween(playButtonTxt, { x: GAME_WIDTH / 2, alpha: 1 }, { duration: 800, easing: tween.elasticOut, onFinish: function onFinish() { // Start pulsing animation after entrance function pulsePlayButton() { tween(playButtonTxt, { scaleX: 1.1, scaleY: 1.1 }, { duration: 600, easing: tween.easeInOut, onFinish: function onFinish() { tween(playButtonTxt, { scaleX: 1.0, scaleY: 1.0 }, { duration: 600, easing: tween.easeInOut, onFinish: pulsePlayButton }); } }); } pulsePlayButton(); } }); }, 500); var highScoreTxt = new Text2('Best: 0', { size: 40, fill: 0xFFFFFF }); highScoreTxt.anchor.set(0.5, 0.5); highScoreTxt.x = GAME_WIDTH + 200; // Start off screen right highScoreTxt.y = GAME_HEIGHT / 2 + 50; highScoreTxt.alpha = 0; // Start invisible game.addChild(highScoreTxt); // Animate high score entrance with delay LK.setTimeout(function () { tween(highScoreTxt, { x: GAME_WIDTH / 2, alpha: 1 }, { duration: 800, easing: tween.elasticOut }); }, 800); // Animate character button entrance with delay LK.setTimeout(function () { tween(characterButtonTxt, { alpha: 1 }, { duration: 800, easing: tween.elasticOut }); tween(characterDisplayTxt, { alpha: 1 }, { duration: 800, easing: tween.elasticOut }); }, 1000); var characterButtonTxt = new Text2('CHARACTER', { size: 45, fill: 0xFFD700 }); characterButtonTxt.anchor.set(0.5, 0.5); characterButtonTxt.x = GAME_WIDTH / 2; characterButtonTxt.y = GAME_HEIGHT / 2 + 100; characterButtonTxt.alpha = 0; game.addChild(characterButtonTxt); // Character display var characterDisplayTxt = new Text2('1/4', { size: 35, fill: 0xFFFFFF }); characterDisplayTxt.anchor.set(0.5, 0.5); characterDisplayTxt.x = GAME_WIDTH / 2; characterDisplayTxt.y = GAME_HEIGHT / 2 + 150; characterDisplayTxt.alpha = 0; game.addChild(characterDisplayTxt); var instructionTxt = new Text2('TAP TO FLAP', { size: 45, fill: 0xFFFFFF }); instructionTxt.anchor.set(0.5, 0.5); instructionTxt.x = GAME_WIDTH / 2; instructionTxt.y = GAME_HEIGHT / 2 + 150; instructionTxt.visible = false; game.addChild(instructionTxt); // Game over elements var gameOverTxt = new Text2('GAME OVER', { size: 70, fill: 0xFF0000 }); gameOverTxt.anchor.set(0.5, 0.5); gameOverTxt.x = GAME_WIDTH / 2; gameOverTxt.y = GAME_HEIGHT / 2 - 100; gameOverTxt.visible = false; game.addChild(gameOverTxt); var restartTxt = new Text2('TAP TO RESTART', { size: 45, fill: 0xFFFFFF }); restartTxt.anchor.set(0.5, 0.5); restartTxt.x = GAME_WIDTH / 2; restartTxt.y = GAME_HEIGHT / 2 + 50; restartTxt.visible = false; game.addChild(restartTxt); // Initialize bird bird = game.addChild(new Bird(currentCharacter)); bird.x = GAME_WIDTH / 3.5; bird.y = GAME_HEIGHT / 2; bird.visible = false; // Hide until game starts // Create layered ground var dirt = game.addChild(LK.getAsset('dirt', { anchorX: 0, anchorY: 1 })); dirt.x = 0; dirt.y = GAME_HEIGHT; dirt.width = GAME_WIDTH; ground = game.addChild(LK.getAsset('ground', { anchorX: 0, anchorY: 1 })); ground.x = 0; ground.y = GAME_HEIGHT - 100; ground.width = GAME_WIDTH; // Scale to larger width // Add grass details var grassTufts = []; for (var g = 0; g < GAME_WIDTH / 60; g++) { var grass = game.addChild(LK.getAsset('grass', { anchorX: 0.5, anchorY: 1 })); grass.x = g * 60 + Math.random() * 40; grass.y = GAME_HEIGHT - 100; grass.height = 15 + Math.random() * 10; grassTufts.push(grass); } // Function to spawn pipe function spawnPipe() { var pipe = new Pipe(); // Better gap positioning - ensure minimum distance from top and bottom var minY = gapSize / 2 + 150; // Minimum distance from top var maxY = GAME_HEIGHT - ground.height - gapSize / 2 - 150; // Maximum distance from bottom var centerY = minY + Math.random() * (maxY - minY); pipe.setGap(centerY, gapSize); pipe.x = GAME_WIDTH + 100; pipes.push(pipe); game.addChild(pipe); } // Function to start game function startGame() { if (gameState === 'menu') { gameState = 'playing'; gameStarted = true; // Reset bird velocity to prevent death bird.velocity = 0; bird.y = GAME_HEIGHT / 2; // Hide menu elements titleTxt.visible = false; playButtonTxt.visible = false; highScoreTxt.visible = false; characterButtonTxt.visible = false; characterDisplayTxt.visible = false; // Show game elements bird.visible = true; instructionTxt.visible = true; scoreTxt.visible = true; // Hide instruction after a delay LK.setTimeout(function () { instructionTxt.visible = false; }, 2000); } } // Function to reset game function resetGame() { // Clean up pipes for (var i = 0; i < pipes.length; i++) { pipes[i].destroy(); } pipes = []; // Reset bird bird.destroy(); bird = game.addChild(new Bird(currentCharacter)); bird.x = GAME_WIDTH / 4; bird.y = GAME_HEIGHT / 2; bird.velocity = 0; bird.visible = false; // Update high score var currentScore = LK.getScore(); var bestScore = storage.highScore || 0; if (currentScore > bestScore) { storage.highScore = currentScore; bestScore = currentScore; } // Reset game state gameState = 'menu'; gameStarted = false; gameOver = false; pipeSpawnTimer = 0; LK.setScore(0); scoreTxt.setText('0'); // Show menu elements with animations titleTxt.visible = true; playButtonTxt.visible = true; highScoreTxt.visible = true; characterButtonTxt.visible = true; characterDisplayTxt.visible = true; highScoreTxt.setText('Best: ' + bestScore); characterDisplayTxt.setText(currentCharacter + '/' + totalCharacters); // Reset positions for re-entrance titleTxt.y = -100; titleTxt.alpha = 0; playButtonTxt.x = -200; playButtonTxt.alpha = 0; highScoreTxt.x = GAME_WIDTH + 200; highScoreTxt.alpha = 0; characterButtonTxt.alpha = 0; characterDisplayTxt.alpha = 0; // Re-animate entrance tween(titleTxt, { y: GAME_HEIGHT / 2 - 300, alpha: 1 }, { duration: 1000, easing: tween.bounceOut }); LK.setTimeout(function () { tween(playButtonTxt, { x: GAME_WIDTH / 2, alpha: 1 }, { duration: 800, easing: tween.elasticOut }); }, 300); LK.setTimeout(function () { tween(highScoreTxt, { x: GAME_WIDTH / 2, alpha: 1 }, { duration: 800, easing: tween.elasticOut }); }, 600); LK.setTimeout(function () { tween(characterButtonTxt, { alpha: 1 }, { duration: 800, easing: tween.elasticOut }); tween(characterDisplayTxt, { alpha: 1 }, { duration: 800, easing: tween.elasticOut }); }, 800); instructionTxt.visible = false; gameOverTxt.visible = false; restartTxt.visible = false; scoreTxt.visible = false; } // Touch/click handlers game.down = function (x, y, obj) { if (gameState === 'menu') { // Check if clicked on character button var characterButtonBounds = { x: characterButtonTxt.x - 100, y: characterButtonTxt.y - 30, width: 200, height: 60 }; var characterDisplayBounds = { x: characterDisplayTxt.x - 50, y: characterDisplayTxt.y - 30, width: 100, height: 60 }; // Check if clicked on play button var playButtonBounds = { x: playButtonTxt.x - 120, y: playButtonTxt.y - 30, width: 240, height: 60 }; if (x >= characterButtonBounds.x && x <= characterButtonBounds.x + characterButtonBounds.width && y >= characterButtonBounds.y && y <= characterButtonBounds.y + characterButtonBounds.height || x >= characterDisplayBounds.x && x <= characterDisplayBounds.x + characterDisplayBounds.width && y >= characterDisplayBounds.y && y <= characterDisplayBounds.y + characterDisplayBounds.height) { // Change character currentCharacter = currentCharacter % totalCharacters + 1; storage.selectedCharacter = currentCharacter; characterDisplayTxt.setText(currentCharacter + '/' + totalCharacters); // Recreate bird with new character bird.destroy(); bird = game.addChild(new Bird(currentCharacter)); bird.x = GAME_WIDTH / 4; bird.y = GAME_HEIGHT / 2; bird.visible = false; // Add selection animation tween(characterDisplayTxt, { scaleX: 1.3, scaleY: 1.3 }, { duration: 150, onFinish: function onFinish() { tween(characterDisplayTxt, { scaleX: 1.0, scaleY: 1.0 }, { duration: 150 }); } }); } else if (x >= playButtonBounds.x && x <= playButtonBounds.x + playButtonBounds.width && y >= playButtonBounds.y && y <= playButtonBounds.y + playButtonBounds.height) { // Start game only if play button is clicked startGame(); return; // Exit immediately to prevent flap } } else if (gameState === 'playing' && !gameOver) { bird.flap(); } else if (gameState === 'gameOver') { resetGame(); } }; // Main game loop game.update = function () { if (!gameStarted || gameOver) return; // Spawn pipes pipeSpawnTimer++; if (pipeSpawnTimer >= pipeSpawnInterval) { spawnPipe(); pipeSpawnTimer = 0; } // Update pipes for (var i = pipes.length - 1; i >= 0; i--) { var pipe = pipes[i]; // Check for scoring - use pipe center for more accurate scoring if (!pipe.scored && pipe.x < bird.x - 60) { pipe.scored = true; LK.setScore(LK.getScore() + 1); scoreTxt.setText(LK.getScore()); LK.getSound('score').play(); // Dynamic difficulty - make game harder as score increases var currentScore = LK.getScore(); if (currentScore > 0) { // Gradually decrease gap size (minimum 200) gapSize = Math.max(200, baseGapSize - currentScore * 5); // Gradually decrease spawn interval (minimum 60 frames) pipeSpawnInterval = Math.max(60, basePipeInterval - currentScore * 2); } } // Check collision with bird - use more accurate bird bounds var birdBounds = { x: bird.x - 30, y: bird.y - 20, width: 60, height: 40 }; var topPipeBounds = { x: pipe.x - 55, y: 0, width: 110, height: pipe.topPipeBody.y - 10 }; var bottomPipeBounds = { x: pipe.x - 55, y: pipe.bottomPipeBody.y + 10, width: 110, height: GAME_HEIGHT - pipe.bottomPipeBody.y - 10 }; // Check collision if (birdBounds.x < topPipeBounds.x + topPipeBounds.width && birdBounds.x + birdBounds.width > topPipeBounds.x && birdBounds.y < topPipeBounds.y + topPipeBounds.height && birdBounds.y + birdBounds.height > topPipeBounds.y || birdBounds.x < bottomPipeBounds.x + bottomPipeBounds.width && birdBounds.x + birdBounds.width > bottomPipeBounds.x && birdBounds.y < bottomPipeBounds.y + bottomPipeBounds.height && birdBounds.y + birdBounds.height > bottomPipeBounds.y) { gameOver = true; gameState = 'gameOver'; LK.getSound('hit').play(); LK.effects.flashScreen(0xff0000, 500); // Show game over UI gameOverTxt.visible = true; restartTxt.visible = true; scoreTxt.visible = false; return; } // Remove off-screen pipes if (pipe.x < -200) { pipe.destroy(); pipes.splice(i, 1); } } // Check ground collision - updated for new ground position with better bounds if (bird.y + 20 >= ground.y) { gameOver = true; gameState = 'gameOver'; LK.getSound('hit').play(); LK.effects.flashScreen(0xff0000, 500); // Show game over UI gameOverTxt.visible = true; restartTxt.visible = true; scoreTxt.visible = false; return; } // Check ceiling collision with better bounds if (bird.y - 20 <= 0) { gameOver = true; gameState = 'gameOver'; LK.getSound('hit').play(); LK.effects.flashScreen(0xff0000, 500); // Show game over UI gameOverTxt.visible = true; restartTxt.visible = true; scoreTxt.visible = false; return; } };
===================================================================
--- original.js
+++ change.js
@@ -110,8 +110,10 @@
var gameState = 'menu'; // 'menu', 'playing', 'gameOver'
var pipeSpawnTimer = 0;
var pipeSpawnInterval = 90; // frames
var gapSize = 300; // Increased for larger game area
+var baseGapSize = 300;
+var basePipeInterval = 90;
var scrollSpeed = 4;
// Character selection
var currentCharacter = storage.selectedCharacter || 1;
var characterAssets = ['bird', 'bird2', 'bird3', 'bird4'];
@@ -302,9 +304,12 @@
}
// Function to spawn pipe
function spawnPipe() {
var pipe = new Pipe();
- var centerY = 300 + Math.random() * (GAME_HEIGHT - 500 - gapSize);
+ // Better gap positioning - ensure minimum distance from top and bottom
+ var minY = gapSize / 2 + 150; // Minimum distance from top
+ var maxY = GAME_HEIGHT - ground.height - gapSize / 2 - 150; // Maximum distance from bottom
+ var centerY = minY + Math.random() * (maxY - minY);
pipe.setGap(centerY, gapSize);
pipe.x = GAME_WIDTH + 100;
pipes.push(pipe);
game.addChild(pipe);
@@ -500,27 +505,35 @@
pipe.scored = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
LK.getSound('score').play();
+ // Dynamic difficulty - make game harder as score increases
+ var currentScore = LK.getScore();
+ if (currentScore > 0) {
+ // Gradually decrease gap size (minimum 200)
+ gapSize = Math.max(200, baseGapSize - currentScore * 5);
+ // Gradually decrease spawn interval (minimum 60 frames)
+ pipeSpawnInterval = Math.max(60, basePipeInterval - currentScore * 2);
+ }
}
- // Check collision with bird - use updated pipe structure
+ // Check collision with bird - use more accurate bird bounds
var birdBounds = {
- x: bird.x - 35,
- y: bird.y - 25,
- width: 70,
- height: 50
+ x: bird.x - 30,
+ y: bird.y - 20,
+ width: 60,
+ height: 40
};
var topPipeBounds = {
- x: pipe.x - 60,
+ x: pipe.x - 55,
y: 0,
- width: 120,
- height: pipe.topPipeBody.y
+ width: 110,
+ height: pipe.topPipeBody.y - 10
};
var bottomPipeBounds = {
- x: pipe.x - 60,
- y: pipe.bottomPipeBody.y,
- width: 120,
- height: GAME_HEIGHT - pipe.bottomPipeBody.y
+ x: pipe.x - 55,
+ y: pipe.bottomPipeBody.y + 10,
+ width: 110,
+ height: GAME_HEIGHT - pipe.bottomPipeBody.y - 10
};
// Check collision
if (birdBounds.x < topPipeBounds.x + topPipeBounds.width && birdBounds.x + birdBounds.width > topPipeBounds.x && birdBounds.y < topPipeBounds.y + topPipeBounds.height && birdBounds.y + birdBounds.height > topPipeBounds.y || birdBounds.x < bottomPipeBounds.x + bottomPipeBounds.width && birdBounds.x + birdBounds.width > bottomPipeBounds.x && birdBounds.y < bottomPipeBounds.y + bottomPipeBounds.height && birdBounds.y + birdBounds.height > bottomPipeBounds.y) {
gameOver = true;
@@ -538,10 +551,10 @@
pipe.destroy();
pipes.splice(i, 1);
}
}
- // Check ground collision - updated for new ground position
- if (bird.y + 30 >= ground.y) {
+ // Check ground collision - updated for new ground position with better bounds
+ if (bird.y + 20 >= ground.y) {
gameOver = true;
gameState = 'gameOver';
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 500);
@@ -550,10 +563,10 @@
restartTxt.visible = true;
scoreTxt.visible = false;
return;
}
- // Check ceiling collision
- if (bird.y - 30 <= 0) {
+ // Check ceiling collision with better bounds
+ if (bird.y - 20 <= 0) {
gameOver = true;
gameState = 'gameOver';
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 500);