我正在为我的学校项目在pygame中制作一个简单的Tic Tac Toe游戏。我设法将一些代码放在一起(对不起,如果它有点乱,可能是我试图用来修复当前问题的代码的遗留问题),这在某种程度上可以正常工作。然而,我确实遇到了一个奇怪的错误,我不知道为什么,但似乎我的程序无法处理快速用户输入(如果用户点击非常快),而不是放一个圆然后十字架它可能会放2圆圈或2个十字架。如果用户进展相当慢,它工作正常,但我正在寻找一种摆脱这个问题的方法,如果有人能暗示我做一些我真的很感激。这是源代码:
import pygame
import sys
from pygame.locals import *
DISPLAY_WIDTH = 400
DISPLAY_HEIGHT = 400
BOX_SIZE = 50
BOARD_WIDTH = 3
BOARD_HEIGHT = 3
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BACKGROUND_COLOR = (198, 187, 133)
indexList = ["a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3"]
gameFinished = False
def game_loop():
global DISPLAY_WIDTH, DISPLAY_HEIGHT, displaySurface, gameFinished
pygame.init()
FPSCLOCK = pygame.time.Clock()
displaySurface = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
pygame.display.set_caption("Tic Tac Toe")
displaySurface.fill(BACKGROUND_COLOR)
pygame.draw.line(displaySurface, BLACK, (140, 20), (140, 380), 10)
pygame.draw.line(displaySurface, BLACK, (260, 20), (260, 380), 10)
pygame.draw.line(displaySurface, BLACK, (20, 140), (380, 140), 10)
pygame.draw.line(displaySurface, BLACK, (20, 260), (380, 260), 10)
box1 = pygame.Rect(20, 20, 120, 120)
box2 = pygame.Rect(140, 20, 120,120)
box3 = pygame.Rect(260, 20, 120, 120)
box4 = pygame.Rect(20, 140, 120, 120)
box5 = pygame.Rect(140, 140, 120, 120)
box6 = pygame.Rect(260, 140, 120, 120)
box7 = pygame.Rect(20, 260, 120, 120)
box8 = pygame.Rect(140, 260, 120, 120)
box9 = pygame.Rect(260, 260, 120, 120)
circle = pygame.image.load("circle.png")
cross = pygame.image.load("cross.png")
boardBoxes = [box1, box2, box3, box4, box5, box6, box7, box8, box9]
mouseY = 0
mouseX = 0
placesTaken = {0: False, 1: False, 2: False, 3: False, 4: False, 5: False, 6: False, 7: False, 8: False}
turn = 1
board = generate_boxes(0)
print(repr(board))
while not gameFinished:
mouseClick = False
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == MOUSEMOTION:
mouseX, mouseY = event.pos
elif event.type == MOUSEBUTTONUP:
mouseClick = True
mouseX, mouseY = event.pos
if mouseClick is True and turn == 1:
get_mouse_overbox(mouseX, mouseY, boardBoxes, turn, board)
print("Player")
turn += 1
elif mouseClick is True and turn == 2:
get_mouse_overbox(mouseX, mouseY, boardBoxes, turn, board)
turn -= 1
if board[0] == 1 and placesTaken[0] is False:
put_image(circle, 20, 20)
placesTaken[0] = True
elif board[0] == 2 and placesTaken[0] is False:
put_image(cross, 20, 20)
placesTaken[0] = True
if board[1] == 1 and placesTaken[1] is False:
put_image(circle, 140, 20)
placesTaken[1] = True
elif board[1] == 2 and placesTaken[1] is False:
put_image(cross, 140, 20)
placesTaken[1] = True
if board[2] == 1 and placesTaken[2] is False:
put_image(circle, 260, 20)
placesTaken[2] = True
elif board[2] == 2 and placesTaken[2] is False:
put_image(cross, 260, 20)
placesTaken[2] = True
if board[3] == 1 and placesTaken[3] is False:
put_image(circle, 20, 140)
placesTaken[3] = True
elif board[3] == 2 and placesTaken[3] is False:
put_image(cross, 20, 140)
placesTaken[3] = True
if board[4] == 1 and placesTaken[4] is False:
put_image(circle, 140, 140)
placesTaken[4] = True
elif board[4] == 2 and placesTaken[4] is False:
put_image(cross, 140, 140)
placesTaken[4] = True
if board[5] == 1 and placesTaken[5] is False:
put_image(circle, 260, 140)
placesTaken[5] = True
elif board[5] == 2 and placesTaken[5] is False:
put_image(cross, 260, 140)
placesTaken[5] = True
if board[6] == 1 and placesTaken[6] is False:
put_image(circle, 20, 260)
placesTaken[6] = True
elif board[6] == 2 and placesTaken[6] is False:
put_image(cross, 20, 260)
placesTaken[6] = True
if board[7] == 1 and placesTaken[7] is False:
put_image(circle, 140, 260)
placesTaken[7] = True
elif board[7] == 2 and placesTaken[7] is False:
put_image(cross, 140, 260)
placesTaken[7] = True
if board[8] == 1 and placesTaken[8] is False:
put_image(circle, 260, 260)
placesTaken[8] = True
elif board[8] == 2 and placesTaken[8] is False:
put_image(cross, 260, 260)
placesTaken[8] = True
FPSCLOCK.tick(60)
pygame.display.update()
def put_image(image_name, x_cord, y_cord):
global displaySurface
displaySurface.blit(image_name, (x_cord, y_cord))
def generate_boxes(value):
boxesFilled = []
for i in range(9):
boxesFilled.append(value)
return boxesFilled
def board_getcircles(board):
onlyCircleBoard = [0 if i == 2 else i for i in board]
return onlyCircleBoard
def board_getcrosses(board):
onlyCrossBoard = [0 if i == 2 else i for i in board]
return onlyCrossBoard
def get_mouse_overbox(mouse_x, mouse_y, box_list, which_turn, boardlist):
if which_turn == 1:
for counter in range(len(box_list)):
if box_list[counter].collidepoint(mouse_x, mouse_y):
boardlist[counter] = 1
elif which_turn == 2:
for caunter in range(len(box_list)):
if box_list[caunter].collidepoint(mouse_x, mouse_y):
boardlist[caunter] = 2
game_loop()
答案 0 :(得分:2)
pygame.event.get将检索队列中的所有事件,以便您可以同时获得多个更新。因为在填写图像时您没有检查轮到谁,所以您可以一次填写多个十字或圆圈。
为什么会这样:
elif event.type == MOUSEBUTTONUP:
mouseClick = True
mouseX, mouseY = event.pos
在循环中mouseClick
第一次被设置为True
,但是因为队列中有多个事件,event.get()有另一个要处理的元素,这次它运行mouseclick
再次循环为True。但是这次我们仍然处于循环中,因为event.get()
是一个多于一个的列表,所以:
elif event.type == MOUSEMOTION:
mouseX, mouseY = event.pos
现在执行此操作,但是mouseClick
在处理此问题时错误地True
,所以我们再次落入另一个声明中,这不是您想要的。
答案 1 :(得分:0)
如果有人有兴趣找到答案,或者只是有一个类似的问题,那么我改变后的代码(它现在有效,感谢答案班车87)
import pygame
import sys
from pygame.locals import *
DISPLAY_WIDTH = 400
DISPLAY_HEIGHT = 400
BOX_SIZE = 50
BOARD_WIDTH = 3
BOARD_HEIGHT = 3
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BACKGROUND_COLOR = (198, 187, 133)
indexList = ["a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3"]
gameFinished = False
def game_loop():
global DISPLAY_WIDTH, DISPLAY_HEIGHT, displaySurface, gameFinished
pygame.init()
FPSCLOCK = pygame.time.Clock()
displaySurface = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
pygame.display.set_caption("Tic Tac Toe")
displaySurface.fill(BACKGROUND_COLOR)
pygame.draw.line(displaySurface, BLACK, (140, 20), (140, 380), 10)
pygame.draw.line(displaySurface, BLACK, (260, 20), (260, 380), 10)
pygame.draw.line(displaySurface, BLACK, (20, 140), (380, 140), 10)
pygame.draw.line(displaySurface, BLACK, (20, 260), (380, 260), 10)
box1 = pygame.Rect(20, 20, 120, 120)
box2 = pygame.Rect(140, 20, 120,120)
box3 = pygame.Rect(260, 20, 120, 120)
box4 = pygame.Rect(20, 140, 120, 120)
box5 = pygame.Rect(140, 140, 120, 120)
box6 = pygame.Rect(260, 140, 120, 120)
box7 = pygame.Rect(20, 260, 120, 120)
box8 = pygame.Rect(140, 260, 120, 120)
box9 = pygame.Rect(260, 260, 120, 120)
circle = pygame.image.load("circle.png")
cross = pygame.image.load("cross.png")
boardBoxes = [box1, box2, box3, box4, box5, box6, box7, box8, box9]
mouseY = 0
mouseX = 0
placesTaken = {0: False, 1: False, 2: False, 3: False, 4: False, 5: False, 6: False, 7: False, 8: False}
turn = 1
board = generate_boxes(0)
print(repr(board))
while not gameFinished:
moveDone = False
mouseClick = False
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == MOUSEBUTTONUP:
mouseClick = True
mouseX, mouseY = event.pos
if mouseClick is True and turn == 1 and moveDone == False:
get_mouse_overbox(mouseX, mouseY, boardBoxes, turn, board)
print("Player1")
moveDone = True
elif mouseClick is True and turn == 2 and moveDone == False:
get_mouse_overbox(mouseX, mouseY, boardBoxes, turn, board)
print("Player2")
moveDone = True
if board[0] == 1 and placesTaken[0] is False:
put_image(circle, 20, 20)
placesTaken[0] = True
turn += 1
elif board[0] == 2 and placesTaken[0] is False:
put_image(cross, 20, 20)
placesTaken[0] = True
turn -= 1
if board[1] == 1 and placesTaken[1] is False:
put_image(circle, 140, 20)
placesTaken[1] = True
turn += 1
elif board[1] == 2 and placesTaken[1] is False:
put_image(cross, 140, 20)
placesTaken[1] = True
turn -= 1
if board[2] == 1 and placesTaken[2] is False:
put_image(circle, 260, 20)
placesTaken[2] = True
turn += 1
elif board[2] == 2 and placesTaken[2] is False:
put_image(cross, 260, 20)
placesTaken[2] = True
turn -= 1
if board[3] == 1 and placesTaken[3] is False:
put_image(circle, 20, 140)
placesTaken[3] = True
turn += 1
elif board[3] == 2 and placesTaken[3] is False:
put_image(cross, 20, 140)
placesTaken[3] = True
turn -= 1
if board[4] == 1 and placesTaken[4] is False:
put_image(circle, 140, 140)
placesTaken[4] = True
turn += 1
elif board[4] == 2 and placesTaken[4] is False:
put_image(cross, 140, 140)
placesTaken[4] = True
turn -= 1
if board[5] == 1 and placesTaken[5] is False:
put_image(circle, 260, 140)
placesTaken[5] = True
turn += 1
elif board[5] == 2 and placesTaken[5] is False:
put_image(cross, 260, 140)
placesTaken[5] = True
turn -= 1
if board[6] == 1 and placesTaken[6] is False:
put_image(circle, 20, 260)
placesTaken[6] = True
turn += 1
elif board[6] == 2 and placesTaken[6] is False:
put_image(cross, 20, 260)
placesTaken[6] = True
turn -= 1
if board[7] == 1 and placesTaken[7] is False:
put_image(circle, 140, 260)
placesTaken[7] = True
turn += 1
elif board[7] == 2 and placesTaken[7] is False:
put_image(cross, 140, 260)
placesTaken[7] = True
turn -= 1
if board[8] == 1 and placesTaken[8] is False:
put_image(circle, 260, 260)
placesTaken[8] = True
turn += 1
elif board[8] == 2 and placesTaken[8] is False:
put_image(cross, 260, 260)
placesTaken[8] = True
turn -= 1
FPSCLOCK.tick(60)
pygame.display.update()
def get_mouse_overbox(mouse_x, mouse_y, box_list, which_turn, boardlist):
if which_turn == 1:
for counter in range(len(box_list)):
if box_list[counter].collidepoint(mouse_x, mouse_y) and which_turn == 1:
boardlist[counter] = 1
elif which_turn == 2:
for caunter in range(len(box_list)):
if box_list[caunter].collidepoint(mouse_x, mouse_y) and which_turn == 2:
boardlist[caunter] = 2
def put_image(image_name, x_cord, y_cord):
global displaySurface
displaySurface.blit(image_name, (x_cord, y_cord))
def generate_boxes(value):
boxesFilled = []
for i in range(9):
boxesFilled.append(value)
return boxesFilled
def board_getcircles(board):
onlyCircleBoard = [0 if i == 2 else i for i in board]
return onlyCircleBoard
def board_getcrosses(board):
onlyCrossBoard = [0 if i == 2 else i for i in board]
return onlyCrossBoard
game_loop()
作为我所做的一个简短的总结,我将if句子的质量移动到循环中的for事件中,并使得当图片实际放在桌子上而不是这样做时,转弯增加或减少1当玩家点击时我做的另一件事是我添加了一个moveDone变量,它跟踪是否已经在当前循环中启动了更改板状态(get_mouse_overbox)的函数。希望这有助于某人,并再次感谢帮助shuttle87