Map Maker 1.2

In this version of the pygame app to create maps for a platform game, we can see the player in action into the map, while we build it like you can see in this video:

Code of Climber map maker 1.2

These images go in the folder imgs

Thes are the audio files that go in data\audio\

This music was made by me.

dawn.wav

grass_0.wav

jump.wav

from pygame.locals import *
import pygame
from time import sleep
from tkinter import messagebox
from tkinter import Tk

map0 ="""                             
                            
wssss  sss   sss  ss   ss  sw
w                           w
w                           w
w    wwwwww    sssss      www
www    w                  s w
w      w          w         w
w   wwwww     ssssw  ww  wwww
w      wwwwww     w     w   w
w    w      s   www  wwww   w
w      w          w     w   w
w   wwwwwwwwwwwww w     w   w
w      w          wwwwwww   w
w                           w
wwwwwwwwwwwwwwwwwwwwwwwwwwwww"""
start = "w"*29
map1 = "w" + " " * 27 + "w\n"
map1 = start + map1 * 15 + start
map2 = """w                          w
w                          w
w       ssswwwss     sssss w
wwsss      w w             w
ww         www   ss        w
ww         w w             w
ww ssss    www         sss w
ww         wwwsss          w
ww         w w           w w
ww         www     ws   sw w
ww         w w     w     s w
w   ssswsssssssss w        w
w      s          ssssss   w
w                          w
wwwwwwwwwwwwwwwwwwwwwwwwwwww"""

def map_to_list(map1=map1):
    if map1 == "":
        start = "w"*29
        map1 = "w" + " " * 27 + "w\n"
        map1 = start + map1 * 14 + start
    map1 = map1.splitlines()
    map2 = []
    for n, line in enumerate(map1):
        map2.append(list(map1[n]))
    return map2

map1 = map_to_list(map1)

def screen_init():
    "Creates globals for screen and map"
    global game_map, WINDOW_SIZE
    game_map = map1
    WINDOW_SIZE = (29 * 32, 16 * 32)


def music_init():
    "Initialize sounds avoiding delay"
    pygame.mixer.pre_init(44100, -16, 1, 512)
    pygame.init()
    pygame.mixer.quit()
    pygame.mixer.init(22050, -16, 2, 512)
    pygame.mixer.set_num_channels(32)


def game_sounds():
    "Loads the sounds for the game"
    sounds_list = "jump", "grass_0"
    sound_dic = {}
    for sound in sounds_list:
        sound_path = f"data/audio/{sound}.wav"
        sound_dic[sound] = pygame.mixer.Sound(sound_path)
    return sound_dic


def soundtrack():
    "Call this to put a soundtrack in the game"
    pygame.mixer.music.load('data/audio/dawn.mp3')
    pygame.mixer.music.play(-1)

screen_init()
music_init()
soundtrack()
sound_dic = game_sounds()


