Skip to content

1. Making the level

laymooiety edited this page Mar 16, 2024 · 20 revisions

1. Making the level

1.0 - Prerequisites

  • Intermediate knowledge of Python
  • Pygame installed on your system (pip install pygame)
  • Basic understanding of Pygame's Sprite and Group classes

1.1 - Project Setup

First, start by creating a folder with any name of your choice where you will store all your code from this workshop.

Second, click here and paste https://github.com/HackMelbourne/Platformer_Game_DeCoded/tree/main/graphics to download the graphic resources of the game.

Then, unzip the file and name it as "graphics".

1.2 - Environment Setup

In this section, you will be able to build a basic map with tiles.

Within this main folder, create a subfolder named "code". Inside the "code" folder, create files:

  • level.py: Manages the game levels, including setting up the level layout with tiles.
  • main.py: Contains the main game loop, initializes the game, and handles events.
  • tiles.py: Defines the Tile class for creating tile sprites.
  • settings.py: Stores game settings, level layouts, and paths to graphic assets.

1.2.0 Create Game Settings

Define Game Settings in settings.py: Includes screen dimensions, tile size, game maps, and paths to graphic resources.

from os import walk, path
import pygame

initial_level_map = [
'                                                        ',
'                                                        ',
'                                                        ',
'       TTT        TTT TT           TTT        TTT TT    ',
'                T                         T             ',
'              TT       TTTT               XT       TTTT ',
'            TT  TT         T            TT  TT         T',
'          TTXX      TTT    X          TTXX      TTT    X',
'          XXXX        XT   X          XXXX        XT   X',
'    TTTT  XXXXTT  TT  XXTTTX    TTTT  XXXXTT  TT  XXTTTX',
'TTTTXXXXTTXXXXXXTTXXTTXXXXXXTTTTXXXXTTXXXXXXTTXXTTXXXXXX'
]

player_level_map = [
'                                                        ',
'                                                        ',
'                                                        ',
'       TTT        TTT TT           TTT        TTT TT    ',
'    P           T                         T             ',
'              TT       TTTT               XT       TTTT ',
'            TT  TT         T            TT  TT         T',
'          TTXX      TTT    X          TTXX      TTT    X',
'          XXXX        XT   X          XXXX        XT   X',
'    TTTT  XXXXTT  TT  XXTTTX    TTTT  XXXXTT  TT  XXTTTX',
'TTTTXXXXTTXXXXXXTTXXTTXXXXXXTTTTXXXXTTXXXXXXTTXXTTXXXXXX'
]

base_path = path.join(path.dirname(__file__), '..', 'graphics')

tile_types = {
    'T': path.join(base_path, 'Tiles', 'grassMid.png'),
    'X': path.join(base_path, 'Tiles', 'grassCenter.png'),
    'C': path.join(base_path, 'Tiles', 'castleMid.png'),
    'M': path.join(base_path, 'Tiles', 'castleCenter.png'),
}

tile_size = 64
clock_tick = 1000
screen_width = 1200
screen_height = len(initial_level_map) * tile_size

1.2.1 Implement the Tile Class

Create tiles.py: Define the Tile class that inherits from pygame.sprite.Sprite. This class will load the tile image, scale it to the desired size, and set its position.

import pygame
from settings import tile_types

class Tile(pygame.sprite.Sprite):
    def __init__(self, pos, size, tile_type):
        super().__init__()
        self.image = pygame.Surface((size, size))
        sprite_surface = pygame.image.load(tile_types[tile_type])
        sprite_surface = pygame.transform.smoothscale(sprite_surface, (size, size))
        self.image.blit(sprite_surface, (0, 0))
        self.rect = self.image.get_rect(topleft=pos)

    def update(self, x_shift):
        self.rect.x += x_shift

1.2.2 Implement the Level Class

Create level.py: This file should contain the Level class, responsible for setting up the level by placing tiles according to the level map provided.

Setup Level Method: In the Level class, implement the setup_level method to iterate through the level map and create tile sprites for non-empty cells.

import pygame
from tiles import Tile
from settings import *

class Level:
    def __init__(self, level_data, surface):
        # Level setup
        self.display_surface = surface
        self.setup_level(level_data)
        self.world_shift = 0

    def setup_level(self, layout):
        self.tiles = pygame.sprite.Group()
        for row_index, row in enumerate(layout):
            for col_index, cell in enumerate(row):
                x = col_index * tile_size
                y = row_index * tile_size

                if cell != ' ':
                    tile_sprite = Tile((x, y), tile_size, cell)
                    self.tiles.add(tile_sprite)

    def run(self):
        # Level tiles
        self.tiles.update(self.world_shift)
        self.tiles.draw(self.display_surface)

1.2.3 The Main Game File

Create main.py: Initialize Pygame, create a game window, and set up the main game loop.

Game Loop: In the loop, handle events (like closing the game), update game elements, draw the background, and update the display.

import pygame, sys
from settings import *
from tiles import Tile
from level import Level
# from button import Button
from os import path

# Pygame setup
pygame.init()
screen = pygame.display.set_mode((screen_width,screen_height))
clock = pygame.time.Clock()
pygame.display.set_caption("2D Platformer Game")

# in this case we run the intial map first
level = Level(initial_level_map, screen)


while True:
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			pygame.quit()
			sys.exit()

    # background setup
	background = pygame.image.load(path.join(base_path, 'bg.png')).convert()
	background = pygame.transform.smoothscale(background, screen.get_size())
	screen.blit(background, (0, 0))

    # run level
	level.run()

	pygame.display.update()
	clock.tick(clock_tick)

1.2.4 Running Your Game

Run main.py to start your game. You should see the game window with the level drawn according to the intial_level_map defined in settings.py.

Clone this wiki locally