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 () { // Only apply gravity and velocity if gameStarted is true if (typeof gameStarted !== "undefined" && gameStarted) { 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 = 80; // Start very thin, will be set wider on spawn self.gapHeight = 520; // Will be randomized a bit self.speed = 12; // Speed at which pipes move left // Top pipe (cloud) self.topPipe = self.attachAsset('cloud', { anchorX: 0, anchorY: 1, width: self.pipeWidth, height: 300, // cloud height y: 0, x: 0 }); // Bottom pipe (mountain) self.bottomPipe = self.attachAsset('mountain', { anchorX: 0, anchorY: 0, width: self.pipeWidth, height: 600, // mountain height 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 cloud: position at gapY, stretch to fill from top to gapY self.topPipe.y = gapY; self.topPipe.height = Math.max(1, gapY); // cloud height = gapY, min 1 self.topPipe.width = self.pipeWidth; // Bottom mountain: position at gapY+gapHeight, stretch to fill to bottom self.bottomPipe.y = gapY + gapHeight; self.bottomPipe.height = Math.max(1, 2732 - (gapY + gapHeight)); // mountain height self.bottomPipe.width = self.pipeWidth; }; // 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: 0x000000 }); /**** * Game Code ****/ // --- Dynamically adjust ground and upground height and their distance as score increases -- if (ground && upground) { // Calculate new height: ground gets taller as score increases, up to maxGroundHeight var minGroundHeight = 120; var maxGroundHeight = 400; var newGroundHeight = minGroundHeight + Math.floor((maxGroundHeight - minGroundHeight) * Math.min(1, score / 50)); if (newGroundHeight > maxGroundHeight) newGroundHeight = maxGroundHeight; if (newGroundHeight < minGroundHeight) newGroundHeight = minGroundHeight; ground.height = newGroundHeight; upground.height = newGroundHeight; // Calculate new gap: distance between ground and upground narrows as score increases, but never less than 900px var minGap = 900; var maxGap = 1800; var newGap = maxGap - Math.floor((maxGap - minGap) * Math.min(1, score / 50)); if (newGap < minGap) newGap = minGap; if (newGap > maxGap) newGap = maxGap; // Keep ground and upground full width, always at x=0 ground.x = 0; upground.x = 0; // Position ground at bottom, upground at top, with the gap between them ground.y = 2732 - newGap / 2 - newGroundHeight; upground.y = newGap / 2; } var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(background); // --- Cloud (top pipe) - white, wide, ellipse // Mountain (bottom pipe) - green, wide, triangle-like // --- 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; // --- Tap to Start Overlay --- var tapToStartTxt = new Text2('Tap to Start', { size: 140, fill: 0xffffff }); tapToStartTxt.anchor.set(0.5, 1); // anchor bottom center tapToStartTxt.x = 2048 / 2; // Place just above ground, with a visible gap (e.g. 120px ground + 80px gap) tapToStartTxt.y = 2732 - 120 - 80; tapToStartTxt.visible = false; // Remove from game if already added, then add to top if (tapToStartTxt.parent) tapToStartTxt.parent.removeChild(tapToStartTxt); game.addChild(tapToStartTxt); game.setChildIndex(tapToStartTxt, game.children.length - 1); // Always on top // --- GUI Score Display --- if (typeof scoreTxt !== "undefined" && scoreTxt && scoreTxt.parent) { scoreTxt.parent.removeChild(scoreTxt); scoreTxt.destroy(); } if (typeof scoreCircleBg !== "undefined" && scoreCircleBg && scoreCircleBg.parent) { scoreCircleBg.parent.removeChild(scoreCircleBg); scoreCircleBg.destroy(); } // Create a perfect circle background for the score and center it scoreCircleBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, x: LK.gui.width / 2, y: 80 + 45, // 45 is half of 90 (score text size), so circle is centered behind text scaleX: 0.8, scaleY: 0.8 }); LK.gui.addChild(scoreCircleBg); scoreTxt = new Text2('0', { size: 90, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0.5); // Center score horizontally at the top, vertically centered in the circle scoreTxt.x = LK.gui.width / 2; scoreTxt.y = 80 + 45; LK.gui.addChild(scoreTxt); // --- Ground (for collision) --- ground = LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 0, y: 2732 - 120 }); game.addChild(ground); // --- Mirrored ground at top (now called upground) --- var upground = LK.getAsset('ground', { anchorX: 0, anchorY: 1, x: 0, y: 0, scaleY: -1 }); game.addChild(upground); // --- Minimum ground width (never narrower than mountain/cloud asset) --- var minGroundWidth = 800; // same as mountain/cloud asset width var maxGroundWidth = 2048; // full width // --- 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 = []; // Ensure background is always at the back if (background && background.parent) { background.parent.setChildIndex(background, 0); } // 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; if (tapToStartTxt) { tapToStartTxt.visible = true; // Remove and re-add to ensure it's on top if (tapToStartTxt.parent) tapToStartTxt.parent.removeChild(tapToStartTxt); game.addChild(tapToStartTxt); game.setChildIndex(tapToStartTxt, game.children.length - 1); } } // --- Start game on first tap --- game.down = function (x, y, obj) { if (gameOver) { return; } if (!gameStarted) { gameStarted = true; if (tapToStartTxt) tapToStartTxt.visible = false; 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) // Calculate pipe width based on score: start thin, widen much more slowly var minPipeWidth = 80; var maxPipeWidth = 880; // Use a slower growth curve (e.g. score/120 instead of score/40) var pipeWidth = minPipeWidth + Math.floor((maxPipeWidth - minPipeWidth) * Math.min(1, score / 120)); // Clamp to max if (pipeWidth > maxPipeWidth) pipeWidth = maxPipeWidth; if (pipeWidth < minPipeWidth) pipeWidth = minPipeWidth; var pipePair = new PipePair(); pipePair.pipeWidth = pipeWidth; pipePair.topPipe.width = pipeWidth; pipePair.bottomPipe.width = pipeWidth; 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); LK.getSound('score').play(); pipe.passed = true; } } // --- Ground and upground remain at full width; no dynamic narrowing -- // 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(); // --- Pause Button --- // Place pause button at right, same vertical as scoreTxt var pauseBtn = new Text2('II', { size: 120, fill: 0xffffff }); pauseBtn.anchor.set(1, 0); // Place at top right, just below top edge (keep 80px from top for visibility) pauseBtn.x = 2048 - 60; // 60px from right edge pauseBtn.y = 80; LK.gui.addChild(pauseBtn); // Pause event (optional: you may want to hook this up to LK.pauseGame if available) // pauseBtn.down = function(x, y, obj) { // LK.pauseGame(); // };
===================================================================
--- original.js
+++ change.js
@@ -142,27 +142,29 @@
/****
* Game Code
****/
-// --- Dynamically adjust ground and upground width and their distance as score increases --
+// --- Dynamically adjust ground and upground height and their distance as score increases --
if (ground && upground) {
- // Calculate new width: ground gets wider as score increases, up to maxGroundWidth
- var newGroundWidth = minGroundWidth + Math.floor((maxGroundWidth - minGroundWidth) * Math.min(1, score / 50));
- if (newGroundWidth > maxGroundWidth) newGroundWidth = maxGroundWidth;
- if (newGroundWidth < minGroundWidth) newGroundWidth = minGroundWidth;
- ground.width = newGroundWidth;
- upground.width = newGroundWidth;
+ // Calculate new height: ground gets taller as score increases, up to maxGroundHeight
+ var minGroundHeight = 120;
+ var maxGroundHeight = 400;
+ var newGroundHeight = minGroundHeight + Math.floor((maxGroundHeight - minGroundHeight) * Math.min(1, score / 50));
+ if (newGroundHeight > maxGroundHeight) newGroundHeight = maxGroundHeight;
+ if (newGroundHeight < minGroundHeight) newGroundHeight = minGroundHeight;
+ ground.height = newGroundHeight;
+ upground.height = newGroundHeight;
// Calculate new gap: distance between ground and upground narrows as score increases, but never less than 900px
var minGap = 900;
var maxGap = 1800;
var newGap = maxGap - Math.floor((maxGap - minGap) * Math.min(1, score / 50));
if (newGap < minGap) newGap = minGap;
if (newGap > maxGap) newGap = maxGap;
- // Position ground and upground to keep them centered horizontally
- ground.x = (2048 - newGroundWidth) / 2;
- upground.x = (2048 - newGroundWidth) / 2;
+ // Keep ground and upground full width, always at x=0
+ ground.x = 0;
+ upground.x = 0;
// Position ground at bottom, upground at top, with the gap between them
- ground.y = 2732 - newGap / 2 - 120;
+ ground.y = 2732 - newGap / 2 - newGroundHeight;
upground.y = newGap / 2;
}
var background = LK.getAsset('background', {
anchorX: 0,
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