我使用 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()
任何提示将不胜感激
你有 2 个函数main()
和game_over()
,每个函数都有自己的事件循环并执行自己的绘图。
创建 2 个状态变量。第一个状态(run
(表示游戏是必须继续还是终止。
第 2 种状态gameover
指示游戏处于"游戏结束"状态或"游戏正在运行"状态的天气。
根据gameover
的状态,main()
或game_over()
必须在主循环中连续调用。这两个函数都可以更改状态,并且必须返回状态变量的当前值。如果gameover
从True
更改为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
把你的主循环放在另一个循环中,所以一旦game_over
函数完成,它就会再次启动:
# main loop
while True:
run = True
while run:
main()
game_over()
由于pygame.quit()
不会退出程序,因此您需要while run:
两个循环并具有两个run = True
,或者在pygame.quit()
之后使用sys.exit(0)
或raise SystemExit(0)
。
还必须从game_over()
函数的for
循环中删除return run
。