Fading Coder

An Old Coder’s Final Dance

Home > Tech > Content

Building an Alien Invasion Game with Pygame: Window, Loop, and Player Ship

Tech 1

This guide walks through the first steps of a simple 2D game using Pygame: creating a window, handling events, and drawing a player spaceship on the screen.

Setup

Install Pygame with pip:

pip install pygame

If pip is outdated, upgrade it:

pip install --upgrade pip

Create a new project directory (for example, alien_invasion/) and an images/ subfolder. Place a ship image at images/ship.bmp.

Using Git for version control is recommended.

Pygame building blocks used here

  • pygame.init()
    • Initializes Pygame modules and must be called before using most Pygame APIs.
  • pygame.display.set_mode((width, height))
    • Creates the main window and returns a Surface representing the screen.
  • pygame.display.set_caption(title)
    • Sets the window title.
  • Surface.fill(color, rect=None)
    • Fills the entire surface or an optional rectangular area with a color. Colors are RGB tuples like (255, 0, 0).
  • pygame.display.flip() or pygame.display.update()
    • Updates the screen with whatever you’ve drawn since the last flip/udpate.
  • pygame.event.get()
    • Retrieves a list of pending events (keyboard, mouse, window events, etc.).
  • pygame.QUIT
    • Event fired when the window is closed.
  • sys.exit()
    • Terminates the program (typically after pygame.quit()).
  • pygame.image.load(path)
    • Loads an image file as a Surface. BMP is universally supported; PNG works well in most setups.
  • Surface.get_rect()
    • Produces a Rect that describes the surface’s size and position. Rect supports attributes like center, centerx, centery, top, bottom, left, right, midtop, midbottom, etc., as well as x and y for the top-left corner. Rect coordinates are integers. The origin (0, 0) is the top-left of the screen and incresaes to the right and downward.
  • Surface.blit(image_surface, dest_rect)
    • Draws one surface onto another at the position determined by dest_rect.

Project structure

  • settings.py – basic configuration like screen dimensions and background color
  • ship.py – player ship sprite and placement logic
  • alien_invasion.py – game bootstrap (window, loop, eveent processing, drawing)

settings.py

Define a compact configuration object for screen size and background color.

# settings.py

class GameSettings:
    """Holds configuration for the game window and visuals."""

    def __init__(self) -> None:
        # Window configuration
        self.width: int = 1200
        self.height: int = 800

        # Background color (light gray)
        self.bg_color: tuple[int, int, int] = (230, 230, 230)

ship.py

Load and position a spaceship image. We’ll center it along the bottom edge of the screen.

# ship.py

import pygame


class PlayerShip:
    """Manage the player-controlled ship's image and placement."""

    def __init__(self, screen: pygame.Surface) -> None:
        self.screen = screen
        self.screen_rect = self.screen.get_rect()

        # Load the ship image and compute its rect
        # .convert() speeds up blits for opaque images; use .convert_alpha() for images with transparency
        self.image = pygame.image.load("images/ship.bmp").convert()
        self.rect = self.image.get_rect()

        # Place the ship centered at the bottom of the screen
        self.rect.midbottom = self.screen_rect.midbottom
        # Optionally lift it a bit above the edge
        self.rect.y -= 10

    def render(self) -> None:
        """Draw the ship at its current location."""
        self.screen.blit(self.image, self.rect)

alien_invasion.py

Initialize Pygame, create the window, handle the event loop, and draw the background and ship.

# alien_invasion.py

import sys
import pygame

from settings import GameSettings
from ship import PlayerShip


class AlienDefense:
    """Initialize core game objects and run the main loop."""

    def __init__(self) -> None:
        pygame.init()

        self.settings = GameSettings()
        self.screen = pygame.display.set_mode(
            (self.settings.width, self.settings.height)
        )
        pygame.display.set_caption("Alien Invasion")

        # Cap the frame rate for consistent behavior
        self.clock = pygame.time.Clock()

        # Game entities
        self.ship = PlayerShip(self.screen)

    def run(self) -> None:
        while True:
            self._handle_events()
            self._draw_frame()
            # Limit to ~60 frames per second
            self.clock.tick(60)

    def _handle_events(self) -> None:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

    def _draw_frame(self) -> None:
        # Clear the screen
        self.screen.fill(self.settings.bg_color)

        # Draw entities
        self.ship.render()

        # Present the frame
        pygame.display.flip()


if __name__ == "__main__":
    game = AlienDefense()
    game.run()

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.