# 3D Starfield made using Python and Pygame

In this tutorial I will show you how to create a pretty cool 3D Starfield simulation using Python and Pygame. See in the video below a demonstration of the simulation.

NOTE: In previous tutorials, I have demonstrated how to create a Simple Starfield as well as how to create a Parallax Starfield.

## The Code

To simulate the effect of a 3D starfield, we initially create a list of stars that are randomly positioned in the world. Each star is represented as a 3D coordinate, I mean, for each star we just store its X,Y and Z coordinates. Then we start the animation loop where we decrease the star’s Z coordinates on each frame. Decreasing the Z coordinate of a star makes it appear to be approaching the screen. When a star disappears from the screen, we reposition it again in the screen giving it random X and Y coordinates, and setting Z = maximum depth.

To make it even more interesting, we make closer stars bigger than distant stars. Similarly, we make closer stars brighter than the distant ones.

Since the stars are represented as 3D coordinates, they must be converted to 2D before being drawn into the screen. The code does that  using perspective projection formulas.

The code is presented below. As you can see, the simulation is made with very few lines of code. If you have any doubt or suggestion, please don’t hesitate to leave a comment.

```"""
3D Starfield Simulation
Developed by Leonel Machava <[email protected]>

http://codeNtronix.com

"""
import pygame, math
from random import randrange

class Simulation:
def __init__(self, num_stars, max_depth):
pygame.init()

self.screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("3D Starfield Simulation (visit codeNtronix.com)")

self.clock = pygame.time.Clock()
self.num_stars = num_stars
self.max_depth = max_depth

self.init_stars()

def init_stars(self):
""" Create the starfield """
self.stars = []
for i in range(self.num_stars):
# A star is represented as a list with this format: [X,Y,Z]
star = [randrange(-25,25), randrange(-25,25), randrange(1, self.max_depth)]
self.stars.append(star)

def move_and_draw_stars(self):
""" Move and draw the stars """
origin_x = self.screen.get_width() / 2
origin_y = self.screen.get_height() / 2

for star in self.stars:
# The Z component is decreased on each frame.
star -= 0.19

# If the star has past the screen (I mean Z<=0) then we
# reposition it far away from the screen (Z=max_depth)
# with random X and Y coordinates.
if star <= 0:
star = randrange(-25,25)
star = randrange(-25,25)
star = self.max_depth

# Convert the 3D coordinates to 2D using perspective projection.
k = 128.0 / star
x = int(star * k + origin_x)
y = int(star * k + origin_y)

# Draw the star (if it is visible in the screen).
# We calculate the size such that distant stars are smaller than
# closer stars. Similarly, we make sure that distant stars are
# darker than closer stars. This is done using Linear Interpolation.
if 0 <= x < self.screen.get_width() and 0 <= y < self.screen.get_height():
size = (1 - float(star) / self.max_depth) * 5
shade = (1 - float(star) / self.max_depth) * 255

def run(self):
""" Main Loop """
while 1:
# Lock the framerate at 50 FPS.
self.clock.tick(50)

# Handle events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return

self.screen.fill((0,0,0))
self.move_and_draw_stars()
pygame.display.flip()

if __name__ == "__main__":
Simulation(512, 32).run()
```

If you liked this article, please consider leaving a comment, or sharing this post using one of the buttons below, or even subscribing to the blog.

1. Fabyola

waaaa, this reminds me of the old windows screensaver x3
good old times… when i didnt knew nothing about programming xD

• lefam 2. aroy

Nice, thx for the code

• lefam

Thank you!

3. Joseph

Yes! thanks! just what I needed for a project I’m working on! But I noticed that you don’t actually use any math, and it works fine without importing it… but still, this code is great!!

• lefam

I applied basic 3D math to develop this demo. It wasn’t needed to import any math library since the math functions I used are available by default.

4. Will

Omg, these tutorials are so helpful!

5. AlfredoKreb

There is tricky method i found on the internet.
If you want to learn it too, simply type in google: Irahsik’s betting system

6. anon

pretty nifty!

7. computer bild spiele ausgabe 9/2017

Enhanced discount computers tzaneen Allowing Yoou To Dominate Thhe discount computers tzaneen Industry

8. ElektroKill

I am trying to make something like this in c#, can you help me ?

9. bitutainers

whoah this weblog is magnificent i really like studying your articles.
Keep up the great work! You know, many individuals are looking around for this info, you
could aid them greatly.