2017-02-20 2 views
0

Okay, ich versuche ein Tom und Jerry-Spiel mit der Pygame-Bibliothek zu erstellen.Kann nicht erneut auf das Bild klicken, was ist falsch mit meinem Pygame-Code?

Das Spiel konzentriert sich auf das Fangen von Mäusen durch Klicken auf sie, wie sie in ihren Löchern erscheinen. Das Problem ist, dass manchmal eine Katze anstelle einer Maus erscheint und wenn der Spieler fälschlicherweise auf die Katze (n) klickt, verliert er alle gesammelten Punkte, aber das Spiel geht weiter. Die Maus ist ein Bild einer Maus und die Katze ist ein Bild einer Katze. Wenn Sie mit der Maus klicken, bekommen Sie die Maus, sonst bekommt die Katze die Punkte. Der Code ist ein Durcheinander, weil ich nicht weiß, was ich mache und nur eine andere Ereignisschleife einstellen, denn dann funktioniert es, weil es nach dem Erstellen der Maus ausgeführt wird. Es funktioniert, um auf die Maus zu klicken, aber Sie klicken irgendwo anders und danach ist es, als ob Sie nicht auf die Maus geklickt haben.

Die Maus wird in einer Schleife erstellt und soll 5 Sekunden warten. Wenn Sie innerhalb dieser Sekunden mit der Maus klicken, wird eine entsprechende Meldung in der Konsole ausgedruckt, Jerry hat geklickt! "Else" 1 Klick ". Wenn du nicht innerhalb von 5 Sekunden auf die Maus klickst, verschwindet ein Bild und die Maus verschwindet,

Nun, was ich gerade versuche, ist, die Nachricht mit einem Klick zu drucken, wenn der Player nicht klickt Alles außer Druck 1 Klick Jerry hat geklickt, wenn der Spieler auf die Maus klickt Ich habe ein Bild des Mauselochs und dann die Maus auf das Mauseloch, also auf ein anderes Bild

Dieser Code funktioniert mit einem Bild mindestens:

pygame.init() 
width=350; 
height=400 
screen = pygame.display.set_mode((width, height)) 
pygame.display.set_caption('clicked on image') 
redSquare = pygame.image.load("images/red-square.png").convert() 

x = 20; # x coordnate of image 
y = 30; # y coordinate of image 
screen.blit(redSquare , (x,y)) # paint to screen 
pygame.display.flip() # paint screen one time 

running = True 
while (running): 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      running = False 
     if event.type == pygame.MOUSEBUTTONDOWN: 
      # Set the x, y postions of the mouse click 
      x, y = event.pos 
      if redSquare.get_rect().collidepoint(x, y): 
       print('clicked on image') 
#loop over, quite pygame 
pygame.quit() 

Mein Problem ist, dass, wenn ich auf der Maus klicken und dann auf mich nicht auf der Maus, die ich nicht auf der Maus wieder an einer anderen Stelle klicken.

Also was ist los? Was mache ich hier falsch?

Hier ist mein Code:

import pygame 
from pygame import * 
from random import * 

init() 

run = True 
screen = (800,800) 
screen = display.set_mode(screen) 
xpos = 0 
ypos = 0 
mouseorcatxpos = 5 
mouseorcatypos = 0 

mousehole = image.load("mousehole.png").convert() 

cat = image.load("tom.png") 
jerry = image.load("jerry.png") 

def makeholes(): 
    global ypos 
    global xpos 

    for holey in range(1,9): 

     for holex in range(1,9): 
      screen.blit(mousehole,(xpos,ypos)) 
      display.flip() 

      xpos += 100 

     ypos += 100 
     xpos = 0 

def mouseorcat(): 
    global xpos 
    mouseorcatxpos = 5 
    ypos = 0 

    for mousecaty in range(1,9): 

      pygame.event.pump() 

      for mousecatx in range(1,9): 

       randommouse = randint(1, 3) 
       randomcat = randint(1, 10) 

       if(randommouse == 2): 

        screen.blit(jerry, (mouseorcatxpos, ypos)) 
        display.flip() 

        for event in pygame.event.get(): 

         if (event.type == MOUSEBUTTONDOWN): 

          if jerry.get_rect().collidepoint(xpos, ypos) == False: 

           print("l clicked!") 

          x, y = event.pos 

          if jerry.get_rect().collidepoint(xpos, y): 
           print("JERRY CLICKED!!") 
           x, y = event.pos 
           print(x, y) 


        time.wait(5000) 
        #screen.blit(mousehole, (mouseorcatxpos - 5, ypos)) 
        display.flip() 

       elif(randomcat == 2): 
        screen.blit(cat, (mouseorcatxpos, ypos)) 
        display.flip() 
        time.wait(1500) 
        screen.blit(mousehole, (mouseorcatxpos-5, ypos)) 
        display.flip() 

       mouseorcatxpos += 100 
      mouseorcatxpos = 0 
      ypos += 100 


