Pygame - 在单击并拖动其中一个的同时移动两个对象
Pygame - move two objects while clicking and dragging one of them
我必须能够通过单击并拖动其中之一来移动绿色和红色(一对),同时保持它们彼此的相对位置。我不确定如何使用我已有的代码来完成它。我应该为红色矩形创建另一个 class 还是使用 Parent Child classes?非常感谢帮助。
import pygame as pg
WHITE = (255, 255, 255)
GREEN = (33, 133, 33)
RED = (255, 0, 0)
SCREEN = pg.display.set_mode((700, 500))
clock = pg.time.Clock()
cT = 140 # cycle time
cNum = 3 # cyle number
class Rectangle(pg.sprite.Sprite):
def __init__(self, color, width, height, x, y):
super().__init__()
self.height = height
self.color = color
self.image = pg.Surface((width, height))
self.image.fill(color)
self.rect = self.image.get_rect(topleft=(x, y))
def move(self, rel_x, rel_y):
self.rect.move_ip(rel_x, rel_y)
def collidepoint(self, pos):
return self.rect.collidepoint(pos)
class Rect1():
def __init__(self, color, width, height, x, y, all_sprites):
self.height = height
self.selected1 = False
self.rect = pg.Rect((x, y, width, height))
self.rectangles = []
for z in range(0, cNum * cT, cT):
rect = Rectangle(color, width, height, x, self.rect.y - z + cT)
self.rectangles.append(rect)
all_sprites.add(rect)
def move(self, rel_x, rel_y):
self.rect.move_ip(rel_x, rel_y)
for r in self.rectangles:
r.move(rel_x, rel_y)
def collidepoint(self, pos):
for r in self.rectangles:
if r.rect.collidepoint(pos):
return True
def handle_event(self, event):
if event.type == pg.MOUSEBUTTONDOWN:
if self.collidepoint(event.pos):
self.selected1 = True
elif event.type == pg.MOUSEBUTTONUP:
self.selected1 = False
elif event.type == pg.MOUSEMOTION:
if self.selected1 :
self.move(0, event.rel[1])
class Connection():
def __init__(self, rect_1, rect_2, vel):
self.rect_1 = rect_1
self.rect_2 = rect_2
self.vel = vel
def draw(self, screen):
for r_1 in self.rect_1.rectangles:
for r_2 in self.rect_2.rectangles:
dist1 = r_2.rect.x - r_1.rect.x
velocity = int(dist1 * self.vel) # green wave angle
A_start_x, A_start_y = r_1.rect.topright
A_end_x, A_end_y = r_1.rect.bottomright
B_start_x, B_start_y = r_2.rect.topleft
B_end_x, B_end_y = r_2.rect.bottomleft
if B_start_y < A_start_y - velocity and B_end_y > A_start_y - velocity:
start_pos = (A_start_x, A_start_y)
end_pos = (B_start_x, A_start_y - velocity) # minus 50
pg.draw.aaline(screen, GREEN, start_pos, end_pos, 1)
if B_end_y > A_end_y - velocity and B_start_y < A_end_y - velocity:
start_pos = (A_end_x, A_end_y-1)
end_pos = (B_end_x, A_end_y - 1 - velocity) # minus 50
pg.draw.aaline(screen, RED, start_pos, end_pos, 1)
def main():
pg.init()
all_sprites = pg.sprite.Group()
objects = [
Rect1(GREEN, 10, 58, 55, 244, all_sprites ),
Rect1(GREEN, 10, 111, 188, 226, all_sprites ),
Rect1(RED, 10, 68, 69, 222, all_sprites),
Rect1(RED, 10, 121, 211, 202, all_sprites),]
conns = [
Connection(objects[0], objects[1], 0.1),
Connection(objects[2], objects[3], -0.1),]
done = False
clock = pg.time.Clock()
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
for o in objects:
o.handle_event(event)
SCREEN.fill(WHITE)
all_sprites.draw(SCREEN)
for c in conns:
c.draw(SCREEN)
pg.display.update()
clock.tick(60)
pg.quit()
if __name__ == '__main__':
main()
您可以通过将对另一个矩形的引用存储为属性(例如 self.associated
)来关联矩形,然后在 handle_event
方法中更新关联的矩形:self.associated.move(0, event.rel[1])
class Rect1():
def __init__(self, color, width, height, x, y, all_sprites, associated=None):
self.associated = associated
# Snip ...
def handle_event(self, event):
# Snip ...
elif event.type == pg.MOUSEMOTION:
if self.selected1 :
self.move(0, event.rel[1])
self.associated.move(0, event.rel[1])
def main():
# Snip ...
green_short = Rect1(GREEN, 10, 58, 55, 244, all_sprites)
red_short = Rect1(RED, 10, 68, 69, 222, all_sprites, green_short)
green_short.associated = red_short
green_long = Rect1(GREEN, 10, 111, 188, 226, all_sprites)
red_long = Rect1(RED, 10, 121, 211, 202, all_sprites, green_long)
green_long.associated = red_long
objects = [green_short, green_long, red_short, red_long]
我必须能够通过单击并拖动其中之一来移动绿色和红色(一对),同时保持它们彼此的相对位置。我不确定如何使用我已有的代码来完成它。我应该为红色矩形创建另一个 class 还是使用 Parent Child classes?非常感谢帮助。
import pygame as pg
WHITE = (255, 255, 255)
GREEN = (33, 133, 33)
RED = (255, 0, 0)
SCREEN = pg.display.set_mode((700, 500))
clock = pg.time.Clock()
cT = 140 # cycle time
cNum = 3 # cyle number
class Rectangle(pg.sprite.Sprite):
def __init__(self, color, width, height, x, y):
super().__init__()
self.height = height
self.color = color
self.image = pg.Surface((width, height))
self.image.fill(color)
self.rect = self.image.get_rect(topleft=(x, y))
def move(self, rel_x, rel_y):
self.rect.move_ip(rel_x, rel_y)
def collidepoint(self, pos):
return self.rect.collidepoint(pos)
class Rect1():
def __init__(self, color, width, height, x, y, all_sprites):
self.height = height
self.selected1 = False
self.rect = pg.Rect((x, y, width, height))
self.rectangles = []
for z in range(0, cNum * cT, cT):
rect = Rectangle(color, width, height, x, self.rect.y - z + cT)
self.rectangles.append(rect)
all_sprites.add(rect)
def move(self, rel_x, rel_y):
self.rect.move_ip(rel_x, rel_y)
for r in self.rectangles:
r.move(rel_x, rel_y)
def collidepoint(self, pos):
for r in self.rectangles:
if r.rect.collidepoint(pos):
return True
def handle_event(self, event):
if event.type == pg.MOUSEBUTTONDOWN:
if self.collidepoint(event.pos):
self.selected1 = True
elif event.type == pg.MOUSEBUTTONUP:
self.selected1 = False
elif event.type == pg.MOUSEMOTION:
if self.selected1 :
self.move(0, event.rel[1])
class Connection():
def __init__(self, rect_1, rect_2, vel):
self.rect_1 = rect_1
self.rect_2 = rect_2
self.vel = vel
def draw(self, screen):
for r_1 in self.rect_1.rectangles:
for r_2 in self.rect_2.rectangles:
dist1 = r_2.rect.x - r_1.rect.x
velocity = int(dist1 * self.vel) # green wave angle
A_start_x, A_start_y = r_1.rect.topright
A_end_x, A_end_y = r_1.rect.bottomright
B_start_x, B_start_y = r_2.rect.topleft
B_end_x, B_end_y = r_2.rect.bottomleft
if B_start_y < A_start_y - velocity and B_end_y > A_start_y - velocity:
start_pos = (A_start_x, A_start_y)
end_pos = (B_start_x, A_start_y - velocity) # minus 50
pg.draw.aaline(screen, GREEN, start_pos, end_pos, 1)
if B_end_y > A_end_y - velocity and B_start_y < A_end_y - velocity:
start_pos = (A_end_x, A_end_y-1)
end_pos = (B_end_x, A_end_y - 1 - velocity) # minus 50
pg.draw.aaline(screen, RED, start_pos, end_pos, 1)
def main():
pg.init()
all_sprites = pg.sprite.Group()
objects = [
Rect1(GREEN, 10, 58, 55, 244, all_sprites ),
Rect1(GREEN, 10, 111, 188, 226, all_sprites ),
Rect1(RED, 10, 68, 69, 222, all_sprites),
Rect1(RED, 10, 121, 211, 202, all_sprites),]
conns = [
Connection(objects[0], objects[1], 0.1),
Connection(objects[2], objects[3], -0.1),]
done = False
clock = pg.time.Clock()
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
for o in objects:
o.handle_event(event)
SCREEN.fill(WHITE)
all_sprites.draw(SCREEN)
for c in conns:
c.draw(SCREEN)
pg.display.update()
clock.tick(60)
pg.quit()
if __name__ == '__main__':
main()
您可以通过将对另一个矩形的引用存储为属性(例如 self.associated
)来关联矩形,然后在 handle_event
方法中更新关联的矩形:self.associated.move(0, event.rel[1])
class Rect1():
def __init__(self, color, width, height, x, y, all_sprites, associated=None):
self.associated = associated
# Snip ...
def handle_event(self, event):
# Snip ...
elif event.type == pg.MOUSEMOTION:
if self.selected1 :
self.move(0, event.rel[1])
self.associated.move(0, event.rel[1])
def main():
# Snip ...
green_short = Rect1(GREEN, 10, 58, 55, 244, all_sprites)
red_short = Rect1(RED, 10, 68, 69, 222, all_sprites, green_short)
green_short.associated = red_short
green_long = Rect1(GREEN, 10, 111, 188, 226, all_sprites)
red_long = Rect1(RED, 10, 121, 211, 202, all_sprites, green_long)
green_long.associated = red_long
objects = [green_short, green_long, red_short, red_long]