-
-
Save shricodev/09694c2ad7d6f4d19e4c2cf0e19f171d to your computer and use it in GitHub Desktop.
Geometry Dash (Developed by Qwen 3 Coder AI Model) - Blog Demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Enhanced Geometry Dash color palette | |
| const COLORS = { | |
| background: '#1a1a2e', | |
| background2: '#16213e', | |
| player: '#0f3460', | |
| playerAccent: '#e94560', | |
| obstacle: '#f39c12', | |
| spike: '#e74c3c', | |
| platform: '#2ecc71', | |
| movingPlatform: '#9b59b6', | |
| death: '#e74c3c', | |
| text: '#f1c40f', | |
| ui: '#ecf0f1', | |
| particle: '#3498db', | |
| particle2: '#9b59b6', | |
| particle3: '#e94560' | |
| }; | |
| // Game constants | |
| const GRAVITY = 0.6; | |
| const JUMP_FORCE = -14; | |
| const INITIAL_SPEED = 5; | |
| const MAX_SPEED = 12; | |
| class Game { | |
| constructor() { | |
| this.player = new Player(); | |
| this.obstacles = []; | |
| this.particles = []; | |
| this.gameSpeed = INITIAL_SPEED; | |
| this.gameState = 'menu'; // 'menu', 'playing', 'completed' | |
| this.attempts = 0; | |
| this.startTime = millis(); | |
| this.elapsedTime = 0; | |
| this.obstacleTimer = 0; | |
| this.levelProgress = 0; | |
| this.score = 0; | |
| this.backgroundOffset = 0; | |
| // Enhanced level design with more complex patterns | |
| this.levelBeats = [ | |
| // First section - basic obstacles | |
| 1, 2.5, 4, 5.5, 7, 8.5, 10, 11.5, 13, 14.5, 16, 17.5, 19, 20.5, 22, 23.5, | |
| // Second section - spike patterns | |
| 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, | |
| // Third section - platform challenges | |
| 42, 43.5, 45, 46.5, 48, 49.5, 51, 52.5, 54, 55.5, 57, 58.5, 60, 61.5, 63, 64.5, | |
| // Fourth section - mixed challenges | |
| 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, | |
| // Fifth section - intense pattern | |
| 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, | |
| // Final section - extreme challenge | |
| 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127 | |
| ]; | |
| this.nextBeatIndex = 0; | |
| this.beatInterval = 800; // milliseconds per beat (faster tempo) | |
| // Moving platforms | |
| this.movingPlatforms = []; | |
| // Decorative elements | |
| this.stars = []; | |
| this.generateStars(); | |
| this.attempts = 0; | |
| this.updateUI(); | |
| } | |
| update() { | |
| if (this.gameState === 'playing') { | |
| // Increase game speed over time for progressive difficulty | |
| this.gameSpeed = constrain(INITIAL_SPEED + this.elapsedTime * 0.1, INITIAL_SPEED, MAX_SPEED); | |
| // Update player | |
| this.player.update(); | |
| // Generate obstacles based on beats | |
| this.generateObstacles(); | |
| // Update obstacles | |
| for (let i = this.obstacles.length - 1; i >= 0; i--) { | |
| this.obstacles[i].update(this.gameSpeed); | |
| // Remove obstacles that are off screen | |
| if (this.obstacles[i].x + this.obstacles[i].width < 0) { | |
| this.obstacles.splice(i, 1); | |
| this.score += 10; // Score for passing obstacles | |
| } | |
| } | |
| // Update moving platforms | |
| for (let i = this.movingPlatforms.length - 1; i >= 0; i--) { | |
| this.movingPlatforms[i].update(this.gameSpeed); | |
| // Remove platforms that are off screen | |
| if (this.movingPlatforms[i].x + this.movingPlatforms[i].width < 0) { | |
| this.movingPlatforms.splice(i, 1); | |
| } | |
| } | |
| // Update particles | |
| for (let i = this.particles.length - 1; i >= 0; i--) { | |
| this.particles[i].update(); | |
| // Remove dead particles | |
| if (this.particles[i].life <= 0) { | |
| this.particles.splice(i, 1); | |
| } | |
| } | |
| // Update stars for background | |
| this.updateStars(); | |
| // Check collisions | |
| this.checkCollisions(); | |
| // Update timer | |
| this.elapsedTime = (millis() - this.startTime) / 1000; | |
| this.updateUI(); | |
| // Check level completion | |
| if (this.elapsedTime > 130) { // ~130 seconds for level completion | |
| this.gameState = 'completed'; | |
| } | |
| } | |
| } | |
| display() { | |
| // Draw animated background | |
| this.drawBackground(); | |
| // Draw stars | |
| for (let star of this.stars) { | |
| star.display(); | |
| } | |
| // Draw ground | |
| fill(COLORS.platform); | |
| noStroke(); | |
| rect(0, height - 20, width, 20); | |
| // Draw moving platforms | |
| for (let platform of this.movingPlatforms) { | |
| platform.display(); | |
| } | |
| // Draw player | |
| this.player.display(); | |
| // Draw obstacles | |
| for (let obstacle of this.obstacles) { | |
| obstacle.display(); | |
| } | |
| // Draw particles | |
| for (let particle of this.particles) { | |
| particle.display(); | |
| } | |
| // Draw game state overlays | |
| if (this.gameState === 'completed') { | |
| this.drawCompletionScreen(); | |
| } else if (this.gameState === 'menu') { | |
| this.drawMenuScreen(); | |
| } | |
| } | |
| drawBackground() { | |
| // Create animated gradient background | |
| let color1 = color(26, 26, 46); | |
| let color2 = color(22, 33, 62); | |
| for (let i = 0; i <= height; i++) { | |
| let inter = map(i, 0, height, 0, 1); | |
| let c = lerpColor(color1, color2, inter); | |
| stroke(c); | |
| line(0, i, width, i); | |
| } | |
| // Draw moving background elements | |
| this.drawBackgroundElements(); | |
| // Draw grid lines | |
| stroke(40, 40, 80, 30); | |
| strokeWeight(1); | |
| // Vertical lines | |
| for (let x = this.backgroundOffset; x < width; x += 30) { | |
| line(x, 0, x, height); | |
| } | |
| // Horizontal lines | |
| for (let y = this.backgroundOffset; y < height; y += 30) { | |
| line(0, y, width, y); | |
| } | |
| // Update background offset for animation | |
| this.backgroundOffset = (this.backgroundOffset + this.gameSpeed * 0.5) % 30; | |
| } | |
| drawBackgroundElements() { | |
| // Draw decorative circles | |
| noFill(); | |
| stroke(100, 100, 150, 20); | |
| strokeWeight(2); | |
| const time = millis() * 0.001; | |
| for (let i = 0; i < 5; i++) { | |
| const x = (sin(time + i) * 100 + width/2) % width; | |
| const y = (cos(time * 0.7 + i) * 80 + height/3) % height; | |
| const size = sin(time * 2 + i) * 20 + 30; | |
| ellipse(x, y, size, size); | |
| } | |
| } | |
| generateStars() { | |
| for (let i = 0; i < 50; i++) { | |
| this.stars.push(new Star( | |
| random(width), | |
| random(height * 0.7) | |
| )); | |
| } | |
| } | |
| updateStars() { | |
| for (let star of this.stars) { | |
| star.update(); | |
| } | |
| } | |
| generateObstacles() { | |
| // Generate obstacles based on level beats | |
| if (this.nextBeatIndex < this.levelBeats.length) { | |
| const beatTime = this.levelBeats[this.nextBeatIndex] * this.beatInterval; | |
| const currentTime = millis() - this.startTime; | |
| if (currentTime >= beatTime) { | |
| // Determine obstacle pattern based on level progression | |
| const section = Math.floor(this.nextBeatIndex / 20); | |
| let obstacleType, patternLength; | |
| switch(section) { | |
| case 0: // First section - basic obstacles | |
| obstacleType = floor(random(3)); // 0: gap, 1: spike, 2: platform | |
| patternLength = 1; | |
| break; | |
| case 1: // Second section - spike patterns | |
| obstacleType = 1; // Spike | |
| patternLength = floor(random(2, 5)); // 2-4 spikes in a row | |
| break; | |
| case 2: // Third section - platform challenges | |
| obstacleType = 2; // Platform | |
| patternLength = 1; | |
| break; | |
| case 3: // Fourth section - mixed challenges | |
| obstacleType = floor(random(3)); | |
| patternLength = floor(random(1, 3)); | |
| break; | |
| case 4: // Fifth section - intense pattern | |
| obstacleType = floor(random(2)); // Gap or spike | |
| patternLength = floor(random(3, 6)); // 3-5 obstacles in a row | |
| break; | |
| case 5: // Final section - extreme challenge | |
| obstacleType = floor(random(3)); | |
| patternLength = floor(random(4, 8)); // 4-7 obstacles in a row | |
| break; | |
| default: | |
| obstacleType = floor(random(3)); | |
| patternLength = 1; | |
| } | |
| // Create obstacle pattern | |
| for (let i = 0; i < patternLength; i++) { | |
| // Add special moving platforms in later sections | |
| if (section >= 2 && obstacleType === 2 && random() > 0.7) { | |
| this.movingPlatforms.push(new MovingPlatform(width + i * 90, height - 100)); | |
| } else { | |
| this.obstacles.push(new Obstacle(width + i * 30, height - 20, obstacleType)); | |
| } | |
| } | |
| this.nextBeatIndex += patternLength; | |
| } | |
| } | |
| } | |
| checkCollisions() { | |
| // Ground collision | |
| if (this.player.y + this.player.size > height - 20) { | |
| this.player.y = height - 20 - this.player.size; | |
| this.player.velocityY = 0; | |
| this.player.isGrounded = true; | |
| } | |
| // Obstacle collisions | |
| for (let obstacle of this.obstacles) { | |
| if (this.player.collidesWith(obstacle)) { | |
| this.playerDeath(); | |
| break; | |
| } | |
| } | |
| // Moving platform collisions | |
| for (let platform of this.movingPlatforms) { | |
| if (this.player.collidesWith(platform)) { | |
| // Land on top of platform | |
| if (this.player.velocityY > 0 && | |
| this.player.y + this.player.size < platform.y + 10) { | |
| this.player.y = platform.y - this.player.size; | |
| this.player.velocityY = 0; | |
| this.player.isGrounded = true; | |
| } | |
| } | |
| } | |
| } | |
| playerDeath() { | |
| // Create death particles | |
| for (let i = 0; i < 20; i++) { | |
| this.particles.push(new Particle( | |
| this.player.x + this.player.size/2, | |
| this.player.y + this.player.size/2, | |
| random() > 0.5 ? COLORS.death : (random() > 0.5 ? COLORS.particle : COLORS.particle3) | |
| )); | |
| } | |
| // Reset player | |
| this.player.reset(); | |
| // Reset obstacles | |
| this.obstacles = []; | |
| this.movingPlatforms = []; | |
| this.nextBeatIndex = 0; | |
| this.startTime = millis(); | |
| // Increment attempts | |
| this.attempts++; | |
| this.updateUI(); | |
| } | |
| updateUI() { | |
| document.getElementById('attempts').textContent = this.attempts; | |
| document.getElementById('time').textContent = Math.floor(this.elapsedTime); | |
| document.getElementById('score').textContent = this.score; | |
| } | |
| drawCompletionScreen() { | |
| // Semi-transparent overlay | |
| fill(0, 0, 0, 150); | |
| rect(0, 0, width, height); | |
| // Completion text | |
| fill(COLORS.text); | |
| textSize(48); | |
| textAlign(CENTER, CENTER); | |
| text('LEVEL COMPLETE!', width/2, height/2 - 60); | |
| textSize(24); | |
| fill(COLORS.ui); | |
| text(`Score: ${this.score}`, width/2, height/2 - 10); | |
| text(`Attempts: ${this.attempts}`, width/2, height/2 + 30); | |
| text(`Time: ${Math.floor(this.elapsedTime)}s`, width/2, height/2 + 70); | |
| textSize(18); | |
| fill(COLORS.platform); | |
| text('Refresh to play again', width/2, height/2 + 120); | |
| } | |
| drawMenuScreen() { | |
| // Semi-transparent overlay | |
| fill(0, 0, 0, 150); | |
| rect(0, 0, width, height); | |
| // Title | |
| fill(COLORS.text); | |
| textSize(48); | |
| textAlign(CENTER, CENTER); | |
| text('GEOMETRY DASH', width/2, height/2 - 60); | |
| textSize(24); | |
| fill(COLORS.ui); | |
| text('Click or Press SPACE to Start', width/2, height/2 + 20); | |
| textSize(18); | |
| fill(COLORS.platform); | |
| text('Use SPACE or MOUSE to jump', width/2, height/2 + 60); | |
| } | |
| startGame() { | |
| if (this.gameState === 'menu') { | |
| this.gameState = 'playing'; | |
| this.startTime = millis(); | |
| } | |
| } | |
| } | |
| class Player { | |
| constructor() { | |
| this.size = 20; | |
| this.x = 100; | |
| this.y = height - 40; | |
| this.velocityY = 0; | |
| this.isGrounded = true; | |
| this.gravity = GRAVITY; | |
| this.jumpForce = JUMP_FORCE; | |
| } | |
| update() { | |
| // Apply gravity | |
| this.velocityY += this.gravity; | |
| this.y += this.velocityY; | |
| // Ground collision | |
| if (this.y + this.size > height - 20) { | |
| this.y = height - 20 - this.size; | |
| this.velocityY = 0; | |
| this.isGrounded = true; | |
| } | |
| } | |
| display() { | |
| // Draw player with enhanced visuals | |
| fill(COLORS.player); | |
| stroke(COLORS.playerAccent); | |
| strokeWeight(2); | |
| rect(this.x, this.y, this.size, this.size, 5); // Slightly rounded corners | |
| // Add a simple face to make it more character-like | |
| fill(255); | |
| noStroke(); | |
| ellipse(this.x + 7, this.y + 8, 4, 4); // Left eye | |
| ellipse(this.x + 13, this.y + 8, 4, 4); // Right eye | |
| // Add a smile | |
| stroke(255); | |
| strokeWeight(1); | |
| noFill(); | |
| arc(this.x + 10, this.y + 15, 6, 4, 0, PI); | |
| } | |
| jump() { | |
| if (this.isGrounded) { | |
| this.velocityY = this.jumpForce; | |
| this.isGrounded = false; | |
| } | |
| } | |
| collidesWith(obstacle) { | |
| return ( | |
| this.x < obstacle.x + obstacle.width && | |
| this.x + this.size > obstacle.x && | |
| this.y < obstacle.y + obstacle.height && | |
| this.y + this.size > obstacle.y | |
| ); | |
| } | |
| reset() { | |
| this.y = height - 40; | |
| this.velocityY = 0; | |
| this.isGrounded = true; | |
| } | |
| } | |
| class Obstacle { | |
| constructor(x, groundY, type) { | |
| this.x = x; | |
| this.type = type; // 0: gap, 1: spike, 2: platform | |
| switch(this.type) { | |
| case 0: // Gap | |
| this.width = 60; | |
| this.height = 20; | |
| this.y = groundY; | |
| break; | |
| case 1: // Spike | |
| this.width = 20; | |
| this.height = 30; | |
| this.y = groundY - this.height; | |
| break; | |
| case 2: // Platform | |
| this.width = 80; | |
| this.height = 20; | |
| this.y = groundY - 60; // Higher platform | |
| break; | |
| } | |
| } | |
| update(speed) { | |
| this.x -= speed; | |
| } | |
| display() { | |
| noStroke(); | |
| switch(this.type) { | |
| case 0: // Gap (we represent it as a different colored ground section) | |
| fill(COLORS.background); | |
| rect(this.x, this.y, this.width, this.height); | |
| // Add visual indicator for gap | |
| fill(COLORS.spike); | |
| for (let i = 0; i < this.width; i += 10) { | |
| rect(this.x + i, this.y, 5, this.height); | |
| } | |
| break; | |
| case 1: // Spike (triangle) | |
| fill(COLORS.spike); | |
| triangle( | |
| this.x, this.y + this.height, | |
| this.x + this.width, this.y + this.height, | |
| this.x + this.width/2, this.y | |
| ); | |
| // Add details to spike | |
| fill(COLORS.death); | |
| triangle( | |
| this.x + 5, this.y + this.height - 5, | |
| this.x + this.width - 5, this.y + this.height - 5, | |
| this.x + this.width/2, this.y + 5 | |
| ); | |
| break; | |
| case 2: // Platform | |
| fill(COLORS.platform); | |
| rect(this.x, this.y, this.width, this.height, 5); | |
| // Add platform details | |
| fill(COLORS.background); | |
| rect(this.x + 5, this.y + 5, this.width - 10, 5); | |
| break; | |
| } | |
| } | |
| } | |
| class MovingPlatform { | |
| constructor(x, y) { | |
| this.x = x; | |
| this.y = y; | |
| this.width = 80; | |
| this.height = 15; | |
| this.speed = 2; | |
| this.direction = 1; | |
| this.moveRange = 100; | |
| this.startX = x; | |
| } | |
| update(gameSpeed) { | |
| this.x -= gameSpeed; | |
| // Move platform up and down | |
| this.y += this.speed * this.direction; | |
| if (this.y > height - 80 || this.y < height - 120) { | |
| this.direction *= -1; | |
| } | |
| } | |
| display() { | |
| fill(COLORS.movingPlatform); | |
| stroke(COLORS.playerAccent); | |
| strokeWeight(2); | |
| rect(this.x, this.y, this.width, this.height, 5); | |
| // Add moving platform details | |
| fill(COLORS.background); | |
| rect(this.x + 5, this.y + 3, this.width - 10, 3); | |
| } | |
| } | |
| class Particle { | |
| constructor(x, y, color) { | |
| this.x = x; | |
| this.y = y; | |
| this.color = color; | |
| this.size = random(3, 8); | |
| this.velocityX = random(-5, 5); | |
| this.velocityY = random(-5, 5); | |
| this.life = 30; | |
| } | |
| update() { | |
| this.x += this.velocityX; | |
| this.y += this.velocityY; | |
| this.life--; | |
| this.velocityY += 0.1; // Gravity | |
| } | |
| display() { | |
| fill(red(this.color), green(this.color), blue(this.color), this.life * 8); | |
| noStroke(); | |
| ellipse(this.x, this.y, this.size); | |
| } | |
| } | |
| class Star { | |
| constructor(x, y) { | |
| this.x = x; | |
| this.y = y; | |
| this.size = random(1, 3); | |
| this.brightness = random(100, 255); | |
| this.twinkleSpeed = random(0.01, 0.05); | |
| } | |
| update() { | |
| this.brightness = 150 + sin(millis() * this.twinkleSpeed) * 100; | |
| } | |
| display() { | |
| fill(255, 255, 255, this.brightness); | |
| noStroke(); | |
| ellipse(this.x, this.y, this.size); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Enhanced Geometry Dash</title> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script> | |
| <script src="sketch.js"></script> | |
| <script src="game.js"></script> | |
| <style> | |
| body { | |
| margin: 0; | |
| padding: 0; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 100vh; | |
| background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| overflow: hidden; | |
| color: #ecf0f1; | |
| } | |
| canvas { | |
| display: block; | |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); | |
| border-radius: 8px; | |
| } | |
| #ui { | |
| position: absolute; | |
| top: 20px; | |
| left: 20px; | |
| color: #f1c40f; | |
| font-weight: bold; | |
| text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | |
| background: rgba(0, 0, 0, 0.3); | |
| padding: 10px; | |
| border-radius: 5px; | |
| } | |
| #ui div { | |
| margin: 5px 0; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="ui"> | |
| <div>Attempts: <span id="attempts">0</span></div> | |
| <div>Time: <span id="time">0</span>s</div> | |
| <div>Score: <span id="score">0</span></div> | |
| </div> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let game; | |
| function setup() { | |
| createCanvas(800, 400); | |
| game = new Game(); | |
| } | |
| function draw() { | |
| game.update(); | |
| game.display(); | |
| } | |
| function keyPressed() { | |
| if (keyCode === 32) { // Spacebar | |
| if (game.gameState === 'menu') { | |
| game.startGame(); | |
| } else { | |
| game.player.jump(); | |
| } | |
| return false; // Prevent default behavior | |
| } | |
| } | |
| function mousePressed() { | |
| if (game.gameState === 'menu') { | |
| game.startGame(); | |
| } else { | |
| game.player.jump(); | |
| } | |
| return false; // Prevent default behavior | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment