Skip to content

Instantly share code, notes, and snippets.

@shricodev
Created August 3, 2025 07:26
Show Gist options
  • Select an option

  • Save shricodev/09694c2ad7d6f4d19e4c2cf0e19f171d to your computer and use it in GitHub Desktop.

Select an option

Save shricodev/09694c2ad7d6f4d19e4c2cf0e19f171d to your computer and use it in GitHub Desktop.
Geometry Dash (Developed by Qwen 3 Coder AI Model) - Blog Demo
// 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);
}
}
<!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>
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