User prompt
Delete sapsik
User prompt
delete old close button
User prompt
Add the store close button as a small cross in the top right corner of the close menu
User prompt
And it costs 50 coin
User prompt
add sapsik asset into the store
User prompt
Let every money give 1 million money
User prompt
Let each money be 500 points
User prompt
if you have 500 points, show the screen that you won and write the number of games won at the bottom left of the screen for each win and remember the number of games won for each account that enters the game ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
add a beautiful pixel sky
User prompt
The costumes purchased by the player should be permanent in the account he entered the game with
User prompt
add bird3 asset into the store
User prompt
Don't let the character move without clicking
User prompt
add bird2 asset into the store
User prompt
delete gold and green skins
User prompt
Move the button down a little bit so that the game doesn't end when you press that button
User prompt
When you press the shop button, a menu will appear where we can buy skins for our character with money. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
hide shope button when pressing start button
User prompt
delete shop button when pressing start button
User prompt
delete store button when pressing start button
User prompt
add a shop button
User prompt
add start button
User prompt
Remember how much money the account that entered the game had ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Remember the account of the person who entered the game and write the highest score he earned in the bottom right corner of the screen ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Let the bird jump higher
User prompt
a little big faster
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Bird class
var Bird = Container.expand(function () {
var self = Container.call(this);
// Attach bird asset (ellipse, yellow)
var birdAsset = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
// Set up bird asset properties
birdAsset.width = 120;
birdAsset.height = 120;
birdAsset.color = 0xffe066;
birdAsset.shape = 'ellipse';
// Bird skin logic
self.currentSkin = typeof storage.selectedSkin === "string" ? storage.selectedSkin : "default";
self.setSkin = function (skinId) {
// Remove old asset
if (self.children.length > 0) {
self.removeChild(self.children[0]);
}
// Pick asset for skin
var assetId = "bird";
if (skinId === "gold") assetId = "coin";
if (skinId === "green") assetId = "pipeTop";
var asset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
asset.width = 120;
asset.height = 120;
self.currentSkin = skinId;
};
self.setSkin(self.currentSkin);
// Bird physics
self.velocityY = 0;
self.gravity = 1.1; // Gravity per frame (slightly faster than before)
self.flapStrength = -26; // Negative for upward movement (higher jump)
// Bird update method (called every tick)
self.update = function () {
self.velocityY += self.gravity;
self.y += self.velocityY;
// Clamp bird to not go above the screen
if (self.y < self.height / 2) {
self.y = self.height / 2;
self.velocityY = 0;
}
};
// Flap method
self.flap = function () {
self.velocityY = self.flapStrength;
};
return self;
});
// Coin class
var Coin = Container.expand(function () {
var self = Container.call(this);
// Attach coin asset (ellipse, gold)
var coinAsset = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
width: 100,
height: 100,
color: 0xffd700,
shape: 'ellipse',
x: 0,
y: 0
});
self.collected = false;
// Coin update: move left at pipe speed
self.update = function (speed) {
self.x -= speed;
};
return self;
});
// PipePair class (top and bottom pipes as a pair)
var PipePair = Container.expand(function () {
var self = Container.call(this);
// Pipe properties
self.pipeWidth = 220;
self.gapHeight = 520; // Vertical gap between pipes
self.speed = 16; // Speed at which pipes move left (increased for faster gameplay)
// Randomize gap position
var minGapY = 400;
var maxGapY = 2732 - 400 - self.gapHeight;
self.gapY = minGapY + Math.floor(Math.random() * (maxGapY - minGapY + 1));
// Top pipe
self.topPipe = self.attachAsset('pipeTop', {
anchorX: 0.5,
anchorY: 1.0,
width: self.pipeWidth,
height: self.gapY,
color: 0x4ec04e,
shape: 'box',
x: 0,
y: self.gapY
});
// Bottom pipe
self.bottomPipe = self.attachAsset('pipeBottom', {
anchorX: 0.5,
anchorY: 0.0,
width: self.pipeWidth,
height: 2732 - (self.gapY + self.gapHeight),
color: 0x4ec04e,
shape: 'box',
x: 0,
y: self.gapY + self.gapHeight
});
// Scoring flag (to ensure only one score per pipe pair)
self.scored = false;
// Add coin between pipes
self.coin = new Coin();
// Place coin in the center of the gap
self.coin.x = 0;
self.coin.y = self.gapY + self.gapHeight / 2;
self.addChild(self.coin);
// Update method
self.update = function () {
self.x -= self.speed;
// Coin does not move independently; it stays fixed between the pipes
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Sky blue
});
/****
* Game Code
****/
// Tween plugin for animations (optional, not used in MVP but included for future use)
// Game constants
var GROUND_HEIGHT = 220;
var PIPE_INTERVAL = 70; // Frames between pipes (faster spawn rate)
var BIRD_START_X = 600;
var BIRD_START_Y = 1200;
// Game state variables
var bird;
var pipes = [];
var score = 0;
var scoreTxt;
var ground;
var gameStarted = false;
var gameOver = false;
var ticksSinceLastPipe = 0;
// Add ground (simple green box at bottom)
ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
width: 2048,
height: GROUND_HEIGHT,
color: 0x3b7a2a,
shape: 'box',
x: 0,
y: 2732 - GROUND_HEIGHT
});
game.addChild(ground);
// Add bird
bird = new Bird();
bird.x = BIRD_START_X;
bird.y = BIRD_START_Y;
game.addChild(bird);
// Add score text to GUI
scoreTxt = new Text2('0', {
size: 180,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Add start button to center of screen
var startBtn = new Text2('START', {
size: 220,
fill: 0xffffff,
font: "Impact, Arial Black, Tahoma"
});
startBtn.anchor.set(0.5, 0.5);
startBtn.x = 2048 / 2;
startBtn.y = 2732 / 2;
game.addChild(startBtn);
// Start button tap handler
startBtn.down = function (x, y, obj) {
if (!gameStarted && !gameOver) {
startGame();
startBtn.visible = false;
}
};
// Show/hide start button based on game state
function showStartButton() {
if (typeof startBtn !== "undefined") startBtn.visible = true;
}
function hideStartButton() {
if (typeof startBtn !== "undefined") startBtn.visible = false;
}
// Add money icon and money counter to the right side of the screen
var moneyIcon = LK.getAsset('coin', {
anchorX: 1,
anchorY: 0,
width: 100,
height: 100,
x: 0,
y: 0
});
var moneyAmount = 0;
var moneyTxt = new Text2('0', {
size: 120,
fill: 0xffd700
});
moneyTxt.anchor.set(1, 0);
// Position icon and text at the top right, with some margin from the edge
moneyIcon.x = -40;
moneyIcon.y = 40;
moneyTxt.x = -160;
moneyTxt.y = 60;
LK.gui.topRight.addChild(moneyIcon);
LK.gui.topRight.addChild(moneyTxt);
// Add shop button to top right (below money)
var shopBtn = new Text2('SHOP', {
size: 100,
fill: 0xffffff,
font: "Impact, Arial Black, Tahoma"
});
shopBtn.anchor.set(1, 0);
shopBtn.x = -40;
shopBtn.y = 160;
LK.gui.topRight.addChild(shopBtn);
// High score tracking
var highScore = typeof storage.highScore === "number" ? storage.highScore : 0;
var highScoreTxt = new Text2('Best: ' + highScore, {
size: 100,
fill: 0xffffff
});
highScoreTxt.anchor.set(1, 1);
// Position at bottom right with margin
highScoreTxt.x = -40;
highScoreTxt.y = -40;
LK.gui.bottomRight.addChild(highScoreTxt);
// --- Shop Menu UI and Logic ---
var shopMenu = new Container();
shopMenu.visible = false;
game.addChild(shopMenu);
// Shop background
var shopBg = LK.getAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
width: 900,
height: 1200,
color: 0x222222,
shape: 'box',
x: 2048 / 2,
y: 2732 / 2
});
shopMenu.addChild(shopBg);
// Shop title
var shopTitle = new Text2('SKIN SHOP', {
size: 140,
fill: 0xffffff,
font: "Impact, Arial Black, Tahoma"
});
shopTitle.anchor.set(0.5, 0);
shopTitle.x = 2048 / 2;
shopTitle.y = 2732 / 2 - 500;
shopMenu.addChild(shopTitle);
// Skins data (id, label, price, assetId)
var skins = [{
id: "default",
label: "Classic",
price: 0,
asset: "bird"
}, {
id: "gold",
label: "Gold",
price: 10,
asset: "coin"
}, {
id: "green",
label: "Green",
price: 15,
asset: "pipeTop"
}];
// Load owned skins from storage or default to only "default"
var ownedSkins = storage.ownedSkins && Array.isArray(storage.ownedSkins) ? storage.ownedSkins : ["default"];
var selectedSkin = typeof storage.selectedSkin === "string" ? storage.selectedSkin : "default";
// Helper to update skin buttons
function updateSkinButtons() {
for (var i = 0; i < skinButtons.length; i++) {
var btn = skinButtons[i];
var skin = skins[i];
if (ownedSkins.indexOf(skin.id) !== -1) {
btn.setText(skin.label + (selectedSkin === skin.id ? " (Selected)" : ""));
} else {
btn.setText(skin.label + " (" + skin.price + "💰)");
}
}
}
// Create skin buttons
var skinButtons = [];
for (var i = 0; i < skins.length; i++) {
(function (idx) {
var skin = skins[idx];
var btn = new Text2(skin.label, {
size: 100,
fill: 0xffffff,
font: "Impact, Arial Black, Tahoma"
});
btn.anchor.set(0.5, 0);
btn.x = 2048 / 2;
btn.y = 2732 / 2 - 250 + idx * 220;
btn.down = function (x, y, obj) {
// If already owned, select it
if (ownedSkins.indexOf(skin.id) !== -1) {
selectedSkin = skin.id;
storage.selectedSkin = selectedSkin;
updateSkinButtons();
// Update bird skin if in game
if (typeof bird !== "undefined" && bird.setSkin) bird.setSkin(selectedSkin);
} else if (moneyAmount >= skin.price) {
// Buy skin
moneyAmount -= skin.price;
storage.moneyAmount = moneyAmount;
moneyTxt.setText(moneyAmount + '');
ownedSkins.push(skin.id);
storage.ownedSkins = ownedSkins;
selectedSkin = skin.id;
storage.selectedSkin = selectedSkin;
updateSkinButtons();
if (typeof bird !== "undefined" && bird.setSkin) bird.setSkin(selectedSkin);
}
};
shopMenu.addChild(btn);
skinButtons.push(btn);
})(i);
}
// Close button
var closeShopBtn = new Text2('CLOSE', {
size: 100,
fill: 0xff4444,
font: "Impact, Arial Black, Tahoma"
});
closeShopBtn.anchor.set(0.5, 1);
closeShopBtn.x = 2048 / 2;
closeShopBtn.y = 2732 / 2 + 550;
closeShopBtn.down = function (x, y, obj) {
shopMenu.visible = false;
};
shopMenu.addChild(closeShopBtn);
// Shop button handler
shopBtn.down = function (x, y, obj) {
updateSkinButtons();
shopMenu.visible = true;
};
// Helper: Reset game state
function resetGame() {
// Remove all pipes
for (var i = 0; i < pipes.length; i++) {
pipes[i].destroy();
}
pipes = [];
score = 0;
scoreTxt.setText('0');
moneyAmount = typeof storage.moneyAmount === "number" ? storage.moneyAmount : 0;
if (typeof moneyTxt !== "undefined") moneyTxt.setText(moneyAmount + '');
// Update high score from storage in case it changed externally
if (typeof storage.highScore === "number") {
highScore = storage.highScore;
if (typeof highScoreTxt !== "undefined") {
highScoreTxt.setText('Best: ' + highScore);
}
}
bird.x = BIRD_START_X;
bird.y = BIRD_START_Y;
bird.velocityY = 0;
// Restore bird skin
if (typeof bird.setSkin === "function") {
var skinToSet = typeof storage.selectedSkin === "string" ? storage.selectedSkin : "default";
bird.setSkin(skinToSet);
}
gameStarted = false;
gameOver = false;
ticksSinceLastPipe = 0;
showStartButton();
}
// Helper: Start game (first flap)
function startGame() {
if (!gameStarted && !gameOver) {
gameStarted = true;
hideStartButton();
}
}
// Helper: End game
function endGame() {
gameOver = true;
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
if (typeof highScoreTxt !== "undefined") {
highScoreTxt.setText('Best: ' + highScore);
}
}
LK.effects.flashScreen(0xff0000, 600);
hideStartButton();
LK.showGameOver();
}
// Game tap/flap handler
game.down = function (x, y, obj) {
if (gameOver) return;
if (!gameStarted) {
startGame();
}
bird.flap();
};
// Main game update loop
game.update = function () {
if (gameOver) return;
// Only update bird and pipes if game started
if (gameStarted) {
bird.update();
// Add new pipes at interval
ticksSinceLastPipe++;
if (ticksSinceLastPipe >= PIPE_INTERVAL) {
ticksSinceLastPipe = 0;
var pipePair = new PipePair();
pipePair.x = 2048 + pipePair.pipeWidth / 2;
pipePair.y = 0;
pipes.push(pipePair);
game.addChild(pipePair);
}
// Update pipes and check for collisions
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
pipe.update();
// Remove pipes that have gone off screen
if (pipe.x < -pipe.pipeWidth / 2) {
pipe.destroy();
pipes.splice(i, 1);
continue;
}
// Collision detection (bird with pipes)
// Use .intersects for both top and bottom pipes
if (bird.intersects(pipe.topPipe) || bird.intersects(pipe.bottomPipe)) {
endGame();
return;
}
// Coin collection
if (pipe.coin && !pipe.coin.collected && bird.intersects(pipe.coin)) {
pipe.coin.collected = true;
pipe.coin.visible = false;
score += 5; // Award 5 points for coin
scoreTxt.setText(score + '');
moneyAmount += 1;
moneyTxt.setText(moneyAmount + '');
// Persist moneyAmount to storage
storage.moneyAmount = moneyAmount;
}
// Scoring: if bird passes the center of the pipe and hasn't scored yet
if (!pipe.scored && pipe.x + pipe.pipeWidth / 2 < bird.x - bird.width / 2) {
pipe.scored = true;
score += 1;
scoreTxt.setText(score + '');
}
}
// Collision with ground
if (bird.y + bird.height / 2 >= 2732 - GROUND_HEIGHT) {
bird.y = 2732 - GROUND_HEIGHT - bird.height / 2;
endGame();
return;
}
}
};
// Reset game on game over (handled by LK automatically, but for clarity)
game.onGameOver = function () {
resetGame();
};
// Initial reset
resetGame(); ===================================================================
--- original.js
+++ change.js
@@ -19,8 +19,28 @@
birdAsset.width = 120;
birdAsset.height = 120;
birdAsset.color = 0xffe066;
birdAsset.shape = 'ellipse';
+ // Bird skin logic
+ self.currentSkin = typeof storage.selectedSkin === "string" ? storage.selectedSkin : "default";
+ self.setSkin = function (skinId) {
+ // Remove old asset
+ if (self.children.length > 0) {
+ self.removeChild(self.children[0]);
+ }
+ // Pick asset for skin
+ var assetId = "bird";
+ if (skinId === "gold") assetId = "coin";
+ if (skinId === "green") assetId = "pipeTop";
+ var asset = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ asset.width = 120;
+ asset.height = 120;
+ self.currentSkin = skinId;
+ };
+ self.setSkin(self.currentSkin);
// Bird physics
self.velocityY = 0;
self.gravity = 1.1; // Gravity per frame (slightly faster than before)
self.flapStrength = -26; // Negative for upward movement (higher jump)
@@ -119,10 +139,10 @@
/****
* Game Code
****/
-// Game constants
// Tween plugin for animations (optional, not used in MVP but included for future use)
+// Game constants
var GROUND_HEIGHT = 220;
var PIPE_INTERVAL = 70; // Frames between pipes (faster spawn rate)
var BIRD_START_X = 600;
var BIRD_START_Y = 1200;
@@ -173,11 +193,8 @@
startBtn.down = function (x, y, obj) {
if (!gameStarted && !gameOver) {
startGame();
startBtn.visible = false;
- if (typeof shopBtn !== "undefined") {
- shopBtn.visible = false;
- }
}
};
// Show/hide start button based on game state
function showStartButton() {
@@ -207,8 +224,18 @@
moneyTxt.x = -160;
moneyTxt.y = 60;
LK.gui.topRight.addChild(moneyIcon);
LK.gui.topRight.addChild(moneyTxt);
+// Add shop button to top right (below money)
+var shopBtn = new Text2('SHOP', {
+ size: 100,
+ fill: 0xffffff,
+ font: "Impact, Arial Black, Tahoma"
+});
+shopBtn.anchor.set(1, 0);
+shopBtn.x = -40;
+shopBtn.y = 160;
+LK.gui.topRight.addChild(shopBtn);
// High score tracking
var highScore = typeof storage.highScore === "number" ? storage.highScore : 0;
var highScoreTxt = new Text2('Best: ' + highScore, {
size: 100,
@@ -218,8 +245,122 @@
// Position at bottom right with margin
highScoreTxt.x = -40;
highScoreTxt.y = -40;
LK.gui.bottomRight.addChild(highScoreTxt);
+// --- Shop Menu UI and Logic ---
+var shopMenu = new Container();
+shopMenu.visible = false;
+game.addChild(shopMenu);
+// Shop background
+var shopBg = LK.getAsset('ground', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 900,
+ height: 1200,
+ color: 0x222222,
+ shape: 'box',
+ x: 2048 / 2,
+ y: 2732 / 2
+});
+shopMenu.addChild(shopBg);
+// Shop title
+var shopTitle = new Text2('SKIN SHOP', {
+ size: 140,
+ fill: 0xffffff,
+ font: "Impact, Arial Black, Tahoma"
+});
+shopTitle.anchor.set(0.5, 0);
+shopTitle.x = 2048 / 2;
+shopTitle.y = 2732 / 2 - 500;
+shopMenu.addChild(shopTitle);
+// Skins data (id, label, price, assetId)
+var skins = [{
+ id: "default",
+ label: "Classic",
+ price: 0,
+ asset: "bird"
+}, {
+ id: "gold",
+ label: "Gold",
+ price: 10,
+ asset: "coin"
+}, {
+ id: "green",
+ label: "Green",
+ price: 15,
+ asset: "pipeTop"
+}];
+// Load owned skins from storage or default to only "default"
+var ownedSkins = storage.ownedSkins && Array.isArray(storage.ownedSkins) ? storage.ownedSkins : ["default"];
+var selectedSkin = typeof storage.selectedSkin === "string" ? storage.selectedSkin : "default";
+// Helper to update skin buttons
+function updateSkinButtons() {
+ for (var i = 0; i < skinButtons.length; i++) {
+ var btn = skinButtons[i];
+ var skin = skins[i];
+ if (ownedSkins.indexOf(skin.id) !== -1) {
+ btn.setText(skin.label + (selectedSkin === skin.id ? " (Selected)" : ""));
+ } else {
+ btn.setText(skin.label + " (" + skin.price + "💰)");
+ }
+ }
+}
+// Create skin buttons
+var skinButtons = [];
+for (var i = 0; i < skins.length; i++) {
+ (function (idx) {
+ var skin = skins[idx];
+ var btn = new Text2(skin.label, {
+ size: 100,
+ fill: 0xffffff,
+ font: "Impact, Arial Black, Tahoma"
+ });
+ btn.anchor.set(0.5, 0);
+ btn.x = 2048 / 2;
+ btn.y = 2732 / 2 - 250 + idx * 220;
+ btn.down = function (x, y, obj) {
+ // If already owned, select it
+ if (ownedSkins.indexOf(skin.id) !== -1) {
+ selectedSkin = skin.id;
+ storage.selectedSkin = selectedSkin;
+ updateSkinButtons();
+ // Update bird skin if in game
+ if (typeof bird !== "undefined" && bird.setSkin) bird.setSkin(selectedSkin);
+ } else if (moneyAmount >= skin.price) {
+ // Buy skin
+ moneyAmount -= skin.price;
+ storage.moneyAmount = moneyAmount;
+ moneyTxt.setText(moneyAmount + '');
+ ownedSkins.push(skin.id);
+ storage.ownedSkins = ownedSkins;
+ selectedSkin = skin.id;
+ storage.selectedSkin = selectedSkin;
+ updateSkinButtons();
+ if (typeof bird !== "undefined" && bird.setSkin) bird.setSkin(selectedSkin);
+ }
+ };
+ shopMenu.addChild(btn);
+ skinButtons.push(btn);
+ })(i);
+}
+// Close button
+var closeShopBtn = new Text2('CLOSE', {
+ size: 100,
+ fill: 0xff4444,
+ font: "Impact, Arial Black, Tahoma"
+});
+closeShopBtn.anchor.set(0.5, 1);
+closeShopBtn.x = 2048 / 2;
+closeShopBtn.y = 2732 / 2 + 550;
+closeShopBtn.down = function (x, y, obj) {
+ shopMenu.visible = false;
+};
+shopMenu.addChild(closeShopBtn);
+// Shop button handler
+shopBtn.down = function (x, y, obj) {
+ updateSkinButtons();
+ shopMenu.visible = true;
+};
// Helper: Reset game state
function resetGame() {
// Remove all pipes
for (var i = 0; i < pipes.length; i++) {
@@ -239,8 +380,13 @@
}
bird.x = BIRD_START_X;
bird.y = BIRD_START_Y;
bird.velocityY = 0;
+ // Restore bird skin
+ if (typeof bird.setSkin === "function") {
+ var skinToSet = typeof storage.selectedSkin === "string" ? storage.selectedSkin : "default";
+ bird.setSkin(skinToSet);
+ }
gameStarted = false;
gameOver = false;
ticksSinceLastPipe = 0;
showStartButton();
@@ -337,21 +483,5 @@
game.onGameOver = function () {
resetGame();
};
// Initial reset
-resetGame();
-// Add shop button to bottom center of the screen
-var shopBtn = new Text2('SHOP', {
- size: 180,
- fill: 0xffffff,
- font: "Impact, Arial Black, Tahoma"
-});
-shopBtn.anchor.set(0.5, 0.5);
-shopBtn.x = 2048 / 2;
-shopBtn.y = 2732 - 180; // 180px above bottom edge for visibility
-game.addChild(shopBtn);
-// Shop button tap handler (currently just a placeholder)
-shopBtn.down = function (x, y, obj) {
- // TODO: Open shop UI or handle shop logic here
- // For now, just flash the screen to show it's working
- LK.effects.flashScreen(0xffff00, 300);
-};
\ No newline at end of file
+resetGame();
\ No newline at end of file
a pixel art coin. In-Game asset. 2d. High contrast. pixel
a bird like flappy bird but they are not same In-Game asset. 2d. High contrast. pixel
green grass ground. In-Game asset. 2d. High contrast. pixel no shadow
a beautiful sky. pixel In-Game asset. 2d. High contrast. No shadows
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Flappy Flight" and with the description "Guide a bird through gaps in pipes by tapping to flap and avoid obstacles. Score points for each successful pass.". No text on banner! pixel
a long mario pipeTop. pixel PIPE TOP In-Game asset. 2d. High contrast. No shadows
a pixel bird head. In-Game asset. 2d. High contrast. No shadows
Shop background. In-Game asset. 2d. High contrast. No shadows