I'm building a chess gui using pygame, in which the main game loop calls a method in a seperate class (Move in GameState class), which then further calls another method in the same class(pawn_promotion). In the pawn_promotion method, a surface, promotion_menu, is being blit into the window.
But it only appears on screen for one frame. Please correct me if I'm wrong here but what I think is happening is that the surface is being blit but when the game loop iterates again it gets covered up with the chess board being blit onto to the window.
class GameWindow:
def __init__(self):
load()
gs = GameState()
m = MoveList
run = True
square_selected = ()
clicks = []
while run:
win.blit(board_surface, (467, 132))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
MainMenu()
run = False
# Mouse ui
if event.type == pygame.MOUSEBUTTONDOWN: # checking for clicks
location = (pygame.mouse.get_pos()[0] - 467, pygame.mouse.get_pos()[1] - 132)
if 600 >= location[0] >= 0 and 600 >= location[1] >= 0:
column = location[0] // Square_size
row = location[1] // Square_size
# checking for repeat clicks
if square_selected == (row, column):
square_selected = ()
clicks = [] # if click is repeat, clear previous click
else:
# Player selects a square
square_selected = (row, column)
clicks.append(square_selected)
if len(clicks) == 2:
# second click moves the piece
self.move = m(clicks[0], clicks[1], gs.board)
gs.Move(self.move)
square_selected = ()
clicks = []
if gs.close_window:
run = False
class GameState:
...irrelavant code...
def pawn_promotion(self, move):
print(move.endrow, move.endcol)
self.is_prmt = True
promotion_menu = pygame.Surface((int(Square_size), int(Square_size * 4)))
promotion_menu.fill(white)
prmt_confirm = ''
if self.white_turn:
prmt_white_queen = Button(board_surface, (move.endcol + 1) * Square_size, 50, pieces_dict['wQ'], 1)
prmt_white_rook = Button(board_surface, (move.endcol + 1) * Square_size, 50 + Square_size,
pieces_dict['wR'], 1)
prmt_white_knight = Button(board_surface, (move.endcol + 1) * Square_size, 50 + (2 * Square_size),
pieces_dict['wN'], 1)
prmt_white_bishop = Button(board_surface, (move.endcol + 1) * Square_size, 50 + (3 * Square_size),
pieces_dict['wB'], 1)
if self.run_promote_menu:
print(self.run_promote_menu)
board_surface.blit(promotion_menu, ((move.endcol + 1) * Square_size, (move.endrow * Square_size) + 50))
prmt_queen = Button.draw(prmt_white_queen)
prmt_rook = Button.draw(prmt_white_rook)
prmt_knight = Button.draw(prmt_white_knight)
prmt_bishop = Button.draw(prmt_white_bishop)
if prmt_queen:
prmt_confirm = 'wQ'
# run_promote_menu = False
if prmt_rook:
prmt_confirm = 'wR'
# run_promote_menu = False
if prmt_knight:
prmt_confirm = 'wN'
# run_promote_menu = False
if prmt_bishop:
prmt_confirm = 'wB'
# run_promote_menu = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.run_promote_menu = False
close_window = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_z:
self.run_promote_menu = False
if prmt_confirm != '':
self.run_promote_menu = False
self.board[move.endrow][move.endcol] = prmt_confirm
pygame.display.update()
I'm creating 4 buttons on the surface using the following class
class Button:
def __init__(self, surface, x, y, image, scale):
image_width = image.get_width()
image_height = image.get_height()
self.image = pygame.transform.scale(image, (int(image_width * scale), int(image_height * scale)))
self.image_rect = image.get_rect(topleft=(x, y))
self.surface = surface
self.clicked = False
self.image_bg = pygame.Surface((self.image_rect.width + 10, self.image_rect.height + 5))
self.image_bg.set_alpha(0)
def draw(self):
action = False
pos = pygame.mouse.get_pos()
if self.image_rect.collidepoint(pos):
self.image_bg.set_alpha(1)
for event in pygame.event.get():
if pygame.mouse.get_pressed()[0] == 1 and not self.clicked:
self.clicked = True
action = True
if pygame.mouse.get_pressed()[1] == 0:
self.clicked = False
else:
self.image_bg.set_alpha(0)
self.surface.blit(self.image_bg, (self.image_rect.x - 5, self.image_rect.y))
self.surface.blit(self.image, (self.image_rect.x, self.image_rect.y))
return action
I'm having another small issue with this class, the set_alpha() lines seem to be increasing value of alpha each frame rather than setting it to a constant value. Is there another command for keeping alpha constant?
If I use a while loop inside pawn_promotion, it works perfectly but since it's essentially two nested while loops, it creates a lot of lag. I tried to reduce this lag by using clock.tick() but it doesn't get rid of it entirely.