2017-05-14 2 views
1

Ich habe zwei Listen mit je 3 Retrakten. Kann ich den Variablen selected1 und selected2 3 rects aus jeder Liste zuweisen und diese zwei Zeilen von rects einzeln nach oben und unten verschieben, während die Lücken zwischen ihnen bleiben? Ich bin Anfänger und weiß nicht, ob solch ein konstruierter Code diese Aufgabe bewältigen kann.Mehrere Retrakte verschieben, indem man auf einen davon klickt

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() 
+1

Bitte beschreiben Sie Ihre Ziele im Detail, und posten Sie das Bild des Ampelkoordinationsprogramm, das Sie mir das letzte Mal gezeigt (wenn das noch, was Sie erreichen wollen). – skrx

+1

Was ich hier zu erreichen versuche ist ganz einfach - Zeit/Distanz-Diagramm der Ampel Koordination (grüne Welle). Vertikale grüne Rekruten repräsentieren die Menge des grünen Signals. Jede Reihe von grünen Rezepten repräsentiert unterschiedliche Schnittpunkte. Die Koordination wird durch diagonale Linien (Band) zwischen grünen Rechtecken dargestellt. Ich muss in der Lage sein, notwendige Parameter zu bearbeiten, wie z. B. präzise Reihen von grünen Rezepten zu verschieben, um die beste Konfiguration vorzunehmen, die Länge des grünen Lichts zu ändern, seine Position entsprechend Rotlicht, Zyklus, Geschwindigkeit usw. http://kmkrakow.pl/attachments/article /138/zielona%20fala.jpg – Bartnick81

Antwort

1

Um die Rects gleichzeitig zu bewegen, können Sie sie in einer Liste und setzen können, wenn ein rect ausgewählt ist, bewegen sie alle mit Hilfe des rel Attribut des MOUSEMOTION Ereignis (die relative Position von der letzten Maus Veranstaltung). Hier ist ein minimales Beispiel:

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() 
+1

Ich löste mein Problem, aber ich musste die Listen loswerden. Ihre Lösung scheint jedoch viel eleganter, schöner. Allerdings kann ich den Code nicht vollständig verstehen - wie funktioniert dieser Teil: für y in Bereich (0, 241, 120)] – Bartnick81

+1

'[pg.Rect (100, 100 + y, 20, 80) für y in Bereich (0, 241, 120)] 'das ist ein [Listenverständnis] (http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/). 'für y im Bereich (0, 241, 120)' gibt Ihnen die Zahlen 0, 120 und 240 (ich habe sie nur als y-Offsets für die rect-Positionen verwendet). – skrx

+0

Das Rel-Attribut des MOUSEMOTION-Ereignisses ist eine nette Methode, um das Rect zu verschieben (relativ zu dem, wo es geklickt hat), aber ich muss es um einen Faktor von 2 oder mehr Pixeln verschieben, ich kann es einfach durch Multiplikation von event.rel machen [1] aber dann, was erwartet wird, ist es irgendwie nicht mehr synchron. Kann die Verschiebung um einen Faktor mit event.rel korrekt durchgeführt werden? – Bartnick81

Verwandte Themen