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.
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