# (c) Hochschule Anhalt, veröffentlicht unter MIT-Lizenz # Monster-Klasse # Autor: Viktor Lysow, Johannes Tümler # Letzte Änderung: 03.08.2022 # Zweck: Definition der Monster # # Monster erbt Alles von Figur # Monster können selbst laufen # Sterben, wenn sie mit der Magie des Helden in Berührung kommen # können den Helden bei Berührung töten # Der Nachfolgende Codeblock "BLOCK1" sorgt dafür, dass man aus jeder Datei heraus das Hauptprogramm starten kann. # Dadurch kann man in jeder Datei auf "play" drücken und es wird automatisch main.py gestartet. if __name__=="__main__": import subprocess # Auf Linux oder Mac aktivieren Sie die folgende Zeile und deaktivieren Sie die Zeile danach: #subprocess.call("python3 main.py", shell=True) # die richtige Main-Datei aufrufen (unser eigentliches Hauptprogramm) subprocess.call("main.py", shell=True) # die richtige Main-Datei aufrufen (unser eigentliches Hauptprogramm) exit(0) # nun das Programm hier beenden .. wir wollen ja nur das Hauptprogramm starten und nicht *diese* Datei. # Ende "BLOCK1" from importlib import import_module import pygame from random import randint from time import time from KlasseFigur import Figur from screen import screen import sounds class Monster(Figur): zeitDupl = 0 monsterListe = [] angriffsradius = 150 # je größer, je schwieriger. Dies ist der Abstand, unter dem Monster auf den Spieler zu laufen def __init__(self, x, y, geschw, breite, hoehe, level, bildFigur, zeitMonster): super().__init__(x, y, geschw, breite, hoehe, level, bildFigur) self.xReset = x self.yReset = y self.richtung = 1 self.zeitMonster = zeitMonster self.leben = True self.heldTot = False self.feuerWechsel = 0 self.heldDaten = None self.monsterDaten = None self.bildSterben = [pygame.image.load(f"Bilder/Geist/tot.png")] self.bildSterbenAngezeigt = False self.bildTot = [pygame.image.load(f"Bilder/Feuer/F1.png"), pygame.image.load(f"Bilder/Feuer/F2.png"), pygame.image.load(f"Bilder/Feuer/F3.png")] self.letzteX = 0 self.letzteY = 0 def reset(self): self.x = self.xReset self.y = self.yReset self.leben = True self.heldTot = False def spielerRichtung(self, spieler): absX = self.x - spieler.x absY = self.y - spieler.y abstand = (abs(absX)**2 + abs(absY)**2)**0.5 # Pythagoras .. schlechte Performance if (abstand < Monster.angriffsradius) and not (self.x == self.letzteX and self.y == self.letzteY): # wenn der Abstand zum Spieler < Monster.angriffsradius Pixel ist, in seine Richtung laufen! # Ausnahme: wenn wir uns beim letzten Schritt nicht bewegt haben (z.B. vor einer Wand fest stehen) if (abs(absX) > abs(absY)): # der X-Wert ist größer, d.h. der Spieler ist weiter in x von uns entfernt, als in y # wir sollten also in x Richtung gehen if absX < 0: return 2 # nach rechts gehen else: return 3 # nach links gehen else: if absY > 0: return 0 # 0...nach oben else: return 1 # 1...nach unten else: return randint(0,3) def mlaufen(self, spieler , monster = None): #Monster können selber laufen if self.leben: self.heldDaten = spieler #Alle Daten vom Held werden hier gespeichert self.monsterDaten = monster #Alle Daten von einem Monster werden hier gespeichert if time() - self.zeitMonster >= randint(5,10) * 0.1: # zwischen 0,5 und 1,0 Sekunden laufen die Monster in die gleiche Richtung if self.richtung != -1: #abhängig von der Zeit ändern sie die Richtung self.richtung = self.spielerRichtung(spieler) #in Richtung Spieler laufen self.zeitMonster = time() self.letzteX = self.x # den alten Wert der Bewegung speichern um in spielerRichtung festzustellen, ob wir uns bewegt haben self.letzteY = self.y self.laufen(self.richtung) #Laufen in eine Richtung self.sterben() self.faehigkeit() return self.heldTot #Rückgabe ob der Held tot ist else: if not self.bildSterbenAngezeigt: screen.blit(self.bildSterben[0], (self.x, self.y)) #Monster hinterlassen kurz eine Spur, wenn sie tot sind if time() - self.zeitMonster >= 1.0: self.bildSterbenAngezeigt = True self.zeitMonster = time() else: if time() - self.zeitMonster >= 0.15: self.feuerWechsel = (self.feuerWechsel + 1) % len(self.bildTot) self.zeitMonster = time() screen.blit(self.bildTot[self.feuerWechsel], (self.x, self.y)) #Monster brennen, wenn sie tot sind def toeten(self): #Held wird getötet bei Kollision if self.rechteck.colliderect(self.heldDaten.rechteck): sounds.soundTot() screen.blit(self.heldDaten.bildtot, (self.heldDaten.x, self.heldDaten.y)) self.heldTot = True def sterben(self): # Monster ist tot nach der Berührung von der Magie des Helden for k in self.heldDaten.kugeln: if self.rechteck.colliderect(k.waffeRec): self.heldDaten.kugeln.remove(k) self.leben = False sounds.soundFeuer() def faehigkeit(self): #Alle Fähigkeiten von Monster kommen hier rein self.toeten()