pgzblaster02.py ohne Kommentar
from random import choice, uniform
from enum import Enum
import pgzrun
from pgzblasterutils import sinus_oszillator, dreieck_oszillator, entscheide

WIDTH, HEIGHT = 500, 700
W, H = WIDTH, HEIGHT
WH, HH = W/2, H/2

RAKETEN_SPRITES = ['rakete01', 'rakete02', 'rakete03', 'rakete04', 'rakete05']
UFO_SPRITES = ['ufo01', 'ufo02', 'ufo03', 'ufo04', 'ufo05']
BOMBEN_SPRITES = ['bombe01', 'bombe02', 'bombe03', 'bombe04', 'bombe05']


class Zustand(Enum):
    BEREIT = 0
    SPIEL = 1
    GETROFFEN = 2
    SPIEL_VORBEI = 3


class Schiff(Actor):
    def __init__(self):
        Actor.__init__(self, 'schiff')
        self.geschwindigkeit = 6
        self.punkte = 0
        self.leben = 3
        self.initialisiere_position()

    def initialisiere_position(self):
        self.bottom = H-50
        self.centerx = WH

    def aktualisiere(self):
        if keyboard.left:
            self.x -= self.geschwindigkeit
        if keyboard.right:
            self.x += self.geschwindigkeit
        if keyboard.up:
            self.y -= self.geschwindigkeit
        if keyboard.down:
            self.y += self.geschwindigkeit
        self.clamp_ip(0, 0, W, H-50)

    def rakete_abfeuern(self):
        rakete = Rakete(self.x, self.y - 50)
        spiel.raketen.append(rakete)

    def getroffen(self):
        self.leben -= 1
        if self.leben > 0:
            spiel.zustand = Zustand.GETROFFEN
            clock.schedule(spiel.spiel_fortsetzen, 4)
            self.initialisiere_position()
        else:
            spiel.zustand = Zustand.SPIEL_VORBEI
            clock.schedule(spiel.vorbereiten, 4)

class Rakete(Actor):
    def __init__(self, x, y):
        Actor.__init__(self, choice(RAKETEN_SPRITES))
        self.aktiv = True
        self.x = x
        self.y = y
        self.geschwindigkeit = 10

    def aktualisiere(self):
        self.y -= self.geschwindigkeit
        if(self.top < 0):
            self.aktiv = False
        for actor in spiel.ufos + spiel.bomben:
            if self.colliderect(actor):
                actor.getroffen()
                self.aktiv = False
                return


class UFO(Actor):
    def __init__(self, y_linear, x1_freq, x2_freq, y_freq, zeit_versatz, abwurf_rate):
        Actor.__init__(self, choice(UFO_SPRITES))
        self.aktiv = True
        self.y_linear = y_linear
        self.y = y_linear
        self.y_vel = 1
        self.x1_freq = x1_freq
        self.x2_freq = x2_freq
        self.y_freq = y_freq
        self.zeit_versatz = zeit_versatz
        self.abwurf_rate = abwurf_rate

    def aktualisiere(self):
        x1_oszillator = dreieck_oszillator(self.x1_freq, 0, WH, self.zeit_versatz)
        x2_oszillator = dreieck_oszillator(self.x2_freq, 0, WH, self.zeit_versatz)
        y_oszillator = dreieck_oszillator(self.y_freq, -50, 50, self.zeit_versatz)

        self.x = x1_oszillator + x2_oszillator
        self.y_linear += self.y_vel
        self.y = self.y_linear + y_oszillator

        if self.top > H:
            self.aktiv = False

        if entscheide(self.abwurf_rate) and self.top > 0:
            self.bombe_abwerfen()

        if self.colliderect(spiel.schiff):
            spiel.schiff.getroffen()

    def bombe_abwerfen(self):
        spiel.bomben.append(Bombe(self.center))


    def getroffen(self):
        self.aktiv = False
        spiel.schiff.punkte += 100


class UfoFabrik():
    def __init__(self):
        self.anzahl_ufos = 7
        self.x1_freq = 0.1
        self.x2_freq = 0.1
        self.y_freq = 0.1
        self.zeit_versatz = 0.3
        self.abwurf_rate = 0.002

    def erzeuge_ufo_geschwader(self):
        geschwader = [UFO((i*-40) - H / 4,
                      self.x1_freq,
                      self.x2_freq,
                      self.y_freq,
                      i * self.zeit_versatz,
                      self.abwurf_rate)
                  for i in range(0, self.anzahl_ufos)]
        self.erhoehe_schwierigkeit()
        return geschwader

    def erhoehe_schwierigkeit(self):
        self.anzahl_ufos += 1
        self.x1_freq += uniform(0, 0.05)
        self.x2_freq += uniform(0, 0.05)
        self.y_freq += uniform(0, 0.05)
        self.zeit_versatz += uniform(0, 0.2)
        self.abwurf_rate += 0.0005


