In the second part of this tutorial to make a platform based on the dafluffypotato work, we will do this:
The video explanation
The initializing and the variables for movements
pygame.init() clock = pygame.time.Clock() pygame.display.set_caption('Game') WINDOW_SIZE = (600, 400) # This will be the Surface where we will blit everything display = pygame.Surface((300, 200)) # Then we will scale (every frame) the display onto the screen screen = pygame.display.set_mode(WINDOW_SIZE, 0, 32) moving_right = False moving_left = False # For the pygame.transform.flip(player_img, 1, 0) stay_right = True momentum = 0 air_timer = 0
The variables holding the map and its tiles
game_map1 = """ <---->xxxx<----xxxx ox<----ooo-------oo o------ooo--------o o--->xxoo-----xxxxo o------ooxxx<-----o oxx<---oo-------xxo o------oo---------o o--->xxooxxxxxxx<-o o------oo---------o oxxxxxxoo-xxxxxxxxo ooooooooo---------- ooooooooooooooooooo """.splitlines() game_map = [list(lst) for lst in game_map1] tl = {} tl["o"] = dirt_img = pygame.image.load('dirt.png') tl["x"] = grass_img = pygame.image.load('grass.png') tl["<"] = grassr = pygame.image.load('grassr.png') tl[">"] = grassr = pygame.image.load('grassl.png')
The player image converted to transparent and its rect object
player_img = pygame.image.load('player.png').convert() player_img.set_colorkey((255, 255, 255)) player_rect = pygame.Rect(100, 100, 5, 13)
This returns a list of the tiles colliding with the player
def collision_test(rect, tiles): "Returns the Rect of the tile with which the player collides" hit_list = [] for tile in tiles: if rect.colliderect(tile): hit_list.append(tile) return hit_list
This returns the player rect and where the collision is (up, left…)
def move(rect, movement, tiles): collision_types = { 'top': False, 'bottom': False, 'right': False, 'left': False} rect.x += movement[0] hit_list = collision_test(rect, tiles) for tile in hit_list: if movement[0] > 0: rect.right = tile.left collision_types['right'] = True elif movement[0] < 0: rect.left = tile.right collision_types['left'] = True rect.y += movement[1] hit_list = collision_test(rect, tiles) for tile in hit_list: if movement[1] > 0: rect.bottom = tile.top collision_types['bottom'] = True elif movement[1] < 0: rect.top = tile.bottom collision_types['top'] = True return rect, collision_types
The while loop that draw the map of tiles
loop = 1 while loop: # CLEAR THE SCREEN display.fill((146, 244, 255)) # Tiles are blitted ========================== tile_rects = [] y = 0 for line_of_symbols in game_map: x = 0 for symbol in line_of_symbols: if symbol in tl: # draw the symbol for image display.blit( tl[symbol], (x * 16, y * 16)) # draw a rectangle for every symbol except for the empty one if symbol != "-": tile_rects.append(pygame.Rect(x * 16, y * 16, 16, 16)) x += 1 y += 1 # ================================================
The movement detection to draw the player (in the while loop)
# MOVEMENT OF THE PLAYER player_movement = [0, 0] if moving_right: player_movement[0] += 2 if moving_left: player_movement[0] -= 2 player_movement[1] += momentum momentum += 0.3 if momentum > 3: momentum = 3 player_rect, collisions = move(player_rect, player_movement, tile_rects) if collisions['bottom']: air_timer = 0 momentum = 0 else: air_timer += 1 # Flip the player image when goes to the left if stay_right: display.blit( player_img, (player_rect.x, player_rect.y)) else: display.blit( pygame.transform.flip(player_img, 1, 0), (player_rect.x, player_rect.y))
The key command to move the player
for event in pygame.event.get(): if event.type == QUIT: loop = 0 if event.type == KEYDOWN: if event.key == K_RIGHT: moving_right = True stay_right = True if event.key == K_LEFT: moving_left = True stay_right = False if event.key == K_SPACE: if air_timer < 6: momentum = -5 if event.type == KEYUP: if event.key == K_RIGHT: moving_right = False if event.key == K_LEFT: moving_left = False
Scaling the display on the screen (and quitting)
screen.blit(pygame.transform.scale(display, (600, 400)), (0, 0)) pygame.display.update() clock.tick(60) pygame.quit()
and now …
The whole code
import pygame import sys from pygame.locals import * pygame.init() clock = pygame.time.Clock() pygame.display.set_caption('Game') WINDOW_SIZE = (600, 400) # This will be the Surface where we will blit everything display = pygame.Surface((300, 200)) # Then we will scale (every frame) the display onto the screen screen = pygame.display.set_mode(WINDOW_SIZE, 0, 32) moving_right = False moving_left = False # For the pygame.transform.flip(player_img, 1, 0) stay_right = True momentum = 0 air_timer = 0 game_map1 = """ <---->xxxx<----xxxx ox<----ooo-------oo o------ooo--------o o--->xxoo-----xxxxo o------ooxxx<-----o oxx<---oo-------xxo o------oo---------o o--->xxooxxxxxxx<-o o------oo---------o oxxxxxxoo-xxxxxxxxo ooooooooo---------- ooooooooooooooooooo """.splitlines() game_map = [list(lst) for lst in game_map1] tl = {} tl["o"] = dirt_img = pygame.image.load('dirt.png') tl["x"] = grass_img = pygame.image.load('grass.png') tl["<"] = grassr = pygame.image.load('grassr.png') tl[">"] = grassr = pygame.image.load('grassl.png') player_img = pygame.image.load('player.png').convert() player_img.set_colorkey((255, 255, 255)) player_rect = pygame.Rect(100, 100, 5, 13) def collision_test(rect, tiles): "Returns the Rect of the tile with which the player collides" hit_list = [] for tile in tiles: if rect.colliderect(tile): hit_list.append(tile) return hit_list def move(rect, movement, tiles): collision_types = { 'top': False, 'bottom': False, 'right': False, 'left': False} rect.x += movement[0] hit_list = collision_test(rect, tiles) for tile in hit_list: if movement[0] > 0: rect.right = tile.left collision_types['right'] = True elif movement[0] < 0: rect.left = tile.right collision_types['left'] = True rect.y += movement[1] hit_list = collision_test(rect, tiles) for tile in hit_list: if movement[1] > 0: rect.bottom = tile.top collision_types['bottom'] = True elif movement[1] < 0: rect.top = tile.bottom collision_types['top'] = True return rect, collision_types loop = 1 while loop: # CLEAR THE SCREEN display.fill((146, 244, 255)) # Tiles are blitted ========================== tile_rects = [] y = 0 for line_of_symbols in game_map: x = 0 for symbol in line_of_symbols: if symbol in tl: # draw the symbol for image display.blit( tl[symbol], (x * 16, y * 16)) # draw a rectangle for every symbol except for the empty one if symbol != "-": tile_rects.append(pygame.Rect(x * 16, y * 16, 16, 16)) x += 1 y += 1 # ================================================ # MOVEMENT OF THE PLAYER player_movement = [0, 0] if moving_right: player_movement[0] += 2 if moving_left: player_movement[0] -= 2 player_movement[1] += momentum momentum += 0.3 if momentum > 3: momentum = 3 player_rect, collisions = move(player_rect, player_movement, tile_rects) if collisions['bottom']: air_timer = 0 momentum = 0 else: air_timer += 1 # Flip the player image when goes to the left if stay_right: display.blit( player_img, (player_rect.x, player_rect.y)) else: display.blit( pygame.transform.flip(player_img, 1, 0), (player_rect.x, player_rect.y)) for event in pygame.event.get(): if event.type == QUIT: loop = 0 if event.type == KEYDOWN: if event.key == K_RIGHT: moving_right = True stay_right = True if event.key == K_LEFT: moving_left = True stay_right = False if event.key == K_SPACE: if air_timer < 6: momentum = -5 if event.type == KEYUP: if event.key == K_RIGHT: moving_right = False if event.key == K_LEFT: moving_left = False screen.blit(pygame.transform.scale(display, (600, 400)), (0, 0)) pygame.display.update() clock.tick(60) pygame.quit()