2017-06-18 6 views
2

Ich versuche, einen Code für ein PvP-Schlachtschiff-Spiel zu schreiben, und ich bin irgendwie fest.Wie kann ich meinen Code auf einen Klick warten lassen?

Ich werde Ihnen die Codes zuerst zeigen dann erklären, wie sie funktionieren.

Hier ist der erste Code. Diese Funktion wird verwendet, um jeweils Schiffe auf einem Gitter zu suchen:

für die Funktion
def ship_builder(name): 
# client ship value = 6, server ship value = 7 
    v_or_h = randrange(2) 
    if v_or_h == 0: 
     vertical = True 
    else: 
     vertical = False 

    if name == 'destroyer': 
     print('Click a cell to build a destroyer.') 
     if vertical == True: 
      print('Vertical') 
      for event in pygame.event.get(): 
       if event.type == pygame.QUIT: 
        break 
       if event.type == pygame.MOUSEBUTTONDOWN: 
        pos = pygame.mouse.get_pos() 
        col = (pos[0] // (cell_side + margin)) + 1 
        row = (pos[1] // (cell_side + margin)) + 1 
        grid[row][col] = 7 
        for i in range(3): 
         row += 1 
         grid[row][col] = 7 

     elif vertical == False: 
      print('Horizontal') 
      for event in pygame.event.get(): 
       if event.type == pygame.QUIT: 
        break 
       if event.type == pygame.MOUSEBUTTONDOWN: 
        pos = pygame.mouse.get_pos() 
        col = (pos[0] // (cell_side + margin)) + 1 
        row = (pos[1] // (cell_side + margin)) + 1 
        grid[row][col] = 7 
        for i in range(3): 
         col += 1 
         grid[row][col] = 7 

    elif name == 'frigate': 
     print('Click a cell to build a frigate') 
     if vertical == True: 
      print('Vertical') 
      for event in pygame.event.get(): 
       if event.type == pygame.QUIT: 
        break 
       if event.type == pygame.MOUSEBUTTONDOWN: 
        pos = pygame.mouse.get_pos() 
        col = (pos[0] // (cell_side + margin)) + 1 
        row = (pos[1] // (cell_side + margin)) + 1 
        grid[row][col] = 7 
        for i in range(2): 
         row += 1 
         grid[row][col] = 7 
     elif vertical == False: 
      print('Horizontal') 
      for event in pygame.event.get(): 
       if event.type == pygame.QUIT: 
        break 
       if event.type == pygame.MOUSEBUTTONDOWN: 
        pos = pygame.mouse.get_pos() 
        col = (pos[0] // (cell_side + margin)) + 1 
        row = (pos[1] // (cell_side + margin)) + 1 
        grid[row][col] = 7 
        for i in range(2): 
         col += 1 
         grid[row][col] = 7 

Zweitens ist ein for-Schleife oben:

for ship in ['destroyer','frigate']: 
    ship_builder(ship) 
    color_change() 

    #color_change() is a function that colors the responding cells for the ships. 

Dies ist, wie sie funktionieren sollen. Zuerst wird ship_builder mit dem Namen eines Schiffes (zB "Schlachtschiff") aufgerufen. Als Erstes überprüft der Code, ob das Schiff vertikal oder horizontal platziert werden soll. Je nach Wert kann der Benutzer auf eine Zelle klicken, um den Standort zu bestimmen. Hier habe ich ein Problem. Der Code springt einfach über diesen Teil und geht ohne etwas zu tun.

Meine Frage ist: Warum springt es über den Mausklick-Teil? Soll pygame.event.get() Python nicht auf eine Aktion warten lassen?

Ich bin mir nicht sicher, ob ich es wesentlich erklärte. Hinterlasse mir einen Kommentar, wenn ich weitere Informationen zur Verfügung stellen muss. Ich brauche wirklich Hilfe!

Vielen Dank!

Antwort

3

Die kurze Antwort: Nein, pygame.event.get() -> EventList nicht anzunehmen 'wait' für eine Aktion. Verwenden Sie stattdessen pygame.event.wait() -> EventType.

Die längere Antwort: Pygame verwendet eine Ereigniswarteschlange, in der Ereignisse gespeichert werden, die aufgetreten sind. Werfen wir einen Blick auf die pygame.event.get() Dokumentation.

pygame.event.get() 
    get events from the queue 
    get() -> Eventlist 
    get(type) -> Eventlist 
    get(typelist) -> Eventlist 

Dadurch werden alle Nachrichten bekommen und sie aus der Warteschlange entfernen. Wenn ein Typ oder eine Folge von Typen angegeben wird, werden nur diese Nachrichten aus der Warteschlange entfernt. Wenn Sie nur bestimmte Ereignisse aus der Warteschlange übernehmen, sollten Sie beachten, dass die Warteschlange möglicherweise mit den Ereignissen gefüllt wird, an denen Sie nicht interessiert sind.

Also im Grunde gibt pygame.event.get() jedes Ereignis zurück, das seit dem letzten Mal passiert ist, als wir es aufgerufen haben. Wenn unser Event noch nicht stattgefunden hat, wird es nicht in der zurückgegebenen EventList sein.

Aber es gibt eine andere Funktion namens pygame.event.wait(), die sich in der verlangten Weise verhält (obwohl sie nur ein einzelnes Ereignis zurückgibt).

pygame.event.wait() 
    wait for a single event from the queue 
    wait() -> EventType instance 

Gibt ein einzelnes Ereignis aus der Warteschlange. Wenn die Warteschlange leer ist, wartet diese Funktion bis eine erstellt wird. Das Ereignis wird aus der Warteschlange entfernt, sobald es zurückgegeben wurde.

So ist es möglich, dass ein Mousedown-Ereignis zu warten, mit so etwas wie

event_happened = False 
while not event_happened: 
    event = pygame.event.wait() 
    if event.type == pygame.MOUSEBUTTONDOWN: 
     do_something() 
     event_happened = True 

Wir brauchen aber vorsicht hier zu sein, denn wie in der Dokumentation angegeben, die Ereignisse aus der Warteschlange entfernt werden , dh alle Ereignisse, die nicht vom Typ pygame.MOUSEBUTTONDOWN sind, gehen verloren. Wir müssten damit umgehen oder sie manuell weitergeben, wenn wir sie brauchten.

 

, dass die längere Antwort war, aber ich habe eine Additions-/Warnung. Das Abrufen der Ereignisse an verschiedenen Stellen im Code kann schnell zu Verwirrung führen (z. B. aufgrund von verlorenen Ereignissen, wie oben beschrieben usw.). Die Entscheidung in diesem Fall könnte mit dem Fehlen einer Hauptspielschleife im Programm zu tun haben (ich kann das nicht sicher sagen, weil ich den umgebenden Code nicht kenne, aber die aktuelle Implementierung scheint so etwas zu suggerieren). Normalerweise

, Ereignisse werden in einem kontinuierlichen Hauptspiel Schleife zugegriffen, wie diese

while True: 
    for event in pygame.event.get(): 
     if event.type == pygame.MOUSEBUTTONDOWN: 
      build_ship_on_event(event) 

     elif event.type == pygame.QUIT: 
      pygame.quit() 
      sys.exit() 

Und die build_ship_on_event(event) Funktion aussehen kann, könnte versuchen so etwas wie

def build_ship_on_event(event): 
    if event_is_mouse_click(event): 
     ship_builder(selected_ship_type, event.pos) 

zu tun, und das Schiff für eine bauen zuvor ausgewählten Typ an der angegebenen Position (natürlich überprüft, ob das Schiff zuvor gebaut wurde und so weiter).

+0

Ich habe keine so detaillierte Antwort erwartet! Schätze es sehr! –

Verwandte Themen