使用Pygame进行Python游戏的游戏问题

问题描述 投票:1回答:2

我在python中使用pygame模块为基本的蛇游戏编写了代码,并且已经到了基本完成的地步,但是,我希望在最后显示一些文本的屏幕上有一个游戏,可以选择播放再次显示分数。如果他们重新开始,分数重置为0并再次播放。不幸的是我似乎无法让这个屏幕成功运行。我已经尝试了一些东西,但我似乎总是得到显示Surface退出的错误。如果有任何提示,我将在下面分享我的代码。

import sys, time, random, pygame
from random import randrange
pygame.init()
fps_controller = pygame.time.Clock()
#Screen Dimensions
screen_width = 600
screen_height = 600

#Screen Set Up
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Snake by Bela Zumbansen")
pygame.mouse.set_visible(0)

#Colours
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLACK  = (0, 0, 0)
GREY = (200, 200, 200)
BLUE = (0, 0, 255)
WHITE = (255, 255, 255)
LIGHTBLUE = (0, 155, 155)

#Directions
RIGHT = 1
LEFT = 2
UP = 3
DOWN = 4

#Game Set Up
snake_pos = [100, 100]
snake_body = [[100, 100], [90, 100], [80, 100]]
snake_speed = 10

apple_pos = [random.randrange(1,60)*10, random.randrange(1,60)*10]
apple_spawn = True

direction = RIGHT
update = direction

scoreval = 0

def game_over():
    global run, scoreval
    screen.fill(LIGHTBLUE)
    draw_text("GAME OVER", 48, WHITE, screen_width/2, screen_height/4)
    draw_text("Score: " + str(score), 22, WHITE,  screen_width / 2, screen_height / 3)
    draw_text("Press SPACE to play again or ESC to exit", 22, WHITE, screen_width/2, screen_height / 4)
    waiting = True
    while waiting:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    scoreval = 0
                    return scoreval
                    run = True
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
            return run
def draw_text(text, size, color, x, y):
    font = pygame.font.Font('freesansbold.ttf', size)
    TextSurf, TextRect = text_objects(text, font, color)
    TextRect.center = (x, y)
    screen.blit(TextSurf, TextRect)

def text_objects(text, font, color):
    textSurface = font.render(text, True, color)
    return textSurface, textSurface.get_rect()

def eating_apple():
    global scoreval, apple_spawn
    scoreval += 1
    apple_spawn = False

def spawnApple():
    global apple_pos, apple_spawn
    apple_pos = [random.randrange(1,60)*10, random.randrange(1,60)*10]
    apple_spawn = True

def score(score):
    font = pygame.font.SysFont(None, 25)
    text = font.render("Score: "+str(score), True, WHITE)
    screen.blit(text,(10,10))

def main():
    global update, direction, run, snake_pos, snake_speed, apple_spawn, apple_pos
    pygame.time.delay(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        update = LEFT
    elif keys[pygame.K_RIGHT]:
        update = RIGHT
    elif keys[pygame.K_UP]:
        update = UP
    elif keys[pygame.K_DOWN]:
        update = DOWN

    if update == RIGHT and direction != LEFT:
        direction = RIGHT
    if update == LEFT and direction != RIGHT:
        direction = LEFT
    if update == UP and direction != DOWN:
        direction = UP
    if update == DOWN and direction != UP:
        direction = DOWN

    if direction == RIGHT:
        snake_pos[0] += snake_speed
    if direction == LEFT:
        snake_pos[0] -= snake_speed
    if direction == UP:
        snake_pos[1] -= snake_speed
    if direction == DOWN:
        snake_pos[1] += snake_speed

    snake_body.insert(0, list(snake_pos))
    if pygame.Rect(*snake_pos, 20, 20).colliderect(*apple_pos, 20, 20):
        eating_apple()
    else:
        snake_body.pop()
    if not apple_spawn:
        spawnApple()

    screen.fill(BLACK)
    for pos in snake_body:
        pygame.draw.rect(screen, GREEN, pygame.Rect(pos[0], pos[1], 20, 20))

    pygame.draw.rect(screen, RED, pygame.Rect(apple_pos[0], apple_pos[1], 20, 20))

    if snake_pos[0] < 0 or snake_pos[0] > screen_width-20:
        run = False
    if snake_pos[1] < 0 or snake_pos[1] > screen_height-20:
        run = False

    for block in snake_body[1:]:
        if snake_pos[0] == block[0] and snake_pos[1] == block[1]:
            run = False

    score(scoreval)
    pygame.display.update()
    fps_controller.tick(25)

#main loop
run = True
while run:
    main()


game_over()

任何提示将非常感谢

python function while-loop pygame
2个回答
0
投票

你有2个函数main()game_over(),每个函数都有自己的事件循环并自己绘制。 创建2个状态变量。第一个状态(run)表示游戏是否必须继续或终止。 第二状态gameover表示游戏处于“游戏结束”状态或“游戏运行”状态的天气。 取决于gameover的状态,main()game_over()必须在主循环中连续调用。这两个函数都可以更改状态,并且必须返回状态变量的当前值。如果gameoverTrue变为False,则必须将游戏控制变量设置为其初始状态(当然,您也可以在代码中为此编写函数):

run = True
gameover = False
while run:
    if not gameover:
        run, gameover = main()
    else:
        run, gameover = game_over()
        if not gameover:
            snake_pos = [100, 100]
            snake_body = [[100, 100], [90, 100], [80, 100]]
            snake_speed = 10
            apple_pos = [random.randrange(1,60)*10, random.randrange(1,60)*10]
            apple_spawn = True
            direction = RIGHT
            update = direction
            scoreval = 0

游戏结束功能必须绘制“游戏结束”屏幕,当然还有pygame.display.update()。该函数评估状态更改并返回值:

def game_over():

    screen.fill(LIGHTBLUE)
    draw_text("GAME OVER", 48, WHITE, screen_width/2, screen_height/4)
    draw_text("Score: " + str(score), 22, WHITE,  screen_width / 2, screen_height / 3)
    draw_text("Press SPACE to play again or ESC to exit", 22, WHITE, screen_width/2, screen_height / 4)
    pygame.display.update()
    fps_controller.tick(25)

    rungame = True 
    continuegame = False 
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            rungame  = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                continuegame = True
            if event.key == pygame.K_ESCAPE:
                rungame = False
    return rungame, not continuegame

如果蛇碰撞,那么main会返回一个改变的状态:

def main():
    global update, direction, snake_pos, snake_speed, apple_spawn, apple_pos
    pygame.time.delay(60)

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

    # [...]

    collision = False
    if snake_pos[0] < 0 or snake_pos[0] > screen_width-20:
        collision = True
    if snake_pos[1] < 0 or snake_pos[1] > screen_height-20:
        collision = True

    for block in snake_body[1:]:
        if snake_pos[0] == block[0] and snake_pos[1] == block[1]:
            collision = True

    score(scoreval)
    pygame.display.update()
    fps_controller.tick(25)

    return rungame, collision

0
投票

你需要把你的主循环放在另一个循环中,所以一旦game_over函数完成它就会重新开始:

# main loop
while True:
    run = True
    while run:
        main()

    game_over()

因为pygame.quit()没有退出程序,你需要让两个循环都是while run:并且有两个run = Trues,或者在sys.exit(0)之后使用raise SystemExit(0)pygame.quit()

您还必须从return run函数中的for循环中删除game_over()

© www.soinside.com 2019 - 2024. All rights reserved.