User prompt
Small still doesn't fit the floor, it just is floating
User prompt
Still doesn't fit the floor, it just is floating
User prompt
Make player character small version have it's own hitbox
User prompt
Make multiple copies of bg be there so loops more natural
User prompt
Re-add bg movement code
User prompt
Make it cover whole in-between the 2 and not move it stays there
User prompt
Make it cover whole in-between the 2 and not move it stays there
User prompt
Resize this into a bg in middle of floor and ceiling
User prompt
Add random spike and orb powerup patterns for each play! Orb makes player smaller and jump higher for 5 jumps. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Change hitboxes to be like the models here
User prompt
Add bg music loop
Code edit (1 edits merged)
Please save this source code
User prompt
Cave Runner
Initial prompt
Geometry Dash recreation. Don't call it geometry Rush, also cave bg
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var CeilingSegment = Container.expand(function () { var self = Container.call(this); var ceilingGraphics = self.attachAsset('ceiling', { anchorX: 0, anchorY: 1 }); self.speed = -8; self.update = function () { self.x += self.speed; }; return self; }); var GroundSegment = Container.expand(function () { var self = Container.call(this); var groundGraphics = self.attachAsset('ground', { anchorX: 0, anchorY: 0 }); self.speed = -8; self.update = function () { self.x += self.speed; }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('spike', { anchorX: 0.5, anchorY: 1.0 }); self.speed = -8; self.update = function () { self.x += self.speed; }; return self; }); var Orb = Container.expand(function () { var self = Container.call(this); var orbGraphics = self.attachAsset('orb', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -8; self.floatOffset = 0; // Start floating animation tween(self, { floatOffset: Math.PI * 2 }, { duration: 2000, easing: tween.linear, onFinish: function onFinish() { // Loop the animation self.floatOffset = 0; tween(self, { floatOffset: Math.PI * 2 }, { duration: 2000, easing: tween.linear }); } }); self.update = function () { self.x += self.speed; // Apply floating motion orbGraphics.y = Math.sin(self.floatOffset) * 20; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.velocityY = 0; self.gravity = 0.8; self.jumpPower = -16; self.isGrounded = false; self.groundY = 2400; self.isPoweredUp = false; self.powerupJumpsLeft = 0; self.originalScale = 1; self.originalJumpPower = self.jumpPower; self.jump = function () { if (self.isGrounded) { // Use enhanced jump power if powered up var currentJumpPower = self.isPoweredUp ? self.originalJumpPower * 1.5 : self.jumpPower; self.velocityY = currentJumpPower; self.isGrounded = false; LK.getSound('jump').play(); // Decrease powerup jumps if active if (self.isPoweredUp) { self.powerupJumpsLeft--; if (self.powerupJumpsLeft <= 0) { self.deactivatePowerup(); } } } }; self.update = function () { // Apply gravity self.velocityY += self.gravity; self.y += self.velocityY; // Adjust ground position based on scale - when small, player needs to be lower to touch ground var currentScale = self.isPoweredUp ? 0.7 : 1; var adjustedGroundY = self.groundY + 101 * (1 - currentScale); // 101 is half the player height // Ground collision if (self.y >= adjustedGroundY) { self.y = adjustedGroundY; self.velocityY = 0; self.isGrounded = true; } // Ceiling collision if (self.y <= 200) { self.y = 200; self.velocityY = 0; } }; self.activatePowerup = function () { self.isPoweredUp = true; self.powerupJumpsLeft = 5; // Make player smaller and change tint to golden tween(playerGraphics, { scaleX: 0.7, scaleY: 0.7, tint: 0xFFD700 }, { duration: 300, easing: tween.easeOut }); }; self.deactivatePowerup = function () { self.isPoweredUp = false; self.powerupJumpsLeft = 0; // Return player to normal size and color tween(playerGraphics, { scaleX: 1, scaleY: 1, tint: 0xFFFFFF }, { duration: 300, easing: tween.easeOut }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c1810 }); /**** * Game Code ****/ var player; var obstacles = []; var orbs = []; var groundSegments = []; var ceilingSegments = []; var gameSpeed = 8; var obstacleSpawnTimer = 0; var orbSpawnTimer = 0; var groundSpawnTimer = 0; var ceilingSpawnTimer = 0; var distance = 0; var isGameRunning = true; var obstaclePattern = []; var orbPattern = []; var patternIndex = 0; // Score display var scoreTxt = new Text2('Distance: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Add multiple background images for seamless looping var backgroundImages = []; for (var i = 0; i < 3; i++) { var backgroundImage = game.addChild(LK.getAsset('Bg', { anchorX: 0, anchorY: 0, scaleX: 20.48, scaleY: 24 })); backgroundImage.x = i * 2048; // Position backgrounds side by side backgroundImage.y = 100; // Start from ceiling backgroundImages.push(backgroundImage); } // Start background music LK.playMusic('Bg-music-loop'); // Generate initial random patterns generateRandomPattern(); // Create player player = game.addChild(new Player()); player.x = 400; player.y = 2400; // Initialize ground segments for (var i = 0; i < 15; i++) { var groundSeg = new GroundSegment(); groundSeg.x = i * 200; groundSeg.y = 2500; groundSegments.push(groundSeg); game.addChild(groundSeg); } // Initialize ceiling segments for (var i = 0; i < 15; i++) { var ceilingSeg = new CeilingSegment(); ceilingSeg.x = i * 200; ceilingSeg.y = 100; ceilingSegments.push(ceilingSeg); game.addChild(ceilingSeg); } function generateRandomPattern() { obstaclePattern = []; orbPattern = []; // Generate random obstacle pattern (30 positions) for (var i = 0; i < 30; i++) { obstaclePattern.push(Math.random() < 0.4); // 40% chance of obstacle } // Generate random orb pattern (15 positions, less frequent) for (var i = 0; i < 15; i++) { orbPattern.push(Math.random() < 0.2); // 20% chance of orb } patternIndex = 0; } function spawnObstacle() { // Use pattern if available, otherwise random var shouldSpawn = obstaclePattern.length > 0 ? obstaclePattern[patternIndex % obstaclePattern.length] : Math.random() < 0.4; if (shouldSpawn) { var obstacle = new Obstacle(); obstacle.x = 2200; obstacle.y = 2500; obstacles.push(obstacle); game.addChild(obstacle); } } function spawnOrb() { // Use pattern if available, otherwise random var shouldSpawn = orbPattern.length > 0 ? orbPattern[Math.floor(patternIndex / 2) % orbPattern.length] : Math.random() < 0.15; if (shouldSpawn) { var orb = new Orb(); orb.x = 2200; orb.y = 2200; // Higher up than obstacles orbs.push(orb); game.addChild(orb); } } function spawnGroundSegment() { var groundSeg = new GroundSegment(); groundSeg.x = 2200; groundSeg.y = 2500; groundSegments.push(groundSeg); game.addChild(groundSeg); } function spawnCeilingSegment() { var ceilingSeg = new CeilingSegment(); ceilingSeg.x = 2200; ceilingSeg.y = 100; ceilingSegments.push(ceilingSeg); game.addChild(ceilingSeg); } function resetGame() { isGameRunning = false; LK.getSound('death').play(); LK.effects.flashScreen(0xff0000, 500); LK.setTimeout(function () { LK.showGameOver(); }, 500); } function checkCollisions() { if (!isGameRunning) return; // Check obstacle collisions with precise hitboxes for (var i = 0; i < obstacles.length; i++) { var obstacle = obstacles[i]; // Player hitbox - smaller when powered up var hitboxScale = player.isPoweredUp ? 0.7 : 1; var playerLeft = player.x - 60 * hitboxScale; var playerRight = player.x + 60 * hitboxScale; var playerTop = player.y - 80 * hitboxScale; var playerBottom = player.y + 80 * hitboxScale; // Obstacle hitbox (spike - reduce width by 30% and height by 20% to match visual spike shape) var obstacleLeft = obstacle.x - 28; var obstacleRight = obstacle.x + 28; var obstacleTop = obstacle.y - 55; var obstacleBottom = obstacle.y; // Check if hitboxes overlap if (playerLeft < obstacleRight && playerRight > obstacleLeft && playerTop < obstacleBottom && playerBottom > obstacleTop) { resetGame(); return; } } // Check orb collisions for (var i = orbs.length - 1; i >= 0; i--) { var orb = orbs[i]; // Player hitbox - smaller when powered up var hitboxScale = player.isPoweredUp ? 0.7 : 1; var playerLeft = player.x - 60 * hitboxScale; var playerRight = player.x + 60 * hitboxScale; var playerTop = player.y - 80 * hitboxScale; var playerBottom = player.y + 80 * hitboxScale; // Orb hitbox var orbLeft = orb.x - 30; var orbRight = orb.x + 30; var orbTop = orb.y - 30; var orbBottom = orb.y + 30; // Check if hitboxes overlap if (playerLeft < orbRight && playerRight > orbLeft && playerTop < orbBottom && playerBottom > orbTop) { // Activate powerup player.activatePowerup(); LK.getSound('powerup').play(); // Remove orb orb.destroy(); orbs.splice(i, 1); } } } game.down = function (x, y, obj) { if (isGameRunning) { player.jump(); } }; game.update = function () { if (!isGameRunning) return; // Update distance distance += gameSpeed; LK.setScore(Math.floor(distance / 10)); scoreTxt.setText('Distance: ' + Math.floor(distance / 10)); // Move all background images with game world for (var i = 0; i < backgroundImages.length; i++) { backgroundImages[i].x -= gameSpeed; // Reset background position when it moves too far left for seamless looping if (backgroundImages[i].x <= -2048) { backgroundImages[i].x += 2048 * backgroundImages.length; } } // Spawn obstacles obstacleSpawnTimer++; if (obstacleSpawnTimer >= 90) { spawnObstacle(); obstacleSpawnTimer = 0; patternIndex++; // Generate new pattern every 30 spawns if (patternIndex % 30 === 0) { generateRandomPattern(); } } // Spawn orbs orbSpawnTimer++; if (orbSpawnTimer >= 180) { // Less frequent than obstacles spawnOrb(); orbSpawnTimer = 0; } // Spawn ground segments groundSpawnTimer++; if (groundSpawnTimer >= 25) { spawnGroundSegment(); groundSpawnTimer = 0; } // Spawn ceiling segments ceilingSpawnTimer++; if (ceilingSpawnTimer >= 25) { spawnCeilingSegment(); ceilingSpawnTimer = 0; } // Remove off-screen obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; if (obstacle.x < -100) { obstacle.destroy(); obstacles.splice(i, 1); } } // Remove off-screen orbs for (var i = orbs.length - 1; i >= 0; i--) { var orb = orbs[i]; if (orb.x < -100) { orb.destroy(); orbs.splice(i, 1); } } // Remove off-screen ground segments for (var i = groundSegments.length - 1; i >= 0; i--) { var groundSeg = groundSegments[i]; if (groundSeg.x < -300) { groundSeg.destroy(); groundSegments.splice(i, 1); } } // Remove off-screen ceiling segments for (var i = ceilingSegments.length - 1; i >= 0; i--) { var ceilingSeg = ceilingSegments[i]; if (ceilingSeg.x < -300) { ceilingSeg.destroy(); ceilingSegments.splice(i, 1); } } // Check collisions checkCollisions(); // Increase difficulty over time if (LK.ticks % 600 === 0 && gameSpeed < 12) { gameSpeed += 0.5; } };
===================================================================
--- original.js
+++ change.js
@@ -83,9 +83,9 @@
self.velocityY = 0;
self.gravity = 0.8;
self.jumpPower = -16;
self.isGrounded = false;
- self.groundY = 2425; // Adjust to account for player anchor and ground position
+ self.groundY = 2400;
self.isPoweredUp = false;
self.powerupJumpsLeft = 0;
self.originalScale = 1;
self.originalJumpPower = self.jumpPower;
@@ -108,11 +108,14 @@
self.update = function () {
// Apply gravity
self.velocityY += self.gravity;
self.y += self.velocityY;
+ // Adjust ground position based on scale - when small, player needs to be lower to touch ground
+ var currentScale = self.isPoweredUp ? 0.7 : 1;
+ var adjustedGroundY = self.groundY + 101 * (1 - currentScale); // 101 is half the player height
// Ground collision
- if (self.y >= self.groundY) {
- self.y = self.groundY;
+ if (self.y >= adjustedGroundY) {
+ self.y = adjustedGroundY;
self.velocityY = 0;
self.isGrounded = true;
}
// Ceiling collision
@@ -201,9 +204,9 @@
generateRandomPattern();
// Create player
player = game.addChild(new Player());
player.x = 400;
-player.y = 2425; // Position player to sit on ground properly
+player.y = 2400;
// Initialize ground segments
for (var i = 0; i < 15; i++) {
var groundSeg = new GroundSegment();
groundSeg.x = i * 200;