class Bombe(Actor):
    def __init__(self, center):
        Actor.__init__(self, choice(BOMBEN_SPRITES))
        self.aktiv = True
        self.center = center
        self.geschwindigkeit = 5

    def aktualisiere(self):
        self.y += self.geschwindigkeit
        if self.top > HEIGHT:
            self.aktiv = False
        if self.colliderect(spiel.schiff):
            spiel.schiff.getroffen()
            self.aktiv = False

    def getroffen(self):
        self.aktiv = False


class Spiel:
    def __init__(self):
        self.zustand = Zustand.BEREIT
        self.raketen = []
        self.ufos = []
        self.bomben = []
        self.schiff = Schiff()
        self.ufo_fabrik = UfoFabrik()

    def vorbereiten(self):
        self.zustand = Zustand.BEREIT
        self.initialisiere_spielobjekte()
        self.schiff = Schiff()
        self.ufo_fabrik = UfoFabrik()

    def initialisiere_spielobjekte(self):
        self.raketen = []
        self.ufos = []
        self.bomben = []

    def spiel_fortsetzen(self):
        self.zustand = Zustand.SPIEL
        self.initialisiere_spielobjekte()
        self.ufos = self.ufo_fabrik.erzeuge_ufo_geschwader()

    def aktualisiere(self):
        for spielobjekte in self.raketen + self.bomben + self.ufos:
            spielobjekte.aktualisiere()
        self.schiff.aktualisiere()

        self.raketen = [r for r in self.raketen if r.aktiv]
        self.ufos = [u for u in self.ufos if u.aktiv]
        self.bomben = [b for b in self.bomben if b.aktiv]

        if len(spiel.ufos) == 0:
            self.ufos = self.ufo_fabrik.erzeuge_ufo_geschwader()


def textnachricht(text):
    screen.draw.text(text,
                    center=(WH, HH),
                    color="black",
                    fontsize=40)


def on_key_down():
    if spiel.zustand == Zustand.BEREIT:
        spiel.zustand = Zustand.SPIEL
        return

    if keyboard.space and spiel.zustand == Zustand.SPIEL:
        spiel.schiff.rakete_abfeuern()


def update():
    if spiel.zustand == Zustand.SPIEL:
        spiel.aktualisiere()


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

    if spiel.zustand == Zustand.BEREIT:
        textnachricht("PRESS ANY KEY TO START")

    if spiel.zustand == Zustand.SPIEL:
        for actor in spiel.raketen + spiel.bomben + spiel.ufos:
            actor.draw()
        spiel.schiff.draw()

    if spiel.zustand == Zustand.GETROFFEN:
        textnachricht("YOU'VE BEEN HIT")

    if spiel.zustand == Zustand.SPIEL_VORBEI:
        textnachricht("GAME OVER")

    if spiel.zustand != Zustand.BEREIT:
        screen.draw.text("Ships: " + str(spiel.schiff.leben),
                         (20, H-30),
                         color="black")

        screen.draw.text("Score: " + str(spiel.schiff.punkte),
                         (W-120, H-30),
                         color="black")

spiel = Spiel()
pgzrun.go()
pgzblaster_utils.py ohne Kommentar
from time import time
from math import pi, sin, asin, cos
from random import random

def entscheide(wahrscheinlichkeit):
    return random() < wahrscheinlichkeit

def skaliere_nach(wert, von_min, von_max, nach_min, nach_max):
    bereich_von = von_max - von_min
    bereich_nach = nach_max - nach_min
    return (((wert - von_min) * bereich_nach) / bereich_von) + nach_min

def sinus_oszillator(frequenz, wert_min, wert_max, zeit_versatz=0):
    t = time() + zeit_versatz
    t = t * pi * 2 * frequenz
    wert = sin(t)
    return skaliere_nach(wert, -1, 1, wert_min, wert_max)

def dreieck_oszillator(frequenz, wert_min, wert_max, zeit_versatz=0):
    t = time() + zeit_versatz
    t = t * pi * 2 * frequenz
    wert = asin(cos(t))
    return skaliere_nach(wert, -pi / 2, pi / 2, wert_min, wert_max)
Zuletzt geändert: Donnerstag, 27. März 2025, 06:59