如何解决pygame如何处理状态
我最近用pygame用python完成了一个四连体类型的游戏。任一玩家获胜后,它会显示一个菜单,询问您是否要再次玩还是退出,每个选项都有一个按钮。程序根据Game
类中的变量(包含游戏的状态)来确定是运行游戏还是显示菜单。问题是我然后必须在程序中的几个点上有一个if
-elif
子句才能看到要做什么。例如,在Game.draw
方法中,它绘制游戏板和棋子或菜单,Game.on_click
方法将事件发送到游戏板或菜单中的按钮,等等。我的问题是,有没有一种方法可以跟踪游戏状态,而无需在整个程序中分散if
-elif
子句?
game.py:
import pygame
from board import Board
from player import Player
from button import Button
from constants import (
BLACK,RED,YELLOW,GREEN,WHITE,SQUARE_SIZE,ROWS,WIDTH,HEIGHT
)
class Game:
PLAYING = 0
HAS_WON = 1
def __init__(self,win):
self.win = win
# self.running = True
self.state = self.PLAYING
self.running = True
self.board = Board()
self.players = [Player(RED,self.board),Player(YELLOW,self.board)]
self.player_turn_counter = 0
pygame.font.init()
self.font = pygame.font.SysFont("Arial",36)
self.text = ""
play_again_xpos = WIDTH // 5
play_again_ypos = (HEIGHT // 5) * 4
play_again_button = Button("Play Again",self.play_again,xpos=play_again_xpos,ypos=play_again_ypos,show_border=True,border_color=(255,255,255))
quit_xpos = (WIDTH // 5) * 4
quit_ypos = (HEIGHT // 5) * 4
quit_button = Button("Quit",self.quit,xpos=quit_xpos,ypos=quit_ypos,255))
self.buttons = [play_again_button,quit_button]
def play_again(self):
self.__init__(self.win)
self.run()
def quit(self):
self.running = False
def draw(self):
self.win.fill(BLACK)
self.board.draw(self.win)
if self.state == self.HAS_WON:
# self.win.fill(WHITE)
text = self.font.render(self.text,True,WHITE)
text_rect = text.get_rect()
text_rect.centerx = WIDTH // 2
text_rect.centery = ((SQUARE_SIZE * ROWS) // 3) - SQUARE_SIZE // 2
self.win.blit(text,text_rect)
for button in self.buttons:
button.draw(self.win)
# self.play_again_button.draw(self.win)
# self.quit_button.draw(self.win)
pygame.display.update()
def is_full(self,column):
board = self.board.get_board()
# pieces = []
# for row in board:
# pieces.append(row[column])
# return all(pieces)
return all([row[column] for row in board])
def on_win(self,color):
self.state = self.HAS_WON
colors = {(255,0): "Yellow",(255,0): "Red"}
self.text = f"{colors[color]} has won!"
# print(f"{colors[color]} has won!")
def on_click(self):
if self.state == self.PLAYING:
column = self.board.get_column()
if not self.is_full(column):
self.player_turn_counter += 1
self.player_turn_counter = self.player_turn_counter % 2
self.players[self.player_turn_counter].on_click()
has_won,color = self.board.check_for_win()
if has_won:
self.on_win(color)
elif self.state == self.HAS_WON:
for button in self.buttons:
button.on_click()
def run(self):
clock = pygame.time.Clock()
while self.running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.MOUSEBUTTONDOWN:
self.on_click()
self.draw()
这里是整个程序的github仓库: https://github.com/pianocomposer321/ConnectFour.git
解决方法
创建两个具有相同接口的类,每个状态一个。这些类包含与游戏状态相关的实现:
class Playing:
def __init__(self,game)
self.game = game
def draw(self):
# [...]
def on_click(self):
# [...]
class HasWon:
def __init__(self,game):
self.game = game
def draw(self):
# [...]
def on_click(self):
# [...]
Game
类使用实现游戏状态的类。附加属性 (self.current
) 指的是当前的 state 类。附加方法 (set_state
) 切换状态变量并根据状态设置 self.current
。这是程序中唯一需要if
- elif
子句的点。在其他方法中,您可以委托给游戏状态实现的实现方法(例如self.current.draw()
, self.current.on_click()
):
class Game:
PLAYING = 0
HAS_WON = 1
def __init__(self,win):
# [...]
self.playing = Playing(self)
self.haswon = HasWon(self)
self.set_state(self.PLAYING)
def set_state(new_state):
self.state = self.PLAYING
if self.state == self.PLAYING:
self.current = self.playing
elif self.state == self.HAS_WON:
self.current = self.haswon
def draw(self):
self.win.fill(BLACK)
self.board.draw(self.win)
self.current.draw()
pygame.display.update()
def on_win(self,color):
self.set_state(self.HAS_WON)
# [...]
def on_click(self):
self.current.on_click()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。