KlasseMonster.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. # (c) Hochschule Anhalt, veröffentlicht unter MIT-Lizenz
  2. # Monster-Klasse
  3. # Autor: Viktor Lysow, Johannes Tümler
  4. # Letzte Änderung: 03.08.2022
  5. # Zweck: Definition der Monster
  6. #
  7. # Monster erbt Alles von Figur
  8. # Monster können selbst laufen
  9. # Sterben, wenn sie mit der Magie des Helden in Berührung kommen
  10. # können den Helden bei Berührung töten
  11. # Der Nachfolgende Codeblock "BLOCK1" sorgt dafür, dass man aus jeder Datei heraus das Hauptprogramm starten kann.
  12. # Dadurch kann man in jeder Datei auf "play" drücken und es wird automatisch main.py gestartet.
  13. if __name__=="__main__":
  14. import subprocess
  15. # Auf Linux oder Mac aktivieren Sie die folgende Zeile und deaktivieren Sie die Zeile danach:
  16. #subprocess.call("python3 main.py", shell=True) # die richtige Main-Datei aufrufen (unser eigentliches Hauptprogramm)
  17. subprocess.call("main.py", shell=True) # die richtige Main-Datei aufrufen (unser eigentliches Hauptprogramm)
  18. exit(0) # nun das Programm hier beenden .. wir wollen ja nur das Hauptprogramm starten und nicht *diese* Datei.
  19. # Hinweis fürs Debugging: Das VSCode-Debugging funktioniert jedoch nur, wenn man das Debugging in der "main.py" beginnt! D.h. wer debuggen möchte, muss die main.py öffnen und dort Debug starten.
  20. # Ende "BLOCK1"
  21. from importlib import import_module
  22. import pygame
  23. from random import randint
  24. from time import time
  25. from KlasseFigur import Figur
  26. from screen import screen
  27. import sounds
  28. from screen import feldHalbe
  29. class Monster(Figur):
  30. zeitDupl = 0
  31. monsterListe = []
  32. angriffsradius = 150 # je größer, je schwieriger. Dies ist der Abstand, unter dem Monster auf den Spieler zu laufen
  33. lebendeMonster = 0
  34. def __init__(self, x, y, geschw, breite, hoehe, level, bildFigur, zeitMonster):
  35. super().__init__(x, y, geschw, breite, hoehe, level, bildFigur)
  36. self.xReset = x
  37. self.yReset = y
  38. self.richtung = 1
  39. self.zeitMonster = zeitMonster
  40. self.leben = True
  41. self.heldTot = False
  42. self.feuerWechsel = 0
  43. self.heldDaten = None
  44. self.monsterDaten = None
  45. self.bildSterben = [pygame.image.load(f"Bilder/Geist/tot.png")]
  46. self.bildSterbenAngezeigt = False
  47. self.bildTot = [pygame.image.load(f"Bilder/Feuer/F1.png"),
  48. pygame.image.load(f"Bilder/Feuer/F2.png"),
  49. pygame.image.load(f"Bilder/Feuer/F3.png")]
  50. self.letzteX = 0
  51. self.letzteY = 0
  52. if bildFigur != "Prinzessin": # wenn eine Prinzessin erzeugt wird, soll sie nicht an die Monsterliste angefügt werden
  53. Monster.monsterListe.append(self) # wir fügen uns selbst der Monsterliste hinzu
  54. Monster.lebendeMonster += 1 # und den Monsterzähler eins erhöhen
  55. if Monster.zeitDupl == 0:
  56. Monster.zeitDupl = time()
  57. def reset(self):
  58. self.x = self.xReset
  59. self.y = self.yReset
  60. self.leben = True
  61. self.heldTot = False
  62. def spielerRichtung(self, spieler):
  63. absX = self.x - (spieler.x + feldHalbe) # die Koordinate der Figur bezieht sich auf "Ecke oben links" des Figur-Icons, daher müssen wir ein halbes Feld dazu rechnen
  64. absY = self.y - (spieler.y + feldHalbe)
  65. abstand = (abs(absX)**2 + abs(absY)**2)**0.5 # Pythagoras .. schlechte Performance
  66. 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!
  67. # Ausnahme: wenn wir uns beim letzten Schritt nicht bewegt haben (z.B. vor einer Wand fest stehen)
  68. 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
  69. # wir sollten also in x Richtung gehen
  70. if absX < 0:
  71. return 2 # nach rechts gehen
  72. else:
  73. return 3 # nach links gehen
  74. else:
  75. if absY > 0:
  76. return 0 # 0...nach oben
  77. else:
  78. return 1 # 1...nach unten
  79. else:
  80. return randint(0,3)
  81. def mlaufen(self, spieler , monster = None): #Monster können selber laufen
  82. if self.leben:
  83. self.heldDaten = spieler #Alle Daten vom Held werden hier gespeichert
  84. self.monsterDaten = monster #Alle Daten von einem Monster werden hier gespeichert
  85. if time() - self.zeitMonster >= randint(5,10) * 0.1: # zwischen 0,5 und 1,0 Sekunden laufen die Monster in die gleiche Richtung
  86. if self.richtung != -1: #abhängig von der Zeit ändern sie die Richtung
  87. self.richtung = self.spielerRichtung(spieler) #in Richtung Spieler laufen
  88. self.zeitMonster = time()
  89. self.letzteX = self.x # den alten Wert der Bewegung speichern um in spielerRichtung festzustellen, ob wir uns bewegt haben
  90. self.letzteY = self.y
  91. self.laufen(self.richtung) #Laufen in eine Richtung
  92. self.sterben()
  93. self.faehigkeit()
  94. return self.heldTot #Rückgabe ob der Held tot ist
  95. else:
  96. if not self.bildSterbenAngezeigt:
  97. screen.blit(self.bildSterben[0], (self.x, self.y)) #Monster hinterlassen kurz eine Spur, wenn sie tot sind
  98. if time() - self.zeitMonster >= 1.0:
  99. self.bildSterbenAngezeigt = True
  100. self.zeitMonster = time()
  101. else:
  102. if time() - self.zeitMonster >= 0.15:
  103. self.feuerWechsel = (self.feuerWechsel + 1) % len(self.bildTot)
  104. self.zeitMonster = time()
  105. screen.blit(self.bildTot[self.feuerWechsel], (self.x, self.y)) #Monster brennen, wenn sie tot sind
  106. def toeten(self): #Held wird getötet bei Kollision
  107. if self.rechteck.colliderect(self.heldDaten.rechteck):
  108. sounds.soundTot()
  109. screen.blit(self.heldDaten.bildtot, (self.heldDaten.x, self.heldDaten.y))
  110. self.heldTot = True
  111. def sterben(self): # Monster ist tot nach der Berührung von der Magie des Helden
  112. for k in self.heldDaten.kugeln:
  113. if self.rechteck.colliderect(k.waffeRec):
  114. self.heldDaten.kugeln.remove(k)
  115. self.leben = False
  116. Monster.lebendeMonster -= 1
  117. sounds.soundFeuer()
  118. def faehigkeit(self): #Alle Fähigkeiten von Monster kommen hier rein
  119. self.toeten()