Можно ли обновить атрибут рисования пигмеев, когда происходит событие? - PullRequest
1 голос
/ 02 мая 2020

Я подхожу к PyGame, но у меня возникла проблема: я пытаюсь нарисовать сетку, состоящую из рисунков из одного прямоугольника, я хочу, чтобы каждый из этих прямоугольников заполнялся или очищался, когда левая кнопка мыши отпущена на указанном прямоугольнике. , Сетка i представлена ​​матрицей кортежей, каждый из которых представляет каждый прямоугольник, отформатированный таким образом (столбец, строка), чтобы он соответствовал координатам пикселя пигмея, затем я создаю другую матрицу кортежей для преобразования из кортежей позиции мыши (colpixel, rowpixel) в Кортежи прямоугольников, я также создал словарь, который объединяет кортежи прямоугольников в качестве ключей со значением, которое может быть 1 или 0, это значение представляет, заполнен ли прямоугольник или нет, это значение, которое я изменяю при отпускании кнопки мыши. Вот код:

import pygame

pygame.init()

SCREEN_WIDTH = 40
SCREEN_HEIGHT = 20

DIM = 20

ROWS = int(SCREEN_HEIGHT / DIM)
COLUMNS = int(SCREEN_WIDTH / DIM)


screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

pygame.display.set_caption('Game of Life')


# filling rect_matrix with tuple, each one representing a rectangle of the grid (columns, rows).
# filling rect_map by pairing the tuples from rect_matrix with a value that can be 0 or 1, default 1.
rect_matrix = []
rect_map = {}

for i in range(ROWS):
    temp = []
    for j in range(COLUMNS):
        temp.append(pygame.Rect((j * DIM, i * DIM), (DIM, DIM)))
        rect_map[(j, i)] = 1
    rect_matrix.append(temp)


# filling mouse_to_rectangle, sort of a decoder to convert from groups of tuples
# (representing mouse coordinates in pixels) to a single tuple (representing single rectangles)
mouse_to_rectangle = []

ii = 0
for i in range(SCREEN_WIDTH):
    jj = 0
    temp = []
    for j in range(SCREEN_HEIGHT):
        temp.append((ii, jj))
        if ((j + 1) % DIM == 0):
            jj += 1
    if ((i + 1) % DIM == 0):
        ii += 1
    mouse_to_rectangle.append(temp)


is_running = True

while is_running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            is_running = False
            pygame.quit()
            exit()
        if event.type == pygame.MOUSEBUTTONUP:

            if rect_map[mouse_to_rectangle[pygame.mouse.get_pos()[0]][pygame.mouse.get_pos()[1]]] == 1:
                rect_map[mouse_to_rectangle[pygame.mouse.get_pos()[0]][pygame.mouse.get_pos()[1]]] = 0
            else:
                rect_map[mouse_to_rectangle[pygame.mouse.get_pos()[0]][pygame.mouse.get_pos()[1]]] = 1



    for i, ii in zip(rect_matrix, range(len(rect_matrix))):
        for j, jj in zip(i, range(len(i))):
            pygame.draw.rect(screen, (100, 100, 100), j, rect_map[(jj, ii)])

    pygame.display.update()

Мне удалось заполнить (относительное значение в rect_map равно 1) прямоугольник при отпускании левой кнопки при ее наведении, но при попытке снова щелкнуть по прямоугольнику, который сейчас заполнено не пусто Я представил свойство «заполнено или нет» единицами или нулями, потому что прямоугольник заполняется, когда параметр width в pygame.draw.rect установлен в 0, если используется значение >0, то у прямоугольника будет толстая граница как указанное значение в пикселях.

1 Ответ

1 голос
/ 02 мая 2020

Вы пропустили очистку дисплея перед рисованием сетки. Таким образом, все прямоугольники, которые были нарисованы, остались там навсегда:

screen.fill((0, 0, 0))

В любом случае, вы слишком усложнили алгоритм. Положение в размоле может быть вычислено путем деления компонентов положения мыши на DIM (// (оператор деления по полу)):

mousepos = pygame.mouse.get_pos()
gridpos = mousepos[0] // DIM, mousepos[1] // DIM

Наконец, это состояние сетки можно легко изменить и mouse_to_rectangle не требуется вообще:

if rect_map[gridpos] == 1:
    rect_map[gridpos] = 0
else:
    rect_map[gridpos] = 1

См. пример:

import pygame

pygame.init()

SCREEN_WIDTH = 200
SCREEN_HEIGHT = 200

DIM = 20

ROWS = int(SCREEN_HEIGHT / DIM)
COLUMNS = int(SCREEN_WIDTH / DIM)

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Game of Life')

# filling rect_matrix with tuple, each one representing a rectangle of the grid (columns, rows).
# filling rect_map by pairing the tuples from rect_matrix with a value that can be 0 or 1, default 1.
rect_matrix = []
rect_map = {}

for i in range(ROWS):
    temp = []
    for j in range(COLUMNS):
        temp.append(pygame.Rect((j * DIM, i * DIM), (DIM, DIM)))
        rect_map[(j, i)] = 1
    rect_matrix.append(temp)

is_running = True

while is_running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            is_running = False
            pygame.quit()
            exit()
        if event.type == pygame.MOUSEBUTTONUP:

            mousepos = pygame.mouse.get_pos()
            gridpos = mousepos[0] // DIM, mousepos[1] // DIM
            if rect_map[gridpos] == 1:
                rect_map[gridpos] = 0
            else:
                rect_map[gridpos] = 1

    screen.fill((0, 0, 0))

    for i, ii in zip(rect_matrix, range(len(rect_matrix))):
        for j, jj in zip(i, range(len(i))):
            pygame.draw.rect(screen, (100, 100, 100), j, rect_map[(jj, ii)])

    pygame.display.update()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...