Spielfigur mit Leertaste hüpfen lassen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wozu ist denn die Abfrage mit 525?
V-Max
User
Beiträge: 10
Registriert: Sonntag 18. Juli 2021, 17:35

Das er wieder nach unten kommt und bei dieser Höhe stoppt
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja eben. Und das ist doch der Moment, ab dem du es wieder erlauben kannst, das der User springt. Also machst du an der Stelle das Rücksetzen.
V-Max
User
Beiträge: 10
Registriert: Sonntag 18. Juli 2021, 17:35

Jetzt teleportiere ich mich stückweise nach oben und kann immer noch fliegen?!

Code: Alles auswählen

    if keyboard.is_pressed("space") and jumpTime == 0:
        jumpTime += 1
        if stickman.y >= 430:
            stickman.y -= 27
    else:
        if stickman.y <= 525:
            stickman.y += 2
            jumpTime = 0
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich würde während des Sprungs einfach eine "Schwerkraft" basteln unter Beachtung der Bodenhöhe, sofern diese nicht immer 0 ist. Ein Beispiel:

Code: Alles auswählen

height = max(height - 5, ground_height)
Die wirkt dann in jedem Intervall (zb 200 ms) als Gegengewicht zur erreichten Höhe durch die Leertaste. Die Operation käme dann als Schritt vor der Tasten-Abfrage.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du darfst den reset nur machen, wenn du auf dem Boden aufkommst. Nicht sofort nur weil du fällst.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@V-Max,

ich will dich nicht mit einem weiteren Lösungsansatz verwirren, aber da du ja jetzt schon einige Zeit mit dem Problem verbracht hast, wollte ich dir wenigstens eine einfachere (jedenfalls aus meiner Sicht) Lösung vorschlagen.

Du kannst ja selbst entscheiden ob du das versuchen möchtest oder nicht.
Am Ende habe ich ein minimales Programm was das Springen demonstriert.

Zunächst hat man den stickman:

Code: Alles auswählen

stickman = Actor("stickman")
Wie in der realen Welt, hat jedes Objekt eine Position, Geschwindigkeit und Beschleunigung.
Die Position ist klar, das sind die x und y Koordinaten auf dem Bildschirm.
Die Geschwindigkeit ist die Rate mit der sich die Position ändert.
Und die Beschleunigung ist die Rate mit der sich die Geschwindigkeit ändert.

Soweit ich weiß, kann man by pgzrun aber nur die Position beeinflussen. Daher muss man sich die anderen Attribute selber anlegen.

Code: Alles auswählen

stickman.x_pos = 400
stickman.y_pos = 600
stickman.x_vel = 0
stickman.y_vel = 0
Der stickman befindet sich hier also in der Mitte des Bildschirms und seine Geschwindigkeit in x und y Richtung ist 0.
Da der Stickman keinen eigenen Antrieb hat, lasse ich die Beschleunigung weg.

Es gibt aber eine immer vorhandene Beschleunigung, die Gravitation:

Code: Alles auswählen

gravity = 0.1
In der Spielwelt kann man sich irgendeinen Wert aussuchen. Je größer um so "schwerer" sind die Spielobjekte.

in der update() Funktion muss man sich nun darum kümmern, dass die Werte richtig bei jedem Update aktualisiert werden:

Code: Alles auswählen

# x-Position und y-Position werden durch Aufsummieren der x-Geschwindigkeit und y-Geschwindigkeit geändert
stickman.x_pos += stickman.x_vel
stickman.y_pos += stickman.y_vel
Die Position ändert sich mit der Geschwindigkeit. Man sieht, so lange die Geschwindigkeit 0 ist, ändert sich auch die Position nicht.

Code: Alles auswählen

# y-Geschwindigkeit wird durch Aufsummierender der Gravitation geändert
stickman.y_vel += gravity
Die einzige Bechleunigung hier ist die Gravitation die die Geschwindigkeit nach unten erhöht.
Das heißt die Geschwindigkeit wird in mit jedem Update anwachsen und damit wird sich die Position auch immer schneller ändern. Der Stickman fällt nach unten.

Damit er nicht ins bodenlose fällt muss man ihn am Boden stoppen:

Code: Alles auswählen

# prüfen ob der stickman in den Boden gefallen ist.
# Wenn ja, wird die y-Position gleich der Bodenposition gesetzt und die Geschwindigkeit in y-Richtung auf 0 gesetzt
if stickman.y_pos > GROUND:
    stickman.y_pos = GROUND
    stickman.y_vel = 0
in pgzrun ist der untere Rand des Stickman Sprites als midbottom definiert.
Man setzt also schließlich den unteren Rand des Stickmans an die neu berechnete Position:

Code: Alles auswählen

# die germerkten Werte an den stickman übertragen
stickman.midbottom = (stickman.x_pos, stickman.y_pos)
Jetzt kommt noch das Springen:
Ich verwende hier die on_key_down() Methode von pgzrun.

Damit der Stickman springen kann, müssen zwei Bedingungen erfüllt sein:
1) SPACE muss gedrückt sein
2) Der Stickman muss auf dem Boden stehen, denn nur dann kann er springen.

Was heißt Springen? Wie in der Realität eine plötzliche Geschwindigkeitsänderung nach oben. (Nach oben heißt natürlich, die Geschwindigkeit muss negativ sein)

Code: Alles auswählen

def on_key_down(key):

    # springen ist nur möglich
    if key == keys.SPACE and stickman.midbottom[1] == GROUND:
        stickman.y_vel = -10

Ich hoffe das hilft um zumindest das Springen zu veranschaulichen:

Code: Alles auswählen

import pgzrun

WIDTH = 800
HEIGHT = 800
GROUND = 600  # fester Wert für den Boden

stickman = Actor("stickman")

# gemerkte Positions und Geschwindigkeitswerte
stickman.x_pos = 400
stickman.y_pos = 600
stickman.x_vel = 0
stickman.y_vel = 0

# Erdbeschleunigung
gravity = 0.1


def update(dt):
    # x-Position und y-Position werden durch Aufsummieren der x-Geschwindigkeit und y-Geschwindigkeit geändert
    stickman.x_pos += stickman.x_vel
    stickman.y_pos += stickman.y_vel

    # y-Geschwindigkeit wird durch Aufsummierender der Gravitation geändert
    stickman.y_vel += gravity

    # prüfen ob der stickman in den Boden gefallen ist.
    # Wenn ja, wird die y-Position gleich der Bodenposition gesetzt
    if stickman.y_pos > GROUND:
        stickman.y_pos = GROUND

    # die germerkten Werte an den stickman übertragen
    stickman.midbottom = (stickman.x_pos, stickman.y_pos)


def draw():
    screen.fill((0, 0, 0))

    # Boden zeichnen
    screen.draw.line((0, GROUND), (WIDTH, GROUND), (255, 255, 255))

    stickman.draw()


def on_key_down(key):

    # springen ist nur möglich
    if key == keys.SPACE and stickman.midbottom[1] == GROUND:
        stickman.y_vel = -10


pgzrun.go()
carterashley
User
Beiträge: 1
Registriert: Freitag 23. Juli 2021, 14:24

Könntest du mir bitte einen groben Code von dem Sprung schicken? Da ich noch Anfänger bin und nicht exakt weiß, wie ich alles zu schreiben habe...
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da steht doch grober code?
Antworten