Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
245 views
in Technique[技术] by (71.8m points)

python - pygame window freezing after losing game and cannot press restart

I I'm using this guy's code on YouTube and I'm just adding some new function and classes.

Code:

import random
from random import choice
import pygame
from pygame.locals import *
from pygame import mixer
import pickle
from os import path

pygame.mixer.pre_init(44100, -16, 2, 512)
mixer.init()
pygame.init()

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

screen_width = 800
screen_height = 800

screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Platformer')


# define font
font = pygame.font.SysFont('Bauhaus 93', 70)
font_score = pygame.font.SysFont('Bauhaus 93', 30)


#define game variables
music = ['music.wav', 'Emotional Piano.wav', 'Movie 1.wav', 'Odesong.wav', 'Video Game 1.wav', 'Techno.wav']
tile_size = 40
game_over = 0
main_menu = True
level = 9
max_levels = 8
score = 0


# define colors
white = (255, 255, 255)
blue = (0, 0, 255)


# load images
sun_img = pygame.image.load('sun.png')
bg_img = pygame.transform.scale(pygame.image.load("sky.png"), (screen_width, screen_height))
restart_img = pygame.image.load('restart_btn.png')
start_img = pygame.image.load('start_btn.png')
exit_img = pygame.image.load('exit_btn.png')

# load sounds
pygame.mixer.music.load('music.wav')
pygame.mixer.music.play(-1, 0.0, 5000)
coin_fx = pygame.mixer.Sound('coin.wav')
coin_fx.set_volume(0.5)
jump_fx = pygame.mixer.Sound('jump.wav')
jump_fx.set_volume(0.5)
game_over_fx = pygame.mixer.Sound('Lose.wav')
game_over_fx.set_volume(0.1)
next_level_fx = pygame.mixer.Sound('Next level.wav')
next_level_fx.set_volume(0.5)
win_fx = pygame.mixer.Sound('Win.wav')
win_fx.set_volume(0.5)

def draw_text(text, font, text_col, x, y):
    img = font.render(text, True, text_col)
    screen.blit(img, (x, y))


