Как получить список из метода min () в python?

Я пытаюсь узнать pygame и python, сделав несколько простых щелкающих игр, и следующая программа, которую я сделал, рисует сетку, и когда я нажимаю на любую коробку в сетке, она меняет свой цвет. Но это ограничено одним полем на клик.

То, что я пытаюсь сделать,-это раскрасить кликнутую коробку и все другие коробки с похожими координатами x или координатами y, координатами x и y, означающими <rect(x, y, 70, 90)>x-y в pygame.Прямоугольник

Вот мой код со всеми соответствующими функциями.

import pygame as pg
import sys

window_width = 720
window_height = 360
window_res = window_width, window_height

cover_width = 70
cover_height = 90

gap_x = 70
gap_y = 90

red = (225, 25, 30)
bkg_colour = (30, 30, 30)
off_white = (180, 180, 180)
magenta = (225, 25, 25)


def get_rekt():
    init_x = int((window_width % gap_x) / 2)
    init_y = 20

    rect_list = []
    for x in range(init_x, window_width - gap_x, gap_x):
        for y in range(init_y, window_height - gap_y, gap_y):
            rect = pg.Rect(x, y, cover_width, cover_height)
            rect_list.append(rect)

    return rect_list


def draw_grid(rect_list):
    for rect in rect_list:
        pg.draw.rect(display, red, rect, 3)


def get_grid():
    return draw_grid(get_rekt())


def get_closest_rect(rect_list, click_pos):
    closest_rect = min(rect_list, key=lambda x: abs(x.centerx - click_pos[0]) + abs(x.centery - click_pos[1]))
    return closest_rect


def main():
    pg.init()

    global display, fps_clock

    display = pg.display.set_mode(window_res)
    display.fill(bkg_colour)
    draw_grid(get_rekt())
    pg.display.flip()

    while True:

        for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()
                sys.exit()

            if pg.mouse.get_pressed()[0]:
                click_pos = pg.mouse.get_pos()
                rect_list = get_rekt()
                closest_rect = get_closest_rect(rect_list, click_pos)
                pg.draw.rect(display, off_white, closest_rect, 3)
                pg.display.flip()
                print(closest_rect)


if __name__ == '__main__':
    main()

Это функция, которая возвращает ближайший rect к тому месту, где я щелкнул. Я использую метод min () с лямбда-ключом.

def get_closest_rect(rect_list, click_pos):
    closest_rect = min(rect_list, key=lambda x: abs(x.centerx - click_pos[0]) + abs(x.centery - click_pos[1]))
    return closest_rect

Вот как это выглядит, когда я щелкаю в поле

Введите описание изображения здесь

И то, что я ищу, это

Введите описание изображения здесь

Что я думал, если эта функция

def get_closest_rect(rect_list, click_pos):
        closest_rect = min(rect_list, key=lambda x: abs(x.centerx - click_pos[0]) + abs(x.centery - click_pos[1]))
        return closest_rect

мог бы вернуть список rect с похожими координатами x или y, я мог бы запустить этот список в цикле for с pg.нарисуйте и сделайте то, что вы можете увидеть на втором изображении.

2 ответа

  1. Эта функция должна сделать трюк.

    def get_closest_rects(rect_list, click_pos):
      return filter(lambda r: r.left <= click_pos[0] <= r.right or r.top <= click_pos[1] <= r.bottom, rect_list)
    

    filter(function, iterable) возвращает список элементов из iterable, для которых функция возвращает True.

    Чтобы получить прямоугольники выше и ниже курсора, мы просто должны проверить, находится ли курсор между левой и правой границами каждого прямоугольника. Для тех, кто слева и справа, мы должны проверить верхнюю и нижнюю границы.

    Если вы замените логическую orоперацию на anand,вы получите только один прямоугольник, который вы щелкнули.

  2. Использовать его:

                if pg.mouse.get_pressed()[0]:
                click_pos = pg.mouse.get_pos()
                rect_list = get_rekt()
                closest_rect = get_closest_rect(rect_list, click_pos)
                linex = 10
                liney = 20
                for i in range(0,10):#x axis
                    newRect=pg.Rect(linex, closest_rect.y, cover_width, cover_height)
                    pg.draw.rect(display, off_white, newRect, 3)
                    linex = linex + 70
    
                for j in range(0,3):
                    newRect = pg.Rect(closest_rect.x, liney, cover_width, cover_height)
                    pg.draw.rect(display, off_white, newRect, 3)
                    liney = liney + 90
    
                pg.display.flip()