Friday, 27 July 2012

Simple Starfield In PyGame

Games are very often highly interactive with even some text adventures operating in real time. I thought it would be fun to go in the opposite direction and create a game with minimal interaction. So I settled on an outer space theme and had a text experiment of a probe travelling through the emptiness of space.

The next step was to create a graphical display and, of course, stars were the first order of business! I looked around at a few star field examples and ended up coding one for myself. Straightforward 2D scrolling is all I want - needs to be calm for the display. The class is nice and simple whilst the demo shows it off fairly well.

Exercise for the reader - can you make a layered demo? I'll share the code on a follow up post. Happy stargazing!

import random
import pygame
import sys
from pygame.locals import *

class starfield(object):
    def __init__(self, pos , size, max, speed):
        self.stars = []
        self.pos = pos
        self.size = size
        self.max = max
        self.speed = speed = True
        self.color = (255,255,255)
        self.bordercolor = Color(255,255,255)
        self.backgroundcolor = Color(0,0,0)
        for loop in range(0, max):
            star = [random.randrange(0, size[0] - 1),
                    random.randrange(0, size[1] - 1)]
    def draw(self, screen):
             pygame.draw.rect(screen, self.backgroundcolor, Rect(self.pos[0], self.pos[1], self.size[0],self.size[1]), 0)
             pygame.draw.rect(screen, self.bordercolor, Rect(self.pos[0], self.pos[1], self.size[0],self.size[1]), 1)
        for loop in range(0, self.max):
            p = (self.pos[0] + self.stars[loop][0], self.pos[1] + self.stars[loop][1] )
            screen.set_at(p, self.color)
    def update(self):
        for loop in range(0, self.max):
            self.stars[loop] = (self.stars[loop][0] + self.speed, self.stars[loop][1])
            if self.stars[loop][0]>self.size[0]:
                self.stars[loop] = (0, self.stars[loop][1])

sf = [starfield( (50,50), (550,410), 80, 1 ),
      starfield( (80,150), (200,200), 33, 2 ),
      starfield( (380,150), (200,200), 33, 3 ),
      starfield( (5,5), (80,80), 12, 4 )

sf[1].color = (255,0,0)
sf[2].color = (0,255,0)
sf[3].color = (0,0,255)

FPS = 50
window = pygame.display.set_mode((640, 480))

background = None
background = pygame.Surface(window.get_size())
background.fill((0, 0, 0))

pygame.time.set_timer(TIMEREVENT, int(1000 / FPS))
pygame.time.set_timer(UPDATEEVENT, 50)

while True:

    for event in pygame.event.get():
        if event.type == TIMEREVENT:
            for s in sf:
            window.blit(background, (0, 0))
        elif event.type == UPDATEEVENT:
            for s in sf:
            # Move starfield
            x = sf[3].pos[0] + 2
            y = sf[3].pos[1] + 2
            if x>640: x=-50
            if y>480: y=-40
            sf[3].pos = (x,y)

        elif event.type == pygame.QUIT:


  1. i dont think python is made to games :| it is a really great language but games "real games" need a lot of memory so i guess C++ is a better option.

    1. It's a decent language for a lot of indy games, or as a scripting or data language for a game with an engine written in something faster.

      Also, pyglet runs on pypy, which is making a lot of progress.

    2. True - C++ has its merits for some api's and raw speed. Python has speed + ease of development on its side. With advances in hardware and compiler technology - the gap is only going to get closer.

      Depends on the meaning of 'real games' too. Pyweek and PyGame sites all have some great games on it.

  2. EVE online is the best example of Python used for serious gaming.
    Rule of thumb: script all logic in Python, write in C the CPU intensive code and redering routines.