我有两个列表,每个列表包含3个rects。我可以分配给每个列表中的selected1和selected2 3个变量并分别上下移动这两行rects,同时保持它们之间的间隙吗?我是初学者,不知道这样构造的代码是否可以处理这个任务。
import pygame
# === CONSTANS ===
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
blue = (0, 0, 255)
green = (0, 102, 0)
yellow = (255, 204, 0)
grid_color = (224, 224, 224)
width = 1200
height = 720
k = 10
screen = pygame.display.set_mode((width, height))
screen_rect = screen.get_rect()
# --- objects ---
G_x = 10 # stripe width
x = 2
stripes_x1 = []
stripes_x2 = []
G1_pos_x = 122
G2_pos_x = 367
G1_pos_y = 0
G2_pos_y = 0
G1_y = 60*x
G2_y = 75*x
G1_start = G1_pos_y + height - G1_y
G2_start = G2_pos_y + height - G2_y
a = 166
b = 222
for x in range(3):
gap = a*x
gap2 = b*x
stripes_x1.append(pygame.Rect(G1_pos_x, (G1_start - 6*k) - gap, G_x, G1_y))
stripes_x2.append(pygame.Rect(G2_pos_x, (G2_start - 6*k) - gap2, G_x, G2_y))
selected1 = None
selected2 = None
# --- mainloop ---
clock = pygame.time.Clock()
is_running = True
while is_running:
for event in pygame.event.get():
# --- global events ---
if event.type == pygame.QUIT:
is_running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
is_running = False
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
for i, r in enumerate(stripes_x1):
if r.collidepoint(event.pos):
selected1 = i
selected_offset_y = r.y - event.pos[1]
if event.type == pygame.MOUSEMOTION:
if selected1 is not None: # selected can be `0` so `is not None` is required
stripes_x1[selected1].y = event.pos[1] + selected_offset_y
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
selected1 = None
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
for j, r in enumerate(stripes_x2):
if r.collidepoint(event.pos):
selected2 = j
selected_offset_y = r.y - event.pos[1]
if event.type == pygame.MOUSEMOTION:
if selected2 is not None: # selected can be `0` so `is not None` is required
stripes_x2[selected2].y = event.pos[1] + selected_offset_y
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
selected2 = None
# --- objects events ---
'''
button.handle_event(event)
'''
# --- updates ---
# empty
# --- draws ---
screen.fill(white)
for i in range(width):
grid_x = k * i
grid_y = k * i
pygame.draw.line(screen, grid_color, (grid_x, 0), (grid_x, height), 1)
pygame.draw.line(screen, grid_color, (0, grid_y), (width, grid_y), 1)
pygame.draw.line(screen, black, (6 * k, height - 6 * k), (width - 6 * k, height - 6 * k), 3)
pygame.draw.line(screen, black, (6 * k, height - 6 * k), (6 * k, 0 * k), 3)
# draw rect
for r in stripes_x1:
pygame.draw.rect(screen, green, r)
for s in stripes_x2:
pygame.draw.rect(screen, green, s)
pygame.display.update()
clock.tick(60)
pygame.quit()
答案 0 :(得分:1)
要同时移动rects,可以将它们放在一个列表中,如果选择了一个rect,则可以借助MOUSEMOTION事件的rel
属性(最后一个鼠标的相对位置)将它们全部移动事件)。这是一个最小的例子:
import sys
import pygame as pg
BLACK = pg.Color('black')
RECT_COLOR = pg.Color(78, 140, 200)
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
rect_list = [pg.Rect(100, 100+y, 20, 80) for y in range(0, 241, 120)]
selected = False
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEBUTTONDOWN:
for rect in rect_list:
if rect.collidepoint(event.pos):
selected = True
elif event.type == pg.MOUSEBUTTONUP:
selected = False
elif event.type == pg.MOUSEMOTION:
if selected:
for rect in rect_list:
rect.y += event.rel[1]
screen.fill(BLACK)
for rect in rect_list:
pg.draw.rect(screen, RECT_COLOR, rect)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()