makeholes() 


while run == True: 


    for event in pygame.event.get(): 
     mouseorcat() 

     if event.type == QUIT: 
      run = False 
+0

Bitte erklären Sie die Regeln und die Mechanik des Spiels im Detail. Ich bin mir nicht sicher, wie es funktionieren soll. Es sieht so aus, als müsste der Code dramatisch umstrukturiert werden. Zum Beispiel sollte es nur eine Ereignisschleife und einen Aufruf von display.flip() geben. – skrx

+0

Um den Downvoter, seien Sie nicht unhöflich und einfach ohne Erklärung, und helfen Sie eher, die Frage zu verbessern. – skrx

+0

Ich habe eine Antwort mit einem komplett neuen Beispiel eingereicht, aber ich werde morgen noch einmal auf dein Programm schauen, um zu sehen, ob es "gerettet" werden kann. ;) Allerdings sieht es wirklich nicht gut aus. Mach dir keine Sorgen, jeder schreibt am Anfang Code wie diesen.Vielleicht wäre es auch besser, beim nächsten Mal nach einem Forum wie https://www.reddit.com/r/pygame/ zu fragen. – skrx

Antwort

1

Ich schrieb Spiel um Ihnen zu zeigen, wie ich es tun würde.

Um den Überblick über die Zeit zu halten und die Framerate ich einen pygame.time.Clock und ein Timer-Variable verwendet zu begrenzen. Die Uhr gibt die Zeit in Millisekunden zurück, seit das letzte Mal aufgerufen wurde, mit dem die Timer-Variable erhöht wird. Die Katze ersetzt die Maus nach zwei Sekunden und die Maus wird auf eine neue Position gesetzt. Ich verwende pygame.Rect s, um die Positionen zu speichern, aber Sie könnten auch Listen oder Tupel verwenden.

import sys 
import random 
import pygame 


pygame.init() 

size = (800, 800) 
screen = pygame.display.set_mode(size) 

# Images replaced by pygame.Surface. Do that too 
# in the future before you post your code. 
mousehole = pygame.Surface((40, 40)).convert() 
mousehole.fill(pygame.Color(30, 30, 30)) 
cat = pygame.Surface((40, 40)).convert() 
cat.fill(pygame.Color(110, 110, 130)) 
jerry = pygame.Surface((40, 40)).convert() 
jerry.fill(pygame.Color(190, 130, 0)) 
# Create the background image and blit the holes. 
background = pygame.Surface(size).convert() 
for holey in range(8): 
    for holex in range(8): 
     background.blit(mousehole, (holex*100, holey*100)) 


def new_position(): 
    """Return a random position between 0-700 in steps of 100.""" 
    return (random.randrange(0, 701, 100), random.randrange(0, 701, 100)) 


def main(): 
    fps = 30 
    clock = pygame.time.Clock() 

    jerry_rect = jerry.get_rect() # Stores jerry's position and size. 
    jerry_rect.topleft = new_position() # New random position. 
    # The cat is outside of the screen first. 
    cat_rect = cat.get_rect(topleft=(-100, -100)) 
    points = 0 
    timer = 0 

    running = True 
    while running: 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       running = False 
      if event.type == pygame.MOUSEBUTTONDOWN: 
       if jerry_rect.collidepoint(event.pos): 
        points += 1 
        print('Jerry caught! Points:', points) 
        timer = 0 
        jerry_rect.topleft = new_position() 
       else: 
        print('Missed. Points:', points) 

     # Run logic. 
     timer += clock.tick(fps)/1000 # timer + seconds since last tick. 
     if timer > 2: # Cat catches mouse after 2 seconds. 
      cat_rect.topleft = jerry_rect.topleft 
      jerry_rect.topleft = new_position() 
      timer = 0 
      points = 0 
      print('Tom caught Jerry.') 
     # Draw. 
     # Clear the screen by blitting the bg. 
     screen.blit(background, (0, 0)) 
     screen.blit(jerry, jerry_rect) 
     screen.blit(cat, cat_rect) 
     pygame.display.flip() 

