在pygame中处理具有负宽度和高度的矩形

问题描述

我试图制作一个区域选择功能,您可以按住鼠标左键并移动鼠标,它会生成一个矩形,并且该矩形内的所有内容都被选中。

import pygame
import time

window = pygame.display.set_mode((1200,600))
thickest = 10
begin = False

while True:
    pygame.event.get()
    window.fill((255,255,255))

    if any(pygame.mouse.get_pressed()) and not begin:
        rpos = pygame.mouse.get_pos()
        begin = True

    if begin:
        pos2 = pygame.mouse.get_pos()
        pygame.draw.rect(window,(100,200,100),(rpos[0],rpos[1],pos2[0] - rpos[0],pos2[1] - rpos[1]),1)

    if not any(pygame.mouse.get_pressed()) and begin:
        begin = False
    
    pygame.display.flip()

但是,我注意到根本没有绘制负高度的矩形,负宽度的矩形甚至都不是矩形。

我想到的一件事是按大小偏移位置并将大小作为大小的绝对值。 x 轴示例:

if pos2[0] - rpos[0] < 0:
    pygame.draw.rect(window,(rpos[0] - (pos2[0] - rpos[0]),abs(pos2[0] - rpos[0]),pos2[1] - rpos[1]))

但是这种方法看起来并不优雅,我想知道是否有更 pygame-ey 的方法来处理这个问题。

解决方法

使用 min 计算矩形的左上角,使用 abs 计算矩形的宽度和高度:

rect = (
    min(pos2[0],rpos[0]),min(pos2[1],rpos[1]),abs(pos2[0]-rpos[0]),abs(pos2[1]-rpos[1])
)
pygame.draw.rect(window,(100,200,100),rect)

绘制一个未填充的矩形

rect = (
    min(pos2[0],max(2,abs(pos2[0]-rpos[0])),abs(pos2[1]-rpos[1])),)        
pygame.draw.rect(window,rect,1)

pygame.Rect.normalize() 为这个问题提供了更优雅的解决方案:

normalize() -> None
如果矩形的大小为负,这将翻转矩形的宽度或高度。矩形将保留在同一位置,仅交换边。

创建一个 pygame.Rect 对象并normalize 它:

rect = pygame.Rect(rpos[0],rpos[1],pos2[0]-rpos[0],pos2[1]-rpos[1])
rect.normalize()
pygame.draw.rect(window,rect)