Doodle Jump in Python- How to Code Doodle Jump
What You're Building
Doodle Jump is that annoying-addictive mobile game where a creature bounces upward on platforms forever. The core loop is dead simple: jump, land, bounce, fall, repeat. The "hard part" is making it feel responsive and actually fun.
You can build a working version in Python in under 200 lines. This guide gets you there.
What You Need Before Starting
- Python 3.8+ installed
- Pygame library (
pip install pygame) - Basic Python knowledge (classes, loops, collision detection)
- About 2-3 hours of focused work
Pygame is the standard choice for 2D Python games. It's not the fastest framework, but the API is straightforward and you won't waste time fighting with documentation.
Game Mechanics You Must Nail
Before touching code, understand the core systems:
- Vertical scrolling - Camera follows the player upward. Fall below the screen, you die.
- Platform generation - New platforms spawn above as you climb. They must be reachable.
- Physics - Gravity pulls the doodle down. Jump velocity launches it up. No horizontal control mid-air.
- Scoring - Score increases as you climb higher. That's it.
Setting Up Your Project
Create a folder, install pygame, and make a main.py file. That's your entire project structure for now.
pip install pygame
mkdir doodle-jump
cd doodle-jump
touch main.py
The Core Code Structure
You'll need three main components:
- Player class - Handles movement, jumping, rendering
- Platform class - Static or moving platforms
- Game class - Main loop, collision detection, scoring
The Player Class
The doodle needs position, velocity, and jump mechanics. Keep it simple:
class Player:
def __init__(self, x, y):
self.x = x
self.y = y
self.velocity_y = 0
self.width = 50
self.height = 60
self.jump_power = -15
self.gravity = 0.5
def jump(self):
self.velocity_y = self.jump_power
def update(self):
self.velocity_y += self.gravity
self.y += self.velocity_y
The negative velocity makes the player move up. Gravity pulls it back down. This creates the bounce cycle.
The Platform Class
Platforms are rectangles with one job: exist at a y-position and wait for collision.
class Platform:
def __init__(self, x, y, width=80, height=15):
self.x = x
self.y = y
self.width = width
self.height = height
def draw(self, screen):
pygame.draw.rect(screen, (0, 255, 0),
(self.x, self.y, self.width, self.height))
The Game Loop
The game loop runs every frame. It handles input, updates positions, checks collisions, and redraws everything.
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Update player
player.update()
# Check platform collisions (only when falling)
if player.velocity_y > 0:
for platform in platforms:
if player.rect.colliderect(platform.rect):
player.jump()
# Scroll screen when player goes above middle
if player.y < SCREEN_HEIGHT // 2:
player.y = SCREEN_HEIGHT // 2
for platform in platforms:
platform.y += abs(player.velocity_y)
# Generate new platforms
# Remove platforms that fell below screen
pygame.display.update()
clock.tick(60)
Making Platforms Appear Correctly
The tricky part is platform generation. You need random x-positions that are reachable from the previous platform.
def generate_platform(start_y, count=10):
platforms = []
for i in range(count):
x = random.randint(0, SCREEN_WIDTH - 80)
y = start_y - (i * 70) # 70 pixels apart - always jumpable
platforms.append(Platform(x, y))
return platforms
The 70-pixel gap assumes your jump height covers about 200 pixels. Adjust based on your jump power and gravity values.
Handling Player Movement
Left and right movement uses keyboard input. Wrap around screen edges so the player can exit left and appear on right:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= 5
if keys[pygame.K_RIGHT]:
player.x += 5
# Screen wrap
if player.x > SCREEN_WIDTH:
player.x = 0
if player.x < 0:
player.x = SCREEN_WIDTH
Collision Detection That Works
Only trigger a jump when the player is falling and lands on top of a platform. Checking velocity_y > 0 prevents double-jumps and landing on platforms from below.
if player.velocity_y > 0:
player_rect = pygame.Rect(player.x, player.y,
player.width, player.height)
platform_rect = pygame.Rect(platform.x, platform.y,
platform.width, platform.height)
if player_rect.colliderect(platform_rect):
if player.y + player.height - player.velocity_y <= platform.y:
player.jump()
The second condition ensures the player actually hit the platform's top surface, not its side.
Scoring System
Track the highest point the player reached. Display it in the corner:
score = max(score, int((start_y - player.y) / 10))
font = pygame.font.Font(None, 36)
score_text = font.render(f"Score: {score}", True, (255, 255, 255))
screen.blit(score_text, (10, 10))
Higher platforms = higher score. Simple.
Game Over Conditions
The player dies when they fall below the visible screen. Track this:
if player.y > SCREEN_HEIGHT:
game_over = True
Show a game over screen with final score and restart option. That's it.
Library Comparison
| Library | Pros | Cons | Best For |
|---|---|---|---|
| Pygame | Easy API, huge community, good docs | Single-threaded, basic graphics | Learning, prototypes |
| Pyglet | Faster rendering, modern OpenGL | Smaller community, steeper learning curve | Performance-focused games |
| Arcade | Object-oriented, built-in physics | Less flexible, newer library | Quick 2D games |
| Kivy | Touch support, cross-platform mobile | Complex setup, heavy framework | Mobile-first projects |
Stick with Pygame for this project. It's the path of least resistance.
Adding Power-Ups (Optional)
Once the basic game works, add variety:
- Spring platforms - Triple jump height. Draw a small coil on top of the platform.
- Propeller hats - Temporary float upward. Trigger on contact, last 2 seconds.
- Breaking platforms - Collapse after one bounce. Track a "broken" state.
Each power-up needs a collision check and a state modifier on the player object.
Common Problems
- Player falls through platforms - Increase collision check frequency or reduce gravity.
- Platforms spawn too far apart - Reduce the y-spacing in generation.
- Jumps feel floaty - Increase gravity or reduce jump power slightly.
- Performance drops over time - Remove off-screen platforms from the list every few frames.
Getting Started Checklist
- Install Pygame
- Set up window and game loop
- Create Player class with movement
- Create Platform class
- Generate initial platform set
- Implement collision detection
- Add vertical scrolling
- Implement game over condition
- Add scoring
- Test and tune physics values
Work through this list. Get one thing working before moving to the next. The full game takes shape fast once the core loop functions.
Next Steps
Add sprite images instead of rectangles. Create a menu screen. Implement high score persistence with a text file. These are incremental improvements on a working foundation.
The code exists. The mechanics are understood. Ship it.