2 Stimmen

Wie kann ich meine Kreise in pygame über den Bildschirm fliegen lassen?

Ich bin ein Anfänger in Python und versuche, ein Kreisspiel zu erstellen. Bis jetzt zeichnet es einen Kreis an der Maus mit einer zufälligen Farbe und Radius, wenn Sie klicken.

Als Nächstes möchte ich, dass der Kreis in eine zufällige Richtung über den Bildschirm fliegt. Wie würde ich das anstellen? Dies ist der Hauptteil meines Codes so weit:

check1 = None
check2 = None

while True:

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit

        if event.type == MOUSEBUTTONDOWN:
            last_mouse_pos = pygame.mouse.get_pos()

    if last_mouse_pos:

        global check

        color1 = random.randint(0,255)
        color2 = random.randint(0,255)
        color3 = random.randint(0,255)
        color = (color1,color2,color3)

        radius = random.randint (5,40)
        posx,posy = last_mouse_pos

        if posx != check1 and posy != check2:
            global check1, check2
            screen.lock()
            pygame.draw.circle(screen, color, (posx,posy), radius)
            screen.unlock()
            check1,check2 = posx,posy

    pygame.display.update()

Auch hier möchte ich, dass der Kreis in eine zufällige Richtung vom Bildschirm fliegt. Ich habe ein paar Versuche gemacht, aber noch keinen Erfolg. Außerdem, Dank an jdi der mir geholfen hat.

7voto

Preet Kukreti Punkte 8257

Erzeugen Sie beim Erstellen des Kreises (durch Anklicken) 2 Zufallszahlen. Dies sind die (x,y)-Komponenten für eine zweidimensionale Euklidisch Geschwindigkeit Vektor:

enter image description here

# interval -1.0 to 1.0, adjust as necessary
vx, vy = ( (random.random()*2) -1, (random.random()*2) - 1 )

Nachdem der Ball erstellt wurde, wird bei jeder Iteration der Spielschleife die Position des Balls um den Geschwindigkeitsvektor erhöht:

enter image description here

posx, posy = posx + vx, posy + vy

Beachten Sie, dass die Gesamtgeschwindigkeit variabel sein kann. Wenn Sie immer eine Geschwindigkeit von 1,0 pro Sekunde haben wollen, normalisieren Sie den Vektor:

An normalisieren den Vektor, dividiert man ihn durch seine Größenordnung :

enter image description here

In Ihrem Fall also:

enter image description here

Und daher:

enter image description here

In Python wird also nach dem Import von math avec import math :

mag = math.sqrt(vx*vx + vy*vy)
v_norm = vx/mag, vy/mag
# use v_norm instead of your (vx, vy) tuple

Dann können Sie dies mit einigen speed Variable, um eine zuverlässige Geschwindigkeit zu erhalten.


Sobald Sie mehrere Objekte haben, die sich umherbewegen und sich möglicherweise außerhalb des Bildschirms befinden, ist es sinnvoll, die Objekte außerhalb des Bildschirms zu entfernen, die keine Chance haben, zurückzukommen, und die nichts mehr mit Ihrem Programm zu tun haben. Wenn Sie sonst all diese Objekte außerhalb des Bildschirms verfolgen, während Sie weitere erstellen, entsteht im Grunde ein Speicherleck, und der Speicher wird bei genügend Zeit/Aktionen erschöpft sein.


Auch wenn das, was Sie gerade tun, recht einfach ist, werden sich die Grundkenntnisse der Vektormathematik schon bald auszahlen, sofern Sie sie nicht bereits erworben haben. Eventuell müssen Sie für bestimmte Umformungen auch etwas Matrixmathematik anwenden. Wenn Sie neu in diesem Bereich sind, ist es nicht so schwer, wie es zunächst aussieht. Es reicht wahrscheinlich, wenn Sie es nicht lernen, aber Sie werden sich später die Mühe ersparen, wenn Sie sich an anspruchsvollere Dinge heranwagen.

5voto

Mark Hildreth Punkte 39593

Im Moment machen Sie Folgendes (was Ihren Code drastisch vereinfacht)...

while True:
    if the mouse was clicked:
        draw a circle on the screen where the mouse was clicked

Lassen Sie uns die Dinge ein wenig einfacher machen und schrittweise aufbauen.

Mit dem Kreis beginnen, ohne dass der Benutzer klickt

Der Einfachheit halber machen wir den Kreis oben links auf dem Bildschirm, so dass wir immer davon ausgehen können, dass es einen Kreis gibt (was die Logik etwas erleichtert)

circle_x, circle_y = 10,10
while True:
    draw the circle at circle_x, circle_y

    pygame.display.update()

Den Kreis animieren

Bevor wir uns zu sehr mit "zufälligen Richtungen" beschäftigen, machen wir es uns einfach und gehen in eine Richtung (sagen wir, immer nach unten und nach rechts).

circle_x, circle_y = 0,0
while True:
    # Update
    circle_x += 0.1
    circle_y += 0.1

    # Draw
    draw the circle at circle_x, circle_y
    update the display