if __name__ == '__main__': 
    main() 
    pygame.quit() 
    sys.exit() 

Side Hinweise:

Sie keine Sterne Importe verwenden (from module import *), denn das kann Code schwieriger zu lesen. Wenn Sie möchten, können Sie from pygame.locals import * verwenden, wenn es der einzige Star-Import ist.

Verwenden Sie keine globalen Variablen, da sie den Code schwerer lesbar, zu verstehen und zu pflegen machen. Übergeben Sie Variablen an Funktionen als Argumente und geben Sie das Ergebnis zurück.


Update: Einige Hinweise über Ihr Programm:

Das erste große Problem ist, dass Ihr Spiel hat zwei Ereignisschleifen und das wichtige ist tief im Inneren von zwei anderen für Schleifen und einem if verschachtelt. Die Ereignisschleife sollte direkt unter der while-Schleife sein (eine Einrückungsebene (wenn Sie mehr Erfahrung haben, können Sie sie in eine Funktion oder Klassenmethode einfügen)).


Die beiden für Schleifen scheinen den Zweck zu haben, den Code laufen zu lassen, bis randommouse oder randomcat sind 2. Code auszuführen, bis eine Bedingung erfüllt ist der Zweck einer while-Schleife ist. Aber in diesem Fall sollten Sie einfach eine zufällige Zahl auswählen und die if/elif-Bedingungen schreiben, damit sie immer zutreffen. Zum Beispiel wollen Sie eine 2/3 Chance für Maus und 1/3 für eine Katze,

random_number = random.randint(1, 3) 
if random_number < 3: 
    print("2/3 probability. It's a mouse") 
else: 
    print("1/3 probability. It's a cat") 

Oder verwenden random.choice mit einer Liste:

>>> random.choice(['mouse', 'mouse', 'cat']) 
'mouse' 

time.wait (5000) sollte nicht verwendet werden, da das Spiel gerade in dieser Zeit hängt. Sie können das Fenster nicht einmal schließen. Begrenzen Sie die Framerate und erhalten Sie die Zeit seit dem letzten Tick mit einem pygame.time.Clock.


pygame.event.pump() wird nicht benötigt.


Wenn Sie get_rect() ohne ein Argument aufrufen, wird das Rect bei (0, 0) positioniert.

if jerry.get_rect().collidepoint(xpos, y): 

Das ist der Grund, warum auf Jerry Klick funktioniert nur in der oberen Reihe, und weil Sie verwenden, um die globale xpos hier. Da xpos 0 ist, zählt die gesamte obere Reihe als Jerry.

Sie können Koordinaten get_rect passieren wie so (auch center oder andere args statt topleft verwenden):

jerry_rect = jerry.get_rect(topleft=(50, 100)) 

Es tut mir leid, aber ich glaube nicht, kann ich einfach beheben dein Code. Ich habe es mehrmals versucht, aber ich schreibe es immer komplett neu.

Ich beginne mit dem Extrahieren der Ereignisschleife aus den zwei verschachtelten For-Schleifen, dann entfernen Sie diese Schleifen, erstellen Sie Retrakte für die Maus und Katze, beheben Sie die Kollisionserkennung, fügen Sie einen Timer und so weiter. Schau dir mein Beispiel genauer an und versuche, dein Spiel auf eine ähnliche Weise neu zu schreiben, und stell weiterhin Fragen, wenn du etwas nicht verstehst.

+1

Ich habe Code von meinem Programmierlehrer bekommen, der das mit kleinen Änderungen macht. Danke für deine Hilfe, ich akzeptiere dies als Antwort, da dieser Code auch funktioniert und es möglich ist, ihn in einem Projekt wie diesem zu verwenden. Der Grund, warum ich meinen Code hier nicht zeige, ist, dass ich das meiste nicht selbst geschrieben habe und den Autor respektiere, ich poste seinen Code nicht ohne Erlaubnis. Ja, der Code in der Frage ist nicht verwendbar, es ist schrecklich :) –

Verwandte Themen