[英]Game Over Screen using Pygame
我正在尝试完成一个版本的乒乓球,我希望当球员错过球并击中球拍后面的墙壁时比赛结束。 我一直在尝试为此构建一个 Game Over 屏幕,但没有运气。 我希望用户可以选择重新开始新游戏或一起退出屏幕。
# Import the pygame library and initialise the game
# the scoring system will be inside of the main game
# the paddle and ball classes are imported into the main game
# still trying to work out how to make the other paddle move without keyboard input
import pygame
from Paddle import Paddle
from Ball import Ball
#while running loop
#rest of the code
pygame.init()
black = (0,0,0)
white = (255,255,255)
paddle2 = Paddle(white, 10, 100)
paddle2.rect.x = 670
paddle2.rect.y = 200
ball = Ball(white,8,8)
ball.rect.x = 345
ball.rect.y = 195
width = 700
height = 500
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Pong")
user_lose = False
sprites_list = pygame.sprite.Group()
sprites_list.add(paddle2)
sprites_list.add(ball)
carryOn = True
clock = pygame.time.Clock()
#Set inital player scores:
scoreA = 0
scoreB = 0
# -------- Main Program Loop -----------
while carryOn:
for event in pygame.event.get():
if event.type == pygame.QUIT:
carryOn = False
elif event.type==pygame.KEYDOWN:
if event.key==pygame.K_x:
carryOn=False
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
paddle2.up(5)
if keys[pygame.K_DOWN]:
paddle2.down(5)
sprites_list.update()
if ball.rect.x>=690:
scoreA+=1
ball.velocity[0] = -ball.velocity[0]
if ball.rect.x<=0:
scoreB+=1
ball.velocity[0] = -ball.velocity[0]
if ball.rect.y>490:
ball.velocity[1] = -ball.velocity[1]
if ball.rect.y<0:
ball.velocity[1] = -ball.velocity[1]
if pygame.sprite.collide_mask(ball, paddle2):
ball.bounce()
screen.fill(black)
sprites_list.draw(screen)
#Scores displayed:
font = pygame.font.Font(None, 74)
font2 = pygame.font.Font(None, 55)
"""
text = font.render(str(scoreA), 1, white)
screen.blit(text, (250,10))
"""
text = font.render(str(scoreB), 1, white)
screen.blit(text, (430,10))
text = font.render(str("Score: "), 1 ,white)
screen.blit(text, (250, 10))
text = font2.render(str("Keep The Ball Bouncing"), 1, white)
screen.blit(text, (155,60))
pygame.display.flip()
clock.tick(60)
pygame.quit()
您可以使用变量state = 'INTRO'/'GAME'/'GAMEOVER'
或分隔变量is_intro = True/False
, is_game = True/False
, is_gameover = True/False
, is_pause = True/False
来控制在 main 中执行的代码环形
它还需要使用global
来重置外部/全局值的 function reset_all_values
。
像这样的东西。
import pygame
def reset_all_values():
global scoreA
global scoreB
scoreA = 0
scoreB = 0
# reset other values
# --- main ---
size = (700, 500)
pygame.init()
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
font = pygame.font.Font(None, 50)
reset_all_values()
# -------- Main Program Loop -----------
state = 'INTRO'
carry_on = True
while carry_on:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
carryOn = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
carry_on = False
if state == 'INTRO':
if event.key == pygame.K_ESCAPE:
state = 'GAME'
reset_all_values() #
# other keys for intro
elif state == 'GAME':
if event.key == pygame.K_ESCAPE:
state = 'GAMEOVER'
# other keys for game
elif state == 'GAMEOVER':
if event.key == pygame.K_ESCAPE:
state = 'INTRO'
#reset_all_values() # TODO
# other keys for gameover
# --- changes/moves/collisions ---
if state == 'INTRO':
pass
elif state == 'GAME':
scoreA += 1
if scoreA >= 100:
state = 'GAMEOVER'
elif state == 'GAMEOVER':
pass
# --- draws ---
screen.fill((0,0,0))
if state == 'INTRO':
text = font.render('INTRO - Press ESC', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
elif state == 'GAME':
text = font.render('GAME - Wait for Score 100', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
text = font.render(f'SCORE {scoreA}' , True, (255,255,255))
rect = text.get_rect()
screen.blit(text, rect)
elif state == 'GAMEOVER':
text = font.render('GAMEOVER - Press ESC', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
text = font.render(f'SCORE {scoreA}' , True, (255,255,255))
rect = text.get_rect()
screen.blit(text, rect)
pygame.display.flip()
clock.tick(30)
pygame.quit()
您还可以将代码放入intro_event_handle()
、 intro_change()
、 intro_draw()
等函数中,以使其更具可读性。
import pygame
def intro_handle_event(event):
global state
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
state = 'GAME'
reset_all_values() #
# other keys for intro
def game_handle_event(event):
global state
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
state = 'GAMEOVER'
# other keys for game
def gameover_handle_event(event):
global state
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
state = 'INTRO'
# other keys for gameover
def intro_change():
pass
def game_change():
global state
global scoreA
scoreA += 1
if scoreA >= 100:
state = 'GAMEOVER'
def gameover_change():
pass
def intro_draw(screen):
text = font.render('INTRO - Press ESC', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
def game_draw(screen):
text = font.render('GAME - Wait for SCORE 100', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
text = font.render(f'SCORE {scoreA}' , True, (255,255,255))
rect = text.get_rect()
screen.blit(text, rect)
def gameover_draw(screen):
text = font.render('GAMEOVER - Press ESC', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
text = font.render(f'SCORE {scoreA}' , True, (255,255,255))
rect = text.get_rect()
screen.blit(text, rect)
def reset_all_values():
global scoreA
global scoreB
scoreA = 0
scoreB = 0
# reset other values
# --- main ---
size = (700, 500)
pygame.init()
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
font = pygame.font.Font(None, 50)
reset_all_values()
# -------- Main Program Loop -----------
state = 'INTRO'
carry_on = True
while carry_on:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
carryOn = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
carry_on = False
if state == 'INTRO':
intro_handle_event(event)
elif state == 'GAME':
game_handle_event(event)
elif state == 'GAMEOVER':
gameover_handle_event(event)
# --- changes/moves/collisions ---
if state == 'INTRO':
intro_change()
elif state == 'GAME':
game_change()
elif state == 'GAMEOVER':
gameover_change()
# --- draws ---
screen.fill((0,0,0))
if state == 'INTRO':
intro_draw(screen)
elif state == 'GAME':
game_draw(screen)
elif state == 'GAMEOVER':
gameover_draw(screen)
pygame.display.flip()
clock.tick(30)
pygame.quit()
您可以将函数保存在字典中
handle_event = {
'INTRO': intro_handle_event,
'GAME': game_handle_event,
'GAMEOVER': gameover_handle_event,
}
并仅使用state
(而不是if/elif
)来执行正确的 function。
handle_event[state](event)
import pygame
def intro_handle_event(event):
global state
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
state = 'GAME'
reset_all_values() #
# other keys for intro
def game_handle_event(event):
global state
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
state = 'GAMEOVER'
# other keys for game
def gameover_handle_event(event):
global state
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
state = 'INTRO'
# other keys for gameover
def intro_change():
pass
def game_change():
global state
global scoreA
scoreA += 1
if scoreA >= 100:
state = 'GAMEOVER'
def gameover_change():
pass
def intro_draw(screen):
text = font.render('INTRO - Press ESC', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
def game_draw(screen):
text = font.render('GAME - Wait for SCORE 100', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
text = font.render(f'SCORE {scoreA}' , True, (255,255,255))
rect = text.get_rect()
screen.blit(text, rect)
def gameover_draw(screen):
text = font.render('GAMEOVER - Press ESC', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
text = font.render(f'SCORE {scoreA}' , True, (255,255,255))
rect = text.get_rect()
screen.blit(text, rect)
def reset_all_values():
global scoreA
global scoreB
scoreA = 0
scoreB = 0
# reset other values
# --- main ---
size = (700, 500)
pygame.init()
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
font = pygame.font.Font(None, 50)
reset_all_values()
handle_event = {
'INTRO': intro_handle_event,
'GAME': game_handle_event,
'GAMEOVER': gameover_handle_event,
}
change = {
'INTRO': intro_change,
'GAME': game_change,
'GAMEOVER': gameover_change,
}
draw = {
'INTRO': intro_draw,
'GAME': game_draw,
'GAMEOVER': gameover_draw,
}
# -------- Main Program Loop -----------
state = 'INTRO'
carry_on = True
while carry_on:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
carryOn = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
carry_on = False
handle_event[state](event)
# --- changes/moves/collisions ---
change[state]()
# --- draws ---
screen.fill((0,0,0))
draw[state](screen)
pygame.display.flip()
clock.tick(30)
pygame.quit()
In similar way you can keep it in classes.
import pygame
class Intro():
def __inti__(self):
self.reset()
def reset(self):
pass
def handle_event(self, event):
global state
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
state = 'GAME'
scene[state].reset()
# other keys for intro
def change(self):
pass
def draw(self, screen):
text = font.render('INTRO - Press ESC', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
class Game():
def __inti__(self):
self.reset()
def reset(self):
global scoreA
global scoreB
scoreA = 0
scoreB = 0
# reset other values
def handle_event(self, event):
global state
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
state = 'GAMEOVER'
scene[state].reset()
# other keys for game
def change(self):
global state
global scoreA
scoreA += 1
if scoreA >= 100:
state = 'GAMEOVER'
scene[state].reset()
def draw(self, screen):
text = font.render('GAME - Wait for SCORE 100', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
text = font.render(f'SCORE {scoreA}' , True, (255,255,255))
rect = text.get_rect()
screen.blit(text, rect)
class GameOver():
def __inti__(self):
self.reset()
def reset(self):
pass
def handle_event(self, event):
global state
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
state = 'INTRO'
scene[state].reset()
# other keys for gameover
def change(self):
pass
def draw(self, screen):
text = font.render('GAMEOVER - Press ESC', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
text = font.render(f'SCORE {scoreA}' , True, (255,255,255))
rect = text.get_rect()
screen.blit(text, rect)
# --- main ---
size = (700, 500)
pygame.init()
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
font = pygame.font.Font(None, 50)
scene = {
'INTRO': Intro(),
'GAME': Game(),
'GAMEOVER': GameOver(),
}
# -------- Main Program Loop -----------
state = 'INTRO'
carry_on = True
while carry_on:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
carryOn = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
carry_on = False
scene[state].handle_event(event)
# --- changes/moves/collisions ---
scene[state].change()
# --- draws ---
screen.fill((0,0,0))
scene[state].draw(screen)
pygame.display.flip()
clock.tick(30)
pygame.quit()
这样您就可以构建有限的 State 机器
其他方法可以为每个状态创建单独的循环并将其放入将运行选定循环或退出游戏的外部循环。
import pygame
def intro_loop(screen):
print('start intro loop')
carry_on = True
next_state = None
while carry_on and not next_state:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
carry_on = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
carry_on = False
if event.key == pygame.K_ESCAPE:
next_state = 'GAME'
# --- changes/moves/collisions ---
# --- draws ---
screen.fill((0,0,0))
text = font.render('INTRO - Press ESC', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
pygame.display.flip()
clock.tick(30)
return carry_on, next_state
def game_loop(screen):
global scoreA
global scoreB
scoreA = 0
scoreB = 0
# reset other values
print('start game loop')
carry_on = True
next_state = None
while carry_on and not next_state:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
carry_on = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
carry_on = False
if event.key == pygame.K_ESCAPE:
next_state = 'GAMEOVER'
# --- changes/moves/collisions ---
scoreA += 1
if scoreA >= 100:
next_state = 'GAMEOVER'
# --- draws ---
screen.fill((0,0,0))
text = font.render('GAME - Wait for SCORE 100', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
text = font.render(f'SCORE {scoreA}' , True, (255,255,255))
rect = text.get_rect()
screen.blit(text, rect)
pygame.display.flip()
clock.tick(30)
return carry_on, next_state
def gameover_loop(screen):
print('start gameover loop')
carry_on = True
next_state = None
while carry_on and not next_state:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
carry_on = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
carry_on = False
if event.key == pygame.K_ESCAPE:
next_state = 'INTRO'
# --- changes/moves/collisions ---
# --- draws ---
screen.fill((0,0,0))
text = font.render('GAMEOVER - Press ESC', True, (255,255,255))
rect = text.get_rect(center=screen.get_rect().center)
screen.blit(text, rect)
text = font.render(f'SCORE {scoreA}' , True, (255,255,255))
rect = text.get_rect()
screen.blit(text, rect)
pygame.display.flip()
clock.tick(30)
return carry_on, next_state
# --- main ---
size = (700, 500)
pygame.init()
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
font = pygame.font.Font(None, 50)
# -------- Main Program Loop -----------
state = 'INTRO'
carry_on = True
while carry_on:
if state == 'INTRO':
carry_on, state = intro_loop(screen)
elif state == 'GAME':
carry_on, state = game_loop(screen)
elif state == 'GAMEOVER':
carry_on, state = gameover_loop(screen)
pygame.quit()
我假设从您的表述方式来看,您的问题是游戏的重新运行,而不是提出问题的游戏结束屏幕。 假设是这种情况...
我不同意尝试将不同状态组合成一个游戏循环的方法。 当然可以,但在这种情况下没有真正好的理由这样做。 它使代码更难遵循,而不会从这种结构中获得任何好处。 在某些情况下,state 机器方法是有意义的,但这确实不是其中之一。
添加一个包含有关重新启动游戏的问题的额外循环可以比这简单得多。 从
carryOn = True
至
pygame.display.flip()
clock.tick(60)
除了这一行:
clock = pygame.time.Clock()
并将所有这些移到一个名为run_game()
的方法中
您还需要移动初始化桨和球位置的线,以及user_lose = False
并将其移动到run_game()
方法的开头。
然后,当您想运行游戏时,您可以调用它。 退出后,您可以询问他们是否要再次播放,如果他们愿意,请再次调用它,如果他们选择不这样做,则退出。 当然,您需要在一个循环中多次重复此操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.