Jedes Mal, wenn Sie die Schleife durchlaufen, verschiebt sich der Mittelpunkt des Kreises ein wenig, und dann zeichnen Sie ihn an seiner neuen Position. Beachten Sie, dass Sie möglicherweise die Werte, die Sie zu circle_x und y hinzufügen, verringern müssen (in meinem Code 0,1), falls sich der Kreis zu schnell bewegt.

Sie werden jedoch feststellen, dass sich Ihr Bildschirm jetzt mit Kreisen füllt! Anstatt eines Kreises, der sich "bewegt", zeichnen Sie den Kreis einfach viele Male! Um dies zu beheben, werden wir den Bildschirm vor jedem Zeichnen "leeren"...

screen = ....
BLACK = (0,0,0) # Defines the "black" color
circle_x, circle_y = 0,0
while True:
    # Update
    circle_x += 0.1
    circle_y += 0.1

    # Draw
    screen.fill(BLACK)
    draw the circle at circle_x, circle_y
    update the display

Beachten Sie, dass wir den Bildschirm "leeren", indem wir alles schwarz malen, bevor wir unseren Kreis zeichnen.

Jetzt können Sie damit beginnen, den Rest der gewünschten Elemente wieder in Ihren Code einzubauen.

Behalten Sie den Überblick über mehrere Kreise

Sie können dies tun, indem Sie eine Liste von Kreisen anstelle von zwei Kreisvariablen verwenden

circles = [...list of circle positions...]
while True:
    # Update
    for circle in circles:
        ... Update the circle position...

    # Draw
    screen.fill(BLACK)
    for circle in circles:
        draw the circle at circle position # This will occur once for each circle
    update the display

Wenn Sie die Positionen der Kreise in einem Tupel festhalten, können Sie deren Werte nicht ändern. Wenn Sie mit objektorientierter Programmierung vertraut sind, können Sie eine Kreisklasse erstellen und diese verwenden, um die Daten zu Ihren Kreisen zu verfolgen. Andernfalls können Sie in jeder Schleife eine Liste der aktualisierten Koordinaten für jeden Kreis erstellen.

Kreis hinzufügen, wenn der Benutzer klickt

circles = []
while True:
    # event handling
    for event in pygame.event.get():
        if event.type == MOUSEBUTTONDOWN:
            pos = pygame.mouse.get_pos()
            circles.append( pos ) # Add a new circle to the list

    # Update all the circles
    # ....

    # Draw
    clear the screen
    for circle_position in circles:
        draw the circle at circle_position # This will occur once for each circle
    update the display

Der Kreis soll sich in eine zufällige Richtung bewegen.

Hier kommt eine gute Portion Mathe ins Spiel. Grundsätzlich müssen Sie einen Weg, um zu bestimmen, was die x-und y-Koordinate des Kreises durch jede Schleife zu aktualisieren. Denken Sie daran, es ist völlig möglich, nur sagen, dass Sie es irgendwo zwischen -1 und 1 für jede Achse (X, y) bewegen wollen, aber das ist nicht unbedingt richtig. Es ist möglich, dass Sie sowohl für X als auch für Y den Wert Null erhalten, in diesem Fall bewegt sich der Kreis überhaupt nicht! Der nächste Kreis könnte 1 und 1 sein, der sich dann schneller bewegt als die anderen Kreise.

Ich bin mir nicht sicher, was Ihr mathematischer Hintergrund ist, also müssen Sie vielleicht noch ein wenig lernen, um zu verstehen, wie man eine "Richtung" (manchmal auch als "Vektor" bezeichnet) in einem Programm speichert. Sie können die Antwort von Preet ausprobieren, um zu sehen, ob das hilft. Ein echtes Verständnis ist einfacher, wenn Sie über Kenntnisse in Geometrie und Trigonometrie verfügen (obwohl Sie vielleicht auch ohne diese Kenntnisse auskommen können, wenn Sie eine gute Quelle finden).

Einige andere Gedanken

Einige andere Dinge, die Sie beachten sollten:

  1. Im Moment ist der Code, mit dem wir spielen, "frame rate dependent". Das heißt, die Geschwindigkeit, mit der sich die Kreise über den Bildschirm bewegen, hängt ganz davon ab, wie schnell der Computer laufen kann. Auf einem langsameren Computer werden sich die Kreise wie Schnecken bewegen, während ein schnellerer Computer die Kreise kaum sehen wird, bevor sie vom Bildschirm fliegen! Es gibt Möglichkeiten, dieses Problem zu beheben, die Sie selbst nachschlagen können (suchen Sie in Ihrer bevorzugten Suchmaschine nach "Abhängigkeit von der Bildrate" oder anderen Begriffen).

  2. Im Moment haben Sie screen.lock() und screen.unlock(). Diese brauchen Sie nicht. Sie müssen die Oberfläche des Bildschirms nur dann sperren/entsperren, wenn die Oberfläche dies erfordert (bei einigen Oberflächen ist dies nicht der Fall) und wenn Sie manuell auf die Pixeldaten zugreifen wollen. Wenn du Dinge wie das Zeichnen von Kreisen auf den Bildschirm tust, sperrt/entsperrt pygame die Oberflächen automatisch für dich. Kurz gesagt, du brauchst dich im Moment nicht mit dem Sperren/Entsperren zu beschäftigen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X