本文介绍了游戏机如何处理状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我最近用pyGame完成了一款连接四个类型的游戏。在任一玩家获胜后,它会显示一个菜单,询问你是想再次玩还是退出,每个选项都有一个按钮。程序根据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",
GREEN,
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",
RED,
self.quit,
xpos=quit_xpos,
ypos=quit_ypos,
show_border=True,
border_color=(255, 255, 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, 255, 0): "Yellow", (255, 0, 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
)引用当前状态类。另一种方法(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()
这篇关于游戏机如何处理状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!