DEV Community

Cover image for From 2D to 3D: My Journey Building Space Invaders in Python 🚀👾
Zubair Dawd
Zubair Dawd

Posted on

From 2D to 3D: My Journey Building Space Invaders in Python 🚀👾

Why Space Invaders?
Like many developers, I wanted to build something fun while learning Python game development. Space Invaders felt perfect because:

Simple concept - shoot aliens, don't get shot

Classic gameplay everyone recognizes

Scalable complexity - start basic, add features

Great learning project for collision detection and game loops

I was inspired by retro arcade games and wanted to experience both traditional 2D pixel art and modern 3D game development.

The Tools:

For 2D Version:
Pygame Community Edition - The go-to Python game library
Pure Python for sound generation (no external audio files!)
Mathematical sprites - all graphics created with code

For 3D Version:
Ursina Engine - Python 3D game engine built on Panda3D
Procedural 3D models - built from basic cube primitives

3D math for camera positioning and collision detection

2D Approach - Simple and clean

import pygame
pygame.init()
screen = pygame.display.set_mode((1280, 960))

3D Approach - More complex setup

from ursina import *
app = Ursina()
window.size = (1280, 960)

camera.position = (0, 0, -10)

Building the 2D Version: Pixel Perfect Nostalgia 🎮
The Design Philosophy
I wanted authentic NES/SNES vibes with:
Limited color palette (no neon overload)
Clean pixel art sprites
Retro sound effects
Classic arcade feel

Key Features I Implemented:

🎯 Double Bullet System

def shoot(self):
# Fire two bullets simultaneously
bullet1 = Bullet(self.x - 0.2, self.y + 0.3)
bullet2 = Bullet(self.x + 0.2, self.y + 0.3)

self.bullets.extend([bullet1, bullet2])

🎵 Programmatic Sound Effects

Instead of audio files, I generated retro beeps with math:

def create_beep_sound(self, frequency, duration):
sample_rate = 22050
frames = int(duration * sample_rate)
sound_data = []
for i in range(frames):
wave_value = int(4096 * math.sin(frequency * 2 * math.pi * i / sample_rate))
sound_data.extend([wave_value & 0xff, (wave_value >> 8) & 0xff])

return pygame.mixer.Sound(buffer=bytes(sound_data))

🎨 Pixel Art Sprites

All graphics created with simple rectangles and circles:

Player spaceship

pygame.draw.rect(sprite, GREEN, (6, 4, 20, 24)) # Main body
pygame.draw.line(sprite, DARK_GREEN, (8, y), (24, y)) # Server lines

pygame.draw.circle(sprite, RED, (26, y), 1) # LED indicator

What Worked Great:
✅ Clean, readable code
✅ Smooth 60fps gameplay
✅ Authentic retro feel
✅ Easy to debug and modify

Image description

Why I Wanted 3D
The 2D version was working great, but I thought: "How hard could 3D be?"

🖥️ Window Size Issues

This should be simple, right? WRONG!

window.size = (1024, 768) # Tiny window
window.size = (1280, 960) # Better, but camera issues

The window would either be microscopic or show nothing at all.
📷 Camera Positioning problems

Tried everything:

camera.position = (0, 0, -5) # Too close
camera.position = (0, 0, -15) # Too far
camera.position = (0, 0, -10) # Finally worked!
camera.fov = 70 # After hours of tweaking

💥 Collision Detection Disasters
The worst part! Bullets would pass right through aliens:

This didn't work:

if distance(bullet.position, alien.position) < 0.8:
# Never triggered!

Had to use simple box collision:

if (abs(bullet.x - alien.x) < 0.5 and
abs(bullet.y - alien.y) < 0.5):
# Finally worked!

👾 Overlapping Alien Models
The aliens were mashed together:

Too big and too close:

x = -5 + col * 0.9 # Overlapping mess

Fixed with proper spacing:

x = -5 + col * 1.0 # Much better!

Image description

What I Learned the Hard Way:
🔴 3D collision detection is HARD
🔴 Camera positioning is an art form
🔴 3D debugging takes 10x longer
🔴 Simple 2D > Complex 3D for learning

Key Lessons Learned 🎓
For Beginner Game Developers:
✅ Start Simple, Stay Simple
Master 2D before attempting 3D
Get one feature working perfectly before adding more
Simple graphics > complex broken visuals

✅ Version Control is Your Friend
Commit working versions frequently
Use descriptive commit messages
Don't be afraid to create new repositories

What I'd Do Differently:
Start with collision detection research
Plan the 3D camera system before coding
Test on different screen sizes early
Focus on gameplay over graphics initially

The Final Verdict: 2D Wins! 🏆
While the 3D version was a valuable learning experience, the 2D version is simply more fun to play. It's:
Responsive and smooth
Visually clear and readable
Easy to modify and extend
Genuinely enjoyable to play

Top comments (0)