[Python] Level help pygame platformer [closed]

Discussão em 'Python' iniciado por Stack, Março 28, 2025.

  1. Stack

    Stack Membro Participativo

    I'm currently making a 2D platformer in pygame for a software engineering assignment.

    I have used Tiled to make 2 levels so far and have them in a list of lists as you will see below. I used a function to iterate through the lists and make the map.

    I can't figure pit how to move to the next level. I have a portal class which i want to collide with to move to the next level. I have tried many things to achieve this but I cant figure it out.

    import pygame
    from pygame.locals import *

    pygame.init()

    clock = pygame.time.Clock()
    fps = 120

    screen_width = 1000
    screen_height = 600

    screen = pygame.display.set_mode((screen_width, screen_height))
    pygame.display.set_caption("Chicken Run")

    tile_size = 50
    game_over = 0
    main_menu = True
    level = 0
    max_level = 1


    #images
    bg_img = pygame.image.load('img/sky.png')
    startbg_img = pygame.image.load('img/start.png')

    restart_img = pygame.image.load('img/restart.png')
    restart_img = pygame.transform.scale(restart_img, (100,50))

    hover_img = pygame.image.load('img/hover.png')
    hover_img = pygame.transform.scale(hover_img, (100,50))

    start_img = pygame.image.load('img/play.png')
    start_img = pygame.transform.scale(start_img, (100,50))

    exit_img = pygame.image.load('img/back.png')
    exit_img = pygame.transform.scale(exit_img, (100,50))

    next_img = pygame.image.load('img/next.png')
    next_img = pygame.transform.scale(next_img, (100,50))


    class Button():
    def __init__(self, x, y, image):
    self.image = image
    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = y
    self.clicked = False

    def draw(self):
    action = False

    pos = pygame.mouse.get_pos()

    if self.rect.collidepoint(pos):

    if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
    action = True
    self.clicked = True

    if pygame.mouse.get_pressed()[0] == 0:
    self.clicked = False




    #draw button
    screen.blit(self.image, self.rect)
    return action

    class player():
    def __init__(self,x,y):
    self.reset(x,y)


    def update(self,game_over):
    #check for key presses
    dx = 0
    dy = 0

    walk_cooldown = 4

    if game_over == 0:
    key = pygame.key.get_pressed()
    if key[pygame.K_SPACE] and self.jumped == False:
    self.vel_y = -14
    self.jumped = True
    #Eif key[pygame.K_SPACE] == False:
    #self.jumped = False

    if key[pygame.K_LEFT]:
    dx -= 3
    self.counter += 1
    self.direction = -1
    if key[pygame.K_RIGHT]:
    dx += 3
    self.counter += 1
    self.direction = 1
    if key[pygame.K_LEFT] == False and key[pygame.K_RIGHT] == False:
    self.counter = 0
    self.index = 0
    if self.direction == 1:
    self.image = self.images_right[self.index]
    if self.direction == -1:
    self.image = self.images_left[self.index]

    #animations
    if self.counter > walk_cooldown:
    self.counter = 0
    self.index += 1
    if self.index >= len(self.images_right):
    self.index = 0
    if self.direction == 1:
    self.image = self.images_right[self.index]
    if self.direction == -1:
    self.image = self.images_left[self.index]

    #gravity
    self.vel_y += 1.
    if self.vel_y >7:
    self.vel_y = 7
    dy += self.vel_y

    #check collision
    for tile in map.tile_list:
    if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
    dx = 0


    if tile[1].colliderect(self.rect.x,self.rect.y + dy,self.width, self.height+1):
    if self.vel_y < 0:
    dy= tile[1].bottom - self.rect.top
    self.vel_y = 0

    elif self.vel_y >= 0:
    dy= tile[1].top- self.rect.bottom
    self.vel_y = 0
    self.jumped = False


    if pygame.sprite.spritecollide(self, lava_group, False):
    game_over = -1







    self.rect.x += dx
    self.rect.y += dy

    if self.rect.bottom>screen_height:
    self.rect.bottom = screen_height
    dy = 0


    elif game_over == -1:
    self.image = self.dead_img
    self.rect.y -= 5


    screen.blit(self.image, self.rect)


    #pygame.draw.rect(screen,(255,255,255),self.rect,2)
    return game_over

    def reset(self,x,y):
    self.direction = 0
    self.images_right = []
    self.images_left = []
    self.index = 0
    self.counter = 0
    for num in range(0,3):
    img_right = pygame.image.load(f'img/right walk/pixil-frame-{num}.png')
    img_right = pygame.transform.scale(img_right, (40,40))
    img_left = pygame.transform.flip(img_right, True, False)
    self.images_right.append(img_right)
    self.images_left.append(img_left)



    img = pygame.image.load('img/chicken.png')
    self.dead_img = pygame.image.load('img/dead.png')
    self.image = self.images_right[self.index]

    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = y
    self.width = self.image.get_width()
    self.height = self.image.get_height()
    self.vel_y = 0
    self.jumped = False





    class map():
    def __init__(self, data):
    self.tile_list = []

    #load images
    dirt_img = pygame.image.load('img/dirt.png')
    grass_img = pygame.image.load('img/grass.png')


    #interpret map
    row_count = 0
    for row in data:
    col_count = 0
    for tile in row:
    if tile == 1:
    img = pygame.transform.scale(grass_img, (tile_size, tile_size))
    img_rect = img.get_rect()
    img_rect.x = col_count * tile_size
    img_rect.y = row_count * tile_size
    tile = (img, img_rect)
    self.tile_list.append(tile)
    if tile == 2:
    img = pygame.transform.scale(dirt_img, (tile_size, tile_size))
    img_rect = img.get_rect()
    img_rect.x = col_count * tile_size
    img_rect.y = row_count * tile_size
    tile = (img, img_rect)
    self.tile_list.append(tile)
    if tile == 3:
    lava = Lava(col_count*tile_size,row_count * tile_size + (tile_size // 2))
    lava_group.add(lava)
    if tile == 4:
    portal = Portal(col_count * tile_size, row_count * tile_size )
    portal_group.add(portal)

    col_count += 1
    row_count += 1

    def draw(self):
    for tile in self.tile_list:
    screen.blit(tile[0], tile[1])
    #pygame.draw.rect(screen,(255,255,255), tile[1],2)

    class Lava(pygame.sprite.Sprite):
    def __init__(self,x,y):
    pygame.sprite.Sprite.__init__(self)
    img = pygame.image.load('img/lava.png')
    self.image = pygame.transform.scale(img,(tile_size,tile_size // 2))
    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = y


    class Portal(pygame.sprite.Sprite):
    def __init__(self,x,y):
    pygame.sprite.Sprite.__init__(self)
    img = pygame.image.load('img/1.png')
    self.image = pygame.transform.scale(img, (tile_size , tile_size ))
    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = y





    #pygame.sprite.Sprite.__init__(self)
    #portal_cooldown = 5
    #self.portal_images= []
    #for num in range(0,3):
    # portal_img = pygame.image.load(f'img/portal/{num}.png')
    # portal_img = pygame.transform.scale(portal_img, (40,40))
    # self.portal_images.append(portal_img)
    #
    #if self.counter > portal_cooldown:
    # self.counter = 0
    # self.index += 1
    #if self.index >= len(self.portal_images):
    # self.index = 0
    #
    #img = portal_img
    #self.image = pygame.transform.scale(img,(tile_size , tile_size))
    #self.rect = self.image.get_rect()
    #self.rect.x = x
    #self.rect.y = y



    map_data = [
    [
    [4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0],
    [0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0],
    [0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,2,0,0,0],
    [0,0,0,0,0,1,1,1,0,0,0,1,0,2,0,2,2,0,0,0],
    [1,1,1,1,0,2,2,2,0,1,0,2,0,0,0,0,0,0,0,0],
    [2,2,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0],
    [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]
    ],
    [
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,1,0,1,1,1,0,0,1,0,0,1,0,1,1,1,0,0,4],
    [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
    [0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1],
    [0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,0,0,1,2],
    [1,1,1,1,0,0,1,0,0,1,0,2,0,0,0,0,1,1,2,2],
    [2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0],
    [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]
    ]
    ]

    player = player(30,screen_height - 100 )

    lava_group = pygame.sprite.Group()
    portal_group = pygame.sprite.Group()


    map = map(map_data[level])

    #make buttons
    restart_button = Button(screen_width // 2 - 50, screen_height // 2, restart_img)
    start_button = Button(screen_width // 2 - 50, screen_height // 2 + 55, start_img)
    exit_button = Button(screen_width // 2 - 50, screen_height // 2 + 115, exit_img)
    next_button = Button(screen_width // 2 - 50, screen_height // 2, next_img)
    run = True
    while run:
    clock.tick(fps)
    screen.blit(startbg_img,(0,0))


    if main_menu == True:
    if start_button.draw():
    main_menu = False
    if exit_button.draw():
    run = False
    else:

    screen.blit(bg_img,(0,0))
    map.draw()


    lava_group.draw(screen)

    game_over = player.update(game_over)

    portal_group.draw(screen)


    if game_over == -1:
    if restart_button.draw():
    player.reset(30,screen_height - 100)
    game_over = 0



    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    run = False

    pygame.display.update()


    I can't figure out how to redraw the map and increase the level. Help would be appreciated.

    Continue reading...

Compartilhe esta Página