User prompt
Increase ground and upground not width, "height" and narrow their distance as score increases
User prompt
when player get score grounds bigger and narrows both ground distance
User prompt
delete narrow both grounds
User prompt
make both ground narrow when score increased but dont narrow more than mountain and cloud
User prompt
make more small score
User prompt
fix score background position and change it to circle
User prompt
add a backgorund for score cirle shaped
User prompt
fix score has an error stacks all numbers in same position, show only one number
User prompt
add sound effect when get scored
User prompt
center position the score
User prompt
change score position to old position
User prompt
take last changes to back
User prompt
change score and pause button position to same distance like "tap to start" but position is upground
User prompt
give a name for upper/mirrored ground, change it name to upground
User prompt
add background to assets
User prompt
add a background for assets
User prompt
change location "tap to start" layer to down ground sprite's on but distance between
User prompt
put the top layer "tap to start"
User prompt
bird dont fall until game start
User prompt
when game open dont start instantly add a click to start
User prompt
wide more slowly
User prompt
change mountain and cloud thin and everytime player gets a score it wider but start very thin and slowly wide
User prompt
add ground to up side but mirrored
User prompt
can you change down side pipes to mountain and up side pipes to cloud
User prompt
2x wider pipes and curves like a mountain
/**** * Plugins ****/ var tween = LK.import("@upit/tween.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 }); // Physics properties self.velocityY = 0; self.gravity = 0.5; // Lower gravity per frame for slower fall self.flapStrength = -20; // Lower flap strength for gentler jump // Bird size for collision self.radius = birdAsset.width * 0.45; // Flap method self.flap = function () { self.velocityY = self.flapStrength; }; // Update method (called every tick) self.update = function () { self.velocityY += self.gravity; self.y += self.velocityY; // Clamp rotation for visual feedback (optional) var maxAngle = Math.PI / 4; var minAngle = -Math.PI / 6; var angle = self.velocityY / 40 * maxAngle; if (angle > maxAngle) { angle = maxAngle; } if (angle < minAngle) { angle = minAngle; } birdAsset.rotation = angle; }; 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 = 440; self.gapHeight = 520; // Will be randomized a bit self.speed = 12; // Speed at which pipes move left // Top pipe self.topPipe = self.attachAsset('pipe', { anchorX: 0, anchorY: 1, width: self.pipeWidth, // Height stretches from top of screen to gapY (set in setGap) height: 0, // will be set in setGap y: 0, x: 0 }); // Bottom pipe self.bottomPipe = self.attachAsset('pipe', { anchorX: 0, anchorY: 0, width: self.pipeWidth, // Height stretches from gapY+gapHeight to bottom of screen height: 0, // will be set in setGap y: 0, x: 0 }); // Used to track if score was already given for this pipe self.passed = false; // Set pipes' vertical positions self.setGap = function (gapY, gapHeight) { self.gapHeight = gapHeight; // Top pipe: from y=0 to gapY self.topPipe.y = gapY; self.topPipe.height = gapY; // Bottom pipe: from gapY+gapHeight to bottom of screen self.bottomPipe.y = gapY + gapHeight; self.bottomPipe.height = 2732 - (gapY + gapHeight); }; // Update method self.update = function () { self.x -= self.speed; }; // Collision check with bird self.collidesWith = function (bird) { // Bird's bounding circle var bx = bird.x; var by = bird.y; var r = bird.radius; // Top pipe rectangle var topRect = { x: self.x, y: 0, w: self.pipeWidth, h: self.topPipe.y }; // Bottom pipe rectangle var bottomRect = { x: self.x, y: self.bottomPipe.y, w: self.pipeWidth, h: 2732 - self.bottomPipe.y }; // Helper: circle-rect collision function circleRectCollide(cx, cy, cr, rx, ry, rw, rh) { var closestX = Math.max(rx, Math.min(cx, rx + rw)); var closestY = Math.max(ry, Math.min(cy, ry + rh)); var dx = cx - closestX; var dy = cy - closestY; return dx * dx + dy * dy < cr * cr; } if (circleRectCollide(bx, by, r, topRect.x, topRect.y, topRect.w, topRect.h)) { return true; } if (circleRectCollide(bx, by, r, bottomRect.x, bottomRect.y, bottomRect.w, bottomRect.h)) { return true; } return false; }; // Has bird passed this pipe? (for scoring) self.isPassedBy = function (bird) { return !self.passed && self.x + self.pipeWidth < bird.x - bird.radius; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Sky blue }); /**** * Game Code ****/ // --- Game Variables --- // Tween plugin for animations (not strictly needed for MVP, but included for future use) // --- Asset Initialization (shapes) --- var bird; var pipes = []; var pipeSpawnTimer = 0; var pipeInterval = 90; // Frames between pipes (1.5s at 60fps) var score = 0; var scoreTxt; var ground; var gameStarted = false; var gameOver = false; // --- GUI Score Display --- scoreTxt = new Text2('0', { size: 180, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Ground (for collision) --- ground = LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 0, y: 2732 - 120 }); game.addChild(ground); // --- Bird --- bird = new Bird(); game.addChild(bird); // Start position: horizontally 30% from left, vertically centered bird.x = 2048 * 0.3; bird.y = 2732 / 2; // --- Reset function --- function resetGame() { // Remove pipes for (var i = 0; i < pipes.length; i++) { pipes[i].destroy(); } pipes = []; // Reset bird bird.x = 2048 * 0.3; bird.y = 2732 / 2; bird.velocityY = 0; // Reset score score = 0; scoreTxt.setText(score); // Reset timers pipeSpawnTimer = 0; gameStarted = false; gameOver = false; } // --- Start game on first tap --- game.down = function (x, y, obj) { if (gameOver) { return; } if (!gameStarted) { gameStarted = true; bird.flap(); return; } bird.flap(); }; // --- Main update loop --- game.update = function () { if (gameOver) { return; } // Bird physics if (gameStarted) { bird.update(); } // Clamp bird to top of screen if (bird.y - bird.radius < 0) { bird.y = bird.radius; bird.velocityY = 0; } // Pipe spawning if (gameStarted) { pipeSpawnTimer++; if (pipeSpawnTimer >= pipeInterval) { pipeSpawnTimer = 0; // Mountain-like curve for gapY using a sine wave var minGapY = 350; var maxGapY = 2732 - 120 - 350 - 700; var t = (score + pipes.length) * 0.5; // t increases as more pipes spawn var amplitude = (maxGapY - minGapY) / 2; var centerY = minGapY + amplitude; var gapY = centerY + Math.sin(t) * amplitude; gapY = Math.max(minGapY, Math.min(maxGapY, gapY)); var gapHeight = 650 + Math.floor(Math.random() * 120); // 650-770 px (increased gap) var pipePair = new PipePair(); pipePair.x = 2048; pipePair.setGap(gapY, gapHeight); pipes.push(pipePair); game.addChild(pipePair); } } // Update pipes, check for collisions and scoring for (var i = pipes.length - 1; i >= 0; i--) { var pipe = pipes[i]; if (gameStarted) { pipe.update(); } // Remove pipes that are off screen if (pipe.x + pipe.pipeWidth < 0) { pipe.destroy(); pipes.splice(i, 1); continue; } // Collision if (gameStarted && pipe.collidesWith(bird)) { endGame(); return; } // Scoring if (gameStarted && pipe.isPassedBy(bird)) { score += 1; scoreTxt.setText(score); pipe.passed = true; } } // Ground collision if (gameStarted && bird.y + bird.radius >= 2732 - 120) { bird.y = 2732 - 120 - bird.radius; endGame(); return; } }; // --- End game --- function endGame() { if (gameOver) { return; } gameOver = true; LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); } // --- Reset on game over (handled by LK) --- LK.on('gameover', function () { resetGame(); }); // --- Initial reset --- resetGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.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
});
// Physics properties
self.velocityY = 0;
self.gravity = 0.5; // Lower gravity per frame for slower fall
self.flapStrength = -20; // Lower flap strength for gentler jump
// Bird size for collision
self.radius = birdAsset.width * 0.45;
// Flap method
self.flap = function () {
self.velocityY = self.flapStrength;
};
// Update method (called every tick)
self.update = function () {
self.velocityY += self.gravity;
self.y += self.velocityY;
// Clamp rotation for visual feedback (optional)
var maxAngle = Math.PI / 4;
var minAngle = -Math.PI / 6;
var angle = self.velocityY / 40 * maxAngle;
if (angle > maxAngle) {
angle = maxAngle;
}
if (angle < minAngle) {
angle = minAngle;
}
birdAsset.rotation = angle;
};
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 = 440;
self.gapHeight = 520; // Will be randomized a bit
self.speed = 12; // Speed at which pipes move left
// Top pipe
self.topPipe = self.attachAsset('pipe', {
anchorX: 0,
anchorY: 1,
width: self.pipeWidth,
// Height stretches from top of screen to gapY (set in setGap)
height: 0,
// will be set in setGap
y: 0,
x: 0
});
// Bottom pipe
self.bottomPipe = self.attachAsset('pipe', {
anchorX: 0,
anchorY: 0,
width: self.pipeWidth,
// Height stretches from gapY+gapHeight to bottom of screen
height: 0,
// will be set in setGap
y: 0,
x: 0
});
// Used to track if score was already given for this pipe
self.passed = false;
// Set pipes' vertical positions
self.setGap = function (gapY, gapHeight) {
self.gapHeight = gapHeight;
// Top pipe: from y=0 to gapY
self.topPipe.y = gapY;
self.topPipe.height = gapY;
// Bottom pipe: from gapY+gapHeight to bottom of screen
self.bottomPipe.y = gapY + gapHeight;
self.bottomPipe.height = 2732 - (gapY + gapHeight);
};
// Update method
self.update = function () {
self.x -= self.speed;
};
// Collision check with bird
self.collidesWith = function (bird) {
// Bird's bounding circle
var bx = bird.x;
var by = bird.y;
var r = bird.radius;
// Top pipe rectangle
var topRect = {
x: self.x,
y: 0,
w: self.pipeWidth,
h: self.topPipe.y
};
// Bottom pipe rectangle
var bottomRect = {
x: self.x,
y: self.bottomPipe.y,
w: self.pipeWidth,
h: 2732 - self.bottomPipe.y
};
// Helper: circle-rect collision
function circleRectCollide(cx, cy, cr, rx, ry, rw, rh) {
var closestX = Math.max(rx, Math.min(cx, rx + rw));
var closestY = Math.max(ry, Math.min(cy, ry + rh));
var dx = cx - closestX;
var dy = cy - closestY;
return dx * dx + dy * dy < cr * cr;
}
if (circleRectCollide(bx, by, r, topRect.x, topRect.y, topRect.w, topRect.h)) {
return true;
}
if (circleRectCollide(bx, by, r, bottomRect.x, bottomRect.y, bottomRect.w, bottomRect.h)) {
return true;
}
return false;
};
// Has bird passed this pipe? (for scoring)
self.isPassedBy = function (bird) {
return !self.passed && self.x + self.pipeWidth < bird.x - bird.radius;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Sky blue
});
/****
* Game Code
****/
// --- Game Variables ---
// Tween plugin for animations (not strictly needed for MVP, but included for future use)
// --- Asset Initialization (shapes) ---
var bird;
var pipes = [];
var pipeSpawnTimer = 0;
var pipeInterval = 90; // Frames between pipes (1.5s at 60fps)
var score = 0;
var scoreTxt;
var ground;
var gameStarted = false;
var gameOver = false;
// --- GUI Score Display ---
scoreTxt = new Text2('0', {
size: 180,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// --- Ground (for collision) ---
ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2732 - 120
});
game.addChild(ground);
// --- Bird ---
bird = new Bird();
game.addChild(bird);
// Start position: horizontally 30% from left, vertically centered
bird.x = 2048 * 0.3;
bird.y = 2732 / 2;
// --- Reset function ---
function resetGame() {
// Remove pipes
for (var i = 0; i < pipes.length; i++) {
pipes[i].destroy();
}
pipes = [];
// Reset bird
bird.x = 2048 * 0.3;
bird.y = 2732 / 2;
bird.velocityY = 0;
// Reset score
score = 0;
scoreTxt.setText(score);
// Reset timers
pipeSpawnTimer = 0;
gameStarted = false;
gameOver = false;
}
// --- Start game on first tap ---
game.down = function (x, y, obj) {
if (gameOver) {
return;
}
if (!gameStarted) {
gameStarted = true;
bird.flap();
return;
}
bird.flap();
};
// --- Main update loop ---
game.update = function () {
if (gameOver) {
return;
}
// Bird physics
if (gameStarted) {
bird.update();
}
// Clamp bird to top of screen
if (bird.y - bird.radius < 0) {
bird.y = bird.radius;
bird.velocityY = 0;
}
// Pipe spawning
if (gameStarted) {
pipeSpawnTimer++;
if (pipeSpawnTimer >= pipeInterval) {
pipeSpawnTimer = 0;
// Mountain-like curve for gapY using a sine wave
var minGapY = 350;
var maxGapY = 2732 - 120 - 350 - 700;
var t = (score + pipes.length) * 0.5; // t increases as more pipes spawn
var amplitude = (maxGapY - minGapY) / 2;
var centerY = minGapY + amplitude;
var gapY = centerY + Math.sin(t) * amplitude;
gapY = Math.max(minGapY, Math.min(maxGapY, gapY));
var gapHeight = 650 + Math.floor(Math.random() * 120); // 650-770 px (increased gap)
var pipePair = new PipePair();
pipePair.x = 2048;
pipePair.setGap(gapY, gapHeight);
pipes.push(pipePair);
game.addChild(pipePair);
}
}
// Update pipes, check for collisions and scoring
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
if (gameStarted) {
pipe.update();
}
// Remove pipes that are off screen
if (pipe.x + pipe.pipeWidth < 0) {
pipe.destroy();
pipes.splice(i, 1);
continue;
}
// Collision
if (gameStarted && pipe.collidesWith(bird)) {
endGame();
return;
}
// Scoring
if (gameStarted && pipe.isPassedBy(bird)) {
score += 1;
scoreTxt.setText(score);
pipe.passed = true;
}
}
// Ground collision
if (gameStarted && bird.y + bird.radius >= 2732 - 120) {
bird.y = 2732 - 120 - bird.radius;
endGame();
return;
}
};
// --- End game ---
function endGame() {
if (gameOver) {
return;
}
gameOver = true;
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
}
// --- Reset on game over (handled by LK) ---
LK.on('gameover', function () {
resetGame();
});
// --- Initial reset ---
resetGame();
galaxy theme background. In-Game asset. 2d. High contrast. No shadows
only black hole simple no background. In-Game asset. 2d. High contrast. No shadows
galactic portals looks like a black hole. In-Game asset. 2d. High contrast. No shadows
galactic portals looks like a long straight pillar . In-Game asset. 2d. High contrast. No shadows
create an ufo without legs only frizby shape. In-Game asset. 2d. High contrast. No shadows