Zeitverzögerter spawner

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.
Antworten
Lengeta
User
Beiträge: 6
Registriert: Freitag 19. März 2021, 12:14

Hey Leute, für ein Spiel möchte ich einen Code programmieren, der in einer bestimmten Zeit Bälle spawned, versteh aber nicht ganz wie die time.sleep funktion funktioniert. Wenn ich das so laufen lass, friert das spiel nur ein.
Hat jemand eine Ahnung wie ich das lösen kann?


Code: Alles auswählen

def ball_spawner():
    for i in range(10):
        cooldown = True
        while cooldown:
            pygame.draw.ellipse(screen, blue,ball)
            cooldown = False
            time.sleep(10)
            cooldown = True
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Du darfst den Programmfluss nicht blockieren. Das tust du aber, wenn du time.sleep() aufrufst.

Wenn Parameter so funktioniert wie die anderen Game Engineering, die ich kenne, gibt es eine Hauptschleife, die die ganze Zeit läuft und das Spiel zeichnet. Die würde aber unterbrochen werden, wenn du, wie hier, time.sleep aufrufst.

Statt also irgendwas zu unterbrechen, musst du in der Hauptschleife schauen, ob seit einem bestimmten Zeitpunkt schon 10 Sekunden vergangen sind.

Dein Code sieht aber auch in sich falsch aus.
Fu iterierst über die Zahlen 1-10 und rufst für jede Zahl auf:
Setzt cooldown=True
Dann tust du Dinge
Dann setzt du in der Schleife cooldown am Ende wieder auf True. Die Schleife läuft also endlos.

Was genau willst du eigentlich tun?
Lengeta
User
Beiträge: 6
Registriert: Freitag 19. März 2021, 12:14

@sparrow: danke für deine Antwort,
Ich möchte ein Spiel programmieren, wo Bälle von oben runterfallen und vom spieler zurück gebouncet werden sollen.
Nach einer gewissen Zeit sollen immer mehr Bälle ins spiel kommen, um so die schwierigkeit zu erhöhen.
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Dann musst du das im Gameloop prüfen und ggf. einen neunen Ball spawnen, wenn genug Zeit vergangen ist.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich habe mal etwas Ähnliches in Qt gebaut: viewtopic.php?t=44384&start=30

Das relevante Prinzip hier ist das regelmäßige aufrufen einer update Methode (da durch einen Timer, bei dir via Hauptschleife), und die Verwaltung der Objekte.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Bei pygame bietet sich für Ereignisse, die wiederholt nach einer bestimmten Zeit stattfinden sollen, ein Timer an:
https://www.pygame.org/docs/ref/time.ht ... .set_timer

Der Timer löst dann nach einem festgesetzten Intervall ein selbst definiertes Event aus, welches sich wie alle anderen in der Game-Loop abfragen läßt.

Bild

Code: Alles auswählen

from random import randint
import pygame as pg

SPAWN_PERIOD = 1000  # ms


class Ball:
    def __init__(self, screen, color, radius, position, velocity, acceleration):
        self.screen = screen
        self.width = screen.get_width()
        self.height = screen.get_height()
        self.color = color
        self.radius = radius
        self.position = position
        self.velocity = velocity
        self.acceleration = acceleration

    def update(self):
        self.velocity += self.acceleration
        self.position += self.velocity
        if self.position.x < self.radius:
            self.position.x = 2 * self.radius - self.position.x
            self.velocity.x = -self.velocity.x
        elif self.position.x > self.width - self.radius:
            self.position.x = 2 * (self.width - self.radius) - self.position.x
            self.velocity.x = -self.velocity.x

        if self.position.y > self.height - self.radius:
            self.position.y = 2 * (self.height - self.radius) - self.position.y
            self.velocity.y = -self.velocity.y

    def draw(self):
        pg.draw.circle(self.screen, self.color, self.position, self.radius)


class Game:
    def __init__(self, width, height):
        self.running = False

        # Ereignis registrieren
        self.event = pg.event.Event(pg.event.custom_type())
        self.width = width
        self.height = height
        self.screen = pg.display.set_mode((self.width, self.height))
        self.balls = []
        self.background = pg.Color(0, 0, 0)

    def run(self):
        clock = pg.time.Clock()

        # Zeitintervall in Millisekunden zum Auslösen des Ereignisses festlegen
        pg.time.set_timer(self.event, SPAWN_PERIOD)
        self.running = True
        self.spawn()
        while self.running:
            self.update()
            self.draw()
            self.process_events()
            clock.tick(60)
            pg.display.update()

    def process_events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.running = False

            # Prüfen ob das Ereignis ausgelöst wurde
            if event == self.event:
                self.spawn()

    def spawn(self):
        radius = 10
        x_position = randint(radius, self.width - radius)
        x_velocity = randint(-2, 2)
        self.balls.append(
            Ball(
                screen=self.screen,
                color=pg.Color(255, 0, 0),
                radius=radius,
                position=pg.Vector2(x_position, 0),
                velocity=pg.Vector2(x_velocity, 0),
                acceleration=pg.Vector2(0, 0.1),
            )
        )

    def update(self):
        for ball in self.balls:
            ball.update()

    def draw(self):
        self.screen.fill(self.background)

        for ball in self.balls:
            ball.draw()


if __name__ == "__main__":
    pg.init()
    Game(500, 500).run()
Antworten