首页 > 解决方案 > 绘制宽度较小的 pygame 矩形

问题描述

我正在通过 pygame 制作数独求解器,并且我已经能够绘制整个棋盘,但是,在编写处理单击图块的代码部分时,我这样做是为了使当前图块“亮起”绿色,因此用户可以知道当前的磁贴。但是,当用户决定单击不同的图块时,我一直在弄清楚如何绘制绿色突出显示的部分。我想完全删除该部分,但由于它是一个厚度为 4 的矩形,而基础瓷砖的厚度为 1,我所做的只是在粗绿线上有一条难看的黑线。我尝试重新绘制整个电路板,但我得到了类似的结果。有什么帮助吗?

class Tile:
    '''Represents each white tile/box on the grid'''
    def __init__(self, value, window, x1, x2):
        self.value = value #value of the num on this grid
        self.window = window
        self.active = False
        self.rect = pygame.Rect(x1, x2, 60, 60) #dimensions for the rectangle

    def draw(self, color, thickness):
        '''Draws a tile on the board'''
        pygame.draw.rect(self.window, color, self.rect, thickness)
        pygame.display.flip()

def main():
    board = Board(screen)
    tiles = board.draw_board() #store the locations of all the tiles on the grid

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

                        elif event.type == pygame.MOUSEBUTTONUP:
                mousePos = pygame.mouse.get_pos()
                #board.draw_board() or (see next comment)
                for i in range(9):
                    for j in range (9): #look for tile we clicked on
                        #tiles[i][j].draw((0,0,0),1)
                        #yield same results
                        if tiles[i][j].is_clicked(mousePos):
                            tiles[i][j].draw((50,205,50),4) #redraws that tile but with a highlighted color to show it's been clicked
                            break

main()

画图不行!

标签: pythonpygamedrawing

解决方案


您可以简单地将突出显示的图块存储在变量中。我也认为你根本不需要Tile上课,因为数独游戏状态基本上只是一个数字列表。

这是一个简单的例子。注意评论:

import random
import pygame

TILE_SIZE = 64

# function to draw the grid
def draw_board():
    board_surface = pygame.Surface((9*TILE_SIZE, 9*TILE_SIZE))
    board_surface.fill((255, 255, 255))
    for x in range(9):
        for y in range(9):
            rect = pygame.Rect(x*TILE_SIZE, y*TILE_SIZE, TILE_SIZE, TILE_SIZE)
            pygame.draw.rect(board_surface, (0, 0, 0), rect, 1)
    pygame.draw.line(board_surface, (0, 0, 0), (0, 3*TILE_SIZE), (9*TILE_SIZE, 3*TILE_SIZE), 5)
    pygame.draw.line(board_surface, (0, 0, 0), (0, 6*TILE_SIZE), (9*TILE_SIZE, 6*TILE_SIZE), 5)
    pygame.draw.line(board_surface, (0, 0, 0), (3*TILE_SIZE, 0), (3*TILE_SIZE, 9*TILE_SIZE), 5)
    pygame.draw.line(board_surface, (0, 0, 0), (6*TILE_SIZE, 0), (6*TILE_SIZE, 9*TILE_SIZE), 5)
    return board_surface

def main():

    # standard pygame setup
    pygame.init()
    clock = pygame.time.Clock()
    screen = pygame.display.set_mode((9*TILE_SIZE, 9*TILE_SIZE))
    font = pygame.font.SysFont(None, 40)
    
    # seperate the game state from the UI
    # create a dummy 9x9 sudoku board
    state = [[None for _ in range(10)] for _ in range(10)]
    for _ in range(15):
        x = random.randint(0, 9)
        y = random.randint(0, 9)
        state[y][x] = random.randint(1, 9)

    # a variable to hold the selected tile's position on the board 
    # (from 0,0 to 8,8)
    selected = None

    # create the grid surface ONCE and reuse it to clear the screen
    board_surface = draw_board()
    
    while True:

        for event in pygame.event.get():
            pos = pygame.mouse.get_pos()
            if event.type == pygame.QUIT:
                return
                
            # when the player clicks on a tile
            # we translate the screen coordinates to the board coordinates
            # e.g. a pos of (140, 12) is the tile at (2, 0)
            if event.type == pygame.MOUSEBUTTONDOWN:
                w_x, w_y = event.pos
                selected = w_x // TILE_SIZE, w_y // TILE_SIZE

        # clear everything by blitting the grid surface to the screen
        screen.blit(board_surface, (0, 0))
        
        # print all numbers in the state to the screen
        # we use a Rect here so we can easily center the numbers
        rect = pygame.Rect(0, 0, TILE_SIZE, TILE_SIZE)
        for line in state:
            for tile in line:
                if tile != None:
                    tmp = font.render(str(tile), True, (0, 0, 0))
                    screen.blit(tmp, tmp.get_rect(center=rect.center))
                rect.move_ip(TILE_SIZE, 0)
            rect.x = 0
            rect.move_ip(0, TILE_SIZE)

        # if a tile is selected, we calculate the world coordinates from the board coordinates
        # and draw a simple green rect
        if selected:
            rect = pygame.Rect(selected[0] * TILE_SIZE, selected[1] * TILE_SIZE, TILE_SIZE, TILE_SIZE)
            pygame.draw.rect(screen, (0, 200, 0), rect, 5)

        clock.tick(30)
        pygame.display.flip()
main()

在此处输入图像描述

此外,您不应该pygame.display.flip()在主循环之外调用。它可能会导致闪烁或图像无法正确显示等效果。


推荐阅读