# ======== Game init, Clock and global vars ===
pygame.display.set_caption('Game')
screen = pygame.display.set_mode(WINDOW_SIZE, 0, 32)
display = pygame.Surface((WINDOW_SIZE[0] // 2, WINDOW_SIZE[1] // 2))
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)
font2 = pygame.font.Font(None, 16)
font3 = pygame.font.SysFont("Arial", 10)
# awareness of direction and position
moving_right = False
moving_left = False
# stay_right = True
gravity = 0
air_timer = 0

player_image = pygame.image.load('imgs\\player.png')
player_jump = pygame.image.load('imgs\\player_jump.png')
player_jumpl = pygame.transform.flip(player_jump, 1, 0)
player_climb = pygame.image.load('imgs\\player_climb.png')
player_climbl = pygame.transform.flip(player_climb, 1, 0)
player_stand = pygame.image.load('imgs\\player_stand.png')
# player_img.set_colorkey((255, 255, 255))
p_right = player_image
p_left = pygame.transform.flip(player_image, 1, 0)
player_img = p_right
bg = pygame.image.load("imgs\\bg.png")
# bg2 = pygame.image.load("imgs\\bg2.png")

# Rectangles for collisions
player_rect = pygame.Rect(100, 100, 5, 13)
starting_pos = 100
health = pygame.image.load("imgs\\health.png")
health_rect = pygame.Rect(150, 225, 16, 16)

# climber 5
stamina = 100


def load_tiles():
    #symbols and relative image
    symb_img = [
                # ("o", "dirt"),
                # ("x", "grass"),
                # ("<", "grassr"),
                # (">", "grassl"),
                (" ", "space"),
                # ("d", "door"),
                ("w", "brick2_16"),
                ("s", "brick2_16")]
    dr = "imgs\\"
    tl = {}
    for i in symb_img:
        tl[i[0]] = pygame.image.load(f'{dr}{i[1]}.png')
    return tl


tl = load_tiles()


# =============
#    Functions
# =============

def collision_test(rect, tiles):
    "Returns the Rect of the tile with which the player collides"
    global stamina

    hit_list = []
    for tile in tiles:
        if rect.colliderect(tile):
            hit_list.append(tile)
    if rect.colliderect(health_rect):
        if stamina < 100:
            stamina += 10
            print("Recovering")
    return hit_list

collision_types = {
        'top': False, 'bottom': False, 'right': False, 'left': False}
goingright = 0


def move(rect, movement, tiles):
    global player_img
    global air_timer, gravity, collision_types, moving_right, moving_left
    global goingright
    global stamina
    global player_altitude
    global starting_pos


    player_altitude = player_rect.y
    collision_types = {
        'top': False, 'bottom': False, 'right': False, 'left': False}

    rect.x += movement[0]
    tile = collision_test(rect, tiles)
    if tile != []:
        tile = tile[0]
        # ===================> MOVE RIGHT
        if moving_right:
            rect.right = tile.left
            collision_types['right'] = True
            goingright = 1
            gravity = -1
            player_img = player_climb
            stamina -= 0.02
            starting_pos = rect.y
        # ====================> MOVE LEFT
        elif moving_left:
            goingright = 0
            rect.left = tile.right
            collision_types['left'] = True
            gravity = -1
            player_img = player_climbl
            stamina -=0.02
            starting_pos = rect.y
    rect.y += movement[1]
    hit_list = collision_test(rect, tiles)
    for tile in hit_list:

        #              === DOWN: falls? ===

        if movement[1] > 0:
            # If it was falling down
            if not moving_left and not moving_right and gravity > 0:
                player_img = player_stand
            if (rect.bottom - starting_pos) > 50:
                stamina -= 30
                pygame.mixer.Sound.play(sound_dic['grass_0'])
                player_img = player_jump
                

            starting_pos = rect.bottom
            rect.bottom = tile.top
            collision_types['bottom'] = True
        elif movement[1] < 0:
            player_img = player_jump
            gravity = -3 # = -1 it attaches to the wall
            attached = rect.top = tile.bottom
            stamina -= 0.03
            #collision_types['top'] = False

    if collision_types['bottom']:
        air_timer = 0
        gravity = 0

    else:
        air_timer += 1
    return rect


def display_tiles():
    "Makes the Rects for the 'physics'"
    tile_rects = []
    y = 0
    for line_of_symbols in game_map:
        x = 0
        for symbol in line_of_symbols:
            display.blit(tl[symbol], (x * 16, y* 16))
            x += 1
        y += 1

def create_tile_rects(game_map):
    "Makes the Rects for the 'physics'"
    tile_rects = []
    y = 0
    for line_of_symbols in game_map:
        x = 0
        for symbol in line_of_symbols:
            if symbol != " ":
                tile_rects.append(pygame.Rect(x * 16, y * 16, 16, 15))
            x += 1
        y += 1
    return tile_rects





player_altitude = player_rect.y
def display_player(pim):
    global player_rect
    global starting_pos
    #player_img = p_right if stay_right else p_left
    display.blit(health, (150, 225))
    display.blit(pim, (player_rect.x, player_rect.y))
    h = str(player_rect.bottom - starting_pos) 
    highness = font3.render(h, 0, pygame.Color("blue"))
    display.blit(highness, (player_rect.x, player_rect.y-10))

# 500, 500, 50, 50
def display_stamina():
    #player_img = p_right if stay_right else p_left
    print("health")

def display_bg():
    "Displays the background"
    global WINDOW_SIZE
    display.blit(bg, (0, 0))


def _display(fnt, what, color, where):
    text_to_show = font.render(what, 0, pygame.Color(color))
    display.blit(text_to_show, where)

def display_text():
    # fps

    _display(
            font,
            what = str(int(clock.get_fps())),
            color = "white",
            where = (0,0)),
    
    _display(font2,
            what = "Wall climber",
            color = 'blue',
            where = (100,0))

    _display(font3,
            what = "Stamina: " + str(int(stamina)),
            color = 'coral',
            where = (300,0))


    _display(font3,
            what = "altitude: " + str(int(player_altitude)),
            color = 'blue',
            where = (300, 15))


def clear_screen():
    display.fill((73, 184, 250))


VELOCITY = 1

def jump():
    # MOVES THE PLAYER WHEN GOES RIGHT OR LEFT
    global moving_right, moving_left, gravity, stamina

    player_movement = [0, 0]
    if moving_right:
        player_movement[0] += VELOCITY
        stamina += 0.005
    if moving_left:
        player_movement[0] -= VELOCITY
        stamina += 0.005
    player_movement[1] += gravity
    return player_movement


def check_life():
    global stamina, player_rect
    if stamina < 0:
        player_rect.x, player_rect.y = 100, 100
        stamina = 100
        root = Tk()
        root.overrideredirect(1)
        root.withdraw()
        messagebox.showinfo("Showinfo", "So many windows!")
        root.destroy()



def move_player():
    global loop, player_rect, moving_right, air_timer, moving_left, gravity, collision_types, player_img, stamina
    global tile_rects
    check_life()
    player_movement = jump()

    gravity += 0.3
    if gravity > 3:
        gravity = 3

    player_rect = move(player_rect, player_movement, tile_rects)

    # ============ Keyboard pressing detection
    for event in pygame.event.get():
        if event.type == QUIT:
            loop = 0
        if event.type == KEYDOWN:
            if event.key == K_RIGHT:
                player_img = p_right
                moving_right = True
            if event.key == K_LEFT:
                player_img = p_left
                moving_left = True
            # ========
            #  JUMP
            # ========
            if event.key == K_UP:
                if air_timer < 6:
                    gravity = -5
                    stamina -= 3
                    pygame.mixer.Sound.play(sound_dic['jump'])
            # ==========
            #  DOWN
            # ==========
            if event.key == K_DOWN:
                if air_timer == 0:
                    player_img = player_jump
                gravity = +1


        elif event.type == KEYUP:
            if event.key == K_RIGHT:
                moving_right = False
            if event.key == K_LEFT:
                moving_left = False

        if pygame.mouse.get_pressed()[0]:
            mx, my = pygame.mouse.get_pos()
            mx, my = int(mx / 32), int(my / 32)
            row, col = my, mx            
            map1[row][col] = "w"
            tile_rects = create_tile_rects(map1)
        if pygame.mouse.get_pressed()[2]:
            mx, my = pygame.mouse.get_pos()
            mx, my = int(mx / 32), int(my / 32)
            row, col = my, mx 
            map1[row][col] = " "
            tile_rects = create_tile_rects(map1)

    return player_img


def scale_screen():
    screen.blit(pygame.transform.scale(display, WINDOW_SIZE), (0, 0))
    
tile_rects = create_tile_rects(map1)
loop = 1
while loop:
    stamina -= 0.001
    clear_screen()
    display_tiles()
    player_img = move_player()
    display_player(player_img)
    display_text()
    scale_screen()
    pygame.display.update()
    clock.tick(60)

pygame.quit()
print("Game over")
"""
------- new in pygame: The climber tutorial 5 -----------
diplay_text
    shows fps, title and stamina

"""

Another video with some experiments on the map maker app

Pygame's Platform Game

Other Pygame's posts

Advertisement