首页 > 解决方案 > 我的迷你游戏项目仅在窗口关闭时运行

问题描述

我为一个大学项目用 python 编写了一个迷你游戏。它处于早期阶段,但我在运行时遇到问题。当我运行 .py 文件时,会出现一个黑色窗口。当我按下“X”按钮关闭窗口时,只有我的背景显示一秒钟,然后窗口关闭。简而言之,我的游戏只有在我关闭窗口时才会运行。

import pygame
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import numpy

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (50, 50, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
player_speed = 10


class Player(pygame.sprite.Sprite):
    change_x = 0
    change_y = 0

    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface([10, 10])
        self.image.fill(WHITE)
        self.rect = self.image.get_rect()
        self.rect.y = y
        self.rect.x = x
        self.change_x = 0
        self.change_y = 0
        #self.walls = None

    def changespeed(self, x, y):
        self.change_x += x
        self.change_y += y

    def move(self, walls):
        self.rect.x += self.change_x
        block_hit_list = pygame.sprite.spritecollide(self, walls, False)
        for block in block_hit_list:
            if self.change_x > 0:
                self.rect.right = block.rect.left
            else:
                self.rect.left = block.rect.right
        self.rect.y += self.change_y
        block_hit_list = pygame.sprite.spritecollide(self, walls, False)
        for block in block_hit_list:
            if self.change_y > 0:
                self.rect.bottom = block.rect.top
            else:
                self.rect.top = block.rect.bottom


class Wall(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height):
        super().__init__()
        self.image = pygame.Surface([width, height])
        self.image.set_alpha(0)
        self.image.fill([255, 255, 255])
        self.rect = self.image.get_rect()
        self.rect.y = y
        self.rect.x = x


class Level(object):
    wall_list = None
    enemy_sprites = None

    def __init__(self):
        self.wall_list = pygame.sprite.Group()
        self.enemy_sprites = pygame.sprite.Group()


class Level1(Level):
    def __init__(self):
        super().__init__()
        walls = [........]                 
        for item in walls:
            wall = Wall(item[0], item[1], item[2], item[3])
            self.wall_list.add(wall)


class Level2(Level):
    def __init__(self):
        super().__init__()
        walls = [.....]
        for item in walls:
            wall = Wall(item[0], item[1], item[2], item[3])
            self.wall_list.add(wall)


def main():
    pygame.init()
    screen = pygame.display.set_mode([1000, 800])
    pygame.display.set_caption('GAME')
    player = Player(100, 100)
    movingsprites = pygame.sprite.Group()
    movingsprites.add(player)

    levels = []
    level = Level1()
    levels.append(level)
    level = Level2()
    levels.append(level)
    current_level_no = 0
    current_level = levels[current_level_no]

    clock = pygame.time.Clock()
    done = False

    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    player.changespeed(-player_speed, 0)
                elif event.key == pygame.K_RIGHT:
                    player.changespeed(player_speed, 0)
                elif event.key == pygame.K_UP:
                    player.changespeed(0, -player_speed)
                elif event.key == pygame.K_DOWN:
                    player.changespeed(0, player_speed)

            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    player.changespeed(player_speed, 0)
                elif event.key == pygame.K_RIGHT:
                    player.changespeed(-player_speed, 0)
                elif event.key == pygame.K_UP:
                    player.changespeed(0, player_speed)
                elif event.key == pygame.K_DOWN:
                    player.changespeed(0, -player_speed)

        player.move(current_level.wall_list)

    if player.rect.x > 900 and player.rect.y < 100:
        if current_level_no == 0:
            current_level_no = 1
            current_level = levels[current_level_no]
            player.rect.x = 50
            player.rect.y = 450
        elif current_level_no == 1:
            current_level_no = 2
            current_level = levels[current_level_no]
            player.rect.x = 790
        else:
            current_level_no = 0
            current_level = levels[current_level_no]
            player.rect.x = 790

    '''if player.rect.x > 1000:
        if current_level_no == 0:
            current_level_no = 1
            current_level = levels[current_level_no]
            player.rect.x = 0
        elif current_level_no == 1:
            current_level_no = 2
            current_level = levels[current_level_no]
            player.rect.x = 0
        else:
            current_level_no = 0
            current_level = levels[current_level_no]
            player.rect.x = 0'''

    if current_level_no == 0:
        background_image1 = pygame.image.load("level1background.jpg").convert()
        screen.blit(background_image1, [0, 0])
    else:
        background_image2 = pygame.image.load("level2background.jpg").convert()
        screen.blit(background_image2, [0, 0])

    movingsprites.draw(screen)
    current_level.wall_list.draw(screen)
    pygame.display.flip()
    clock.tick(60)


pygame.quit()
if __name__ == "__main__":
    main()

标签: pythonpygame

解决方案


除了walls = [....]语法错误之外,基本上问题在于主循环。

最大的问题是由于缩进错误,循环的尾端while not done没有包含最后两个代码块。该行之后的所有代码if player.rect.x > 900 and player.rect.y < 100:都不是循环的一部分,因为它向左缩进了 1 级。纠正这个基本上解决了一切。

def main():
    pygame.init()
    screen = pygame.display.set_mode([1000, 800])
    pygame.display.set_caption('GAME')
    player = Player(100, 100)
    movingsprites = pygame.sprite.Group()
    movingsprites.add(player)

    levels = []
    level = Level1()
    levels.append(level)
    level = Level2()
    levels.append(level)
    current_level_no = 0
    current_level = levels[current_level_no]
    background_image1 = pygame.image.load("level1background.jpg").convert()
    background_image2 = pygame.image.load("level2background.jpg").convert()

    clock = pygame.time.Clock()
    done = False

    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    player.changespeed(-player_speed, 0)
                elif event.key == pygame.K_RIGHT:
                    player.changespeed(player_speed, 0)
                elif event.key == pygame.K_UP:
                    player.changespeed(0, -player_speed)
                elif event.key == pygame.K_DOWN:
                    player.changespeed(0, player_speed)

            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    player.changespeed(player_speed, 0)
                elif event.key == pygame.K_RIGHT:
                    player.changespeed(-player_speed, 0)
                elif event.key == pygame.K_UP:
                    player.changespeed(0, player_speed)
                elif event.key == pygame.K_DOWN:
                    player.changespeed(0, -player_speed)

        player.move(current_level.wall_list)

        if player.rect.x > 900 and player.rect.y < 100:
            if current_level_no == 0:
                current_level_no = 1
                current_level = levels[current_level_no]
                player.rect.x = 50
                player.rect.y = 450
            elif current_level_no == 1:
                current_level_no = 2
                current_level = levels[current_level_no]
                player.rect.x = 790
            else:
                current_level_no = 0
                current_level = levels[current_level_no]
                player.rect.x = 790

        if current_level_no == 0:
            screen.blit(background_image1, [0, 0])
        else:
            screen.blit(background_image2, [0, 0])

        movingsprites.draw(screen)
        current_level.wall_list.draw(screen)
        pygame.display.update()
        pygame.display.flip()
        clock.tick(60)


if __name__ == "__main__":
    main()
    pygame.quit()

我也将这pygame.quit()一行移到了程序的末尾。


推荐阅读