# function to reset level
def reset_level(level):
    player.reset(100, screen_height - 130)
    blob_group.empty()
    platform_group.empty()
    lava_group.empty()
    exit_group.empty()

    # load in level data and create world
    if path.exists(f'level{level}_data'):
    pickle_in = open(f'level{level}_data', 'rb')
    world_data = pickle.load(pickle_in)
    world = World(world_data)

    return world


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

    # get mouse position
    pos = pygame.mouse.get_pos()

    # check mouseover and clicked conditions
    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):
    dx = 0
    dy = 0
    walk_cooldown = 5
    col_thresh = 20

    if game_over == 0:
        #get keypresses
        key = pygame.key.get_pressed()
        if key[pygame.K_SPACE] and self.jumped == False and self.in_air == False:
        jump_fx.play()
        self.vel_y = -15
        self.jumped = True
        if key[pygame.K_SPACE] == False:
        self.jumped = False
        if key[pygame.K_LEFT]:
        dx -= 5
        self.counter += 1
        self.direction = -1
        if key[pygame.K_RIGHT]:
        dx += 5
        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]


        #handle animation
        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]


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

        #check for collision
        self.in_air = True
        for tile in world.tile_list:
        #check for collision in x direction
        if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
            dx = 0
        #check for collision in y direction
        if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
            #check if below the ground i.e. jumping
            if self.vel_y < 0:
            dy = tile[1].bottom - self.rect.top
            self.vel_y = 0
            #check if above the ground i.e. falling
            elif self.vel_y >= 0:
            dy = tile[1].top - self.rect.bottom
            self.vel_y = 0
            self.in_air = False


        # check for collision with enemies
        if pygame.sprite.spritecollide(self, blob_group, False):
        game_over = -1

        # check for collision with lava
        if pygame.sprite.spritecollide(self, lava_group, False):
        game_over = -1

        # check for collision with exit
        if pygame.sprite.spritecollide(self, exit_group, False):
        game_over = 1
        next_level_fx.play()

        # check for collision with spikes
        if pygame.sprite.spritecollide(self, spike_group, False):
        game_over = -1


        # check for collision with platforms
        for platform in platform_group:
        # collision in the x direction
        if platform.rect.colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
            dx = 0
        # collision in the y direction
        if platform.rect.colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
            # check if below platform
            if abs((self.rect.top + dy) - platform.rect.bottom) < col_thresh:
            self.vel_y = 0
            dy = platform.rect.bottom - self.rect.top
            # check if above platform
            elif abs((self.rect.bottom + dy) - platform.rect.top) < col_thresh:
            self.rect.bottom = platform.rect.top - 1
            self.in_air = False
            dy = 0
            # move sideways with platform
            if platform.move_x != 0:
            self.rect.x += platform.move_direction


        #update player coordinates
        self.rect.x += dx
        self.rect.y += dy


    elif game_over == -1:
        self.image = self.dead_image
        draw_text('GAME OVER!', font, blue, (screen_width // 2) - 200, screen_height // 2)
        if self.rect.y > 200:
           self.rect.y -= 5

    #draw player onto screen
    screen.blit(self.image, self.rect)

    return game_over


    def reset(self, x, y):
    self.images_right = []
    self.images_left = []
    self.index = 0
    self.counter = 0
    for num in range(1, 5):
        img_right = pygame.image.load(f'guy{num}.png')
        img_right = pygame.transform.scale(img_right, (40, 80))
        img_left = pygame.transform.flip(img_right, True, False)
        self.images_right.append(img_right)
        self.images_left.append(img_left)
    self.dead_image = pygame.image.load('ghost.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
    self.direction = 0
    self.in_air = True



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

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

    row_count = 0
    for row in data:
        col_count = 0
        for tile in row:
        if tile == 1:
            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 == 2:
            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 == 3:
            blob = Enemy(col_count * tile_size, row_count * tile_size + 5)
            blob_group.add(blob)
        if tile == 4:
            platform = Platform(col_count * tile_size, row_count * tile_size, 1, 0)
            platform_group.add(platform)
        if tile == 5:
            platform = Platform(col_count * tile_size, row_count * tile_size, 0, 1)
            platform_group.add(platform)
        if tile == 6:
            lava = Lava(col_count * tile_size, row_count * tile_size + (tile_size // 2))
            lava_group.add(lava)
        if tile == 7:
            coin = Coin(col_count * tile_size + (tile_size // 2), row_count * tile_size + (tile_size // 2))
            coin_group.add(coin)
        if tile == 8:
            exit = Exit(col_count * tile_size, row_count * tile_size - (tile_size // 2))
            exit_group.add(exit)
        if tile == 9:
            spike = Spike(col_count * tile_size, row_count * tile_size)
            spike_group.add(spike)
        col_count += 1
        row_count += 1


    def draw(self):
    for tile in self.tile_list:
        screen.blit(tile[0], tile[1])



class Enemy(pygame.sprite.Sprite):
    def __init__(self, x, y):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load('blob.png')
    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = y
    self.move_direction = 1
    self.move_counter = 0

    def update(self):
    self.rect.x += self.move_direction
    self.move_counter += 1
    if abs(self.move_counter) > 10:
        self.move_direction *= -1
        self.move_counter *= -1


class Platform(pygame.sprite.Sprite):
    def __init__(self, x, y, move_x, move_y):
    pygame.sprite.Sprite.__init__(self)
    img = pygame.image.load('platform.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
    self.move_counter = 0
    self.move_direction = 1
    self.move_x = move_x
    self.move_y = move_y


    def update(self):
    self.rect.x += self.move_direction * self.move_x
    self.rect.y += self.move_direction * self.move_y
    self.move_counter += 1
    if abs(self.move_counter) > 50:
         self.move_direction *= -1
         self.move_counter *= -1





class Lava(pygame.sprite.Sprite):
    def __init__(self, x, y):
    pygame.sprite.Sprite.__init__(self)
    img = pygame.image.load('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 Coin(pygame.sprite.Sprite):
    def __init__(self, x, y):
    pygame.sprite.Sprite.__init__(self)
    img = pygame.image.load('coin.png')
    self.image = pygame.transform.scale(img, (tile_size // 2, tile_size // 2))
    self.rect = self.image.get_rect()
    self.rect.center = (x, y)


class Exit(pygame.sprite.Sprite):
    def __

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...