Hallo, ich bin derzeit dabei, ein Space Invader zu programmieren, ich hänge gerade nur am Schussystem fest, da ich es nicht hinkriege, dass ich mehrere Schüsse schießen kann. Mir ist klar, das das mit einer Liste funktionieren muss, zu der immer ein neuer Schuss hinzugefügt werden muss. Ich bin mir gerade ehrlich gesagt nicht ganz sicher, ob aktuell die Schüsse übereinander sind, oder wie das gerade aussieht. Hier ist mein Code.
import pygame
import sys
pygame.init()
class Laser:
def __init__(self):
self.x_bullet= -20
self.y_bullet= 300
self.laser_img = None
self.x_bullet_speed = 0
self.y_bullet_speed = 0
self.cooldown = True
self.bullet = pygame.image.load(("BlueShot.PNG"))
self.bullets = []
def Cooldown(self):
pass
def Bullets(self, window, x_bullet):
for self.bullet in self.bullets:
window.blit(self.bullet,(x_bullet ,self.y_bullet ))
def MoveLasers(self):
print(self.x_bullet)
print(self.bullets)
self.bullets.append(self.bullet)
for self.bullet in self.bullets:
self.y_bullet_speed = -0.01
self.x_bullet = 200
def Movement(self):
self.y_bullet+= self.y_bullet_speed
self.x_bullet += self.x_bullet_speed
LASERS = Laser()
class Ship:
def __init__(self):
self.width = 500
self.height = 500
self.mov_speedright = 0
self.mov_speedleft = 0
self.x_ship = 250
self.x_bullet = -40
def Shoot(self):
pass
def Shotupstairs(self):
self.x_bullet= self.x_ship
def Screen(self):
self.screen = pygame.display.set_mode([self.width, self.height])
def Ship(self):
LASERS.Bullets(self.screen, self.x_bullet)
pygame.draw.rect(self.screen, (255,255,0),(self.x_ship,400, 20,200), 0)
def Border(self):
if self.x_ship <= 0:
self.mov_speedleft = 0
self.x_ship = 1
if self.x_ship >= 481:
self.mov_Speedright = 0
self.x_ship = 480
def PlayMovLeft(self):
self.mov_speedleft = -0.5
def PlayMovRight(self):
self.mov_speedright = 0.5
def PlayMovRightSt(self):
self.mov_speedleft = 0
def PlayMovLeftSt(self):
self.mov_speedright = 0
def Movement(self):
self.x_ship += self.mov_speedright
self.x_ship += self.mov_speedleft
def main():
SHIP = Ship()
SHIP.Screen()
start = True
while start:
SHIP.Shoot()
SHIP.Screen()
SHIP.Ship()
SHIP.Border()
SHIP.Movement()
LASERS.Movement()
pygame.display.flip()
#screen.fill(0,0)
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
if event.type == pygame.KEYDOWN:
# moving
if event.key == pygame.K_a:
SHIP.PlayMovLeft()
if event.key == pygame.K_d:
SHIP.PlayMovRight()
# shooting
if event.key == pygame.K_w:
LASERS.MoveLasers()
SHIP.Shotupstairs()
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
SHIP.PlayMovRightSt()
if event.key == pygame.K_d:
SHIP.PlayMovLeftSt()
main()
Space Invaders Schussystem
`pygame.init()` gehört in main und ebenso gehört da ein `pygame.quit()` dazu.
Variablennamen, Methoden und Funktionen schreibt man komplett klein. Nur Konstanten schreibt man KOMPLETT_GROSS. Und werder LASER noch SHIP sind Konstanten.
`LASER` ist eine globale Variable, die es nicht geben darf, kommt also auch in `main` und muß entsprechen Ship übergeben werden.
Methoden sollten nach Tätigkeiten benannt werden, `Bullets` ist keine Tätigkeit und kollidiert mit dem Attribut `bullets` wenn es denn richtigerweise klein geschrieben wäre.
Wenn die Laufvariable einer for-Schleife ein Attribut ist, dann macht man garantiert etwas falsch, weil Attribute ja nur dazu da sind, Zustand über das Ende der Methode hinaus zu speichern.
Die Liste `self.bullets` ist nicht sehr sinnvoll, weil da ja immer nur die selbe Image-Instanz drinsteht. Statt dessen muß aber die Position des Bullets in einer Liste gespeichert werden. Statt dessen hast Du für alle Bullets die selben x- und y-Koordinaten.
In `main` ist die Variable `start` immer True, kann also auch weggelassen werden. sys.exit benutzt man nicht. Das Programm endet, wenn die main-Funktion (z.B. per `return`) verlassen wird.
Variablennamen, Methoden und Funktionen schreibt man komplett klein. Nur Konstanten schreibt man KOMPLETT_GROSS. Und werder LASER noch SHIP sind Konstanten.
`LASER` ist eine globale Variable, die es nicht geben darf, kommt also auch in `main` und muß entsprechen Ship übergeben werden.
Methoden sollten nach Tätigkeiten benannt werden, `Bullets` ist keine Tätigkeit und kollidiert mit dem Attribut `bullets` wenn es denn richtigerweise klein geschrieben wäre.
Wenn die Laufvariable einer for-Schleife ein Attribut ist, dann macht man garantiert etwas falsch, weil Attribute ja nur dazu da sind, Zustand über das Ende der Methode hinaus zu speichern.
Die Liste `self.bullets` ist nicht sehr sinnvoll, weil da ja immer nur die selbe Image-Instanz drinsteht. Statt dessen muß aber die Position des Bullets in einer Liste gespeichert werden. Statt dessen hast Du für alle Bullets die selben x- und y-Koordinaten.
In `main` ist die Variable `start` immer True, kann also auch weggelassen werden. sys.exit benutzt man nicht. Das Programm endet, wenn die main-Funktion (z.B. per `return`) verlassen wird.
-
- User
- Beiträge: 23
- Registriert: Sonntag 12. September 2021, 06:01
OK, vielen Dank, für deine schnelle Antwort, also ich hatte bereits auch schon Probleme, mit den Variablen, da ich nicht genau weiß, wie ich die dann übergeben soll, wie mach ich das denn dann richtig? Wie kann ich Variablen aus Laser sozusagen in Ship einbinden, dass ich das dann verwenden kann? Und wegen der Liste verstehe ich nicht genau, was es mir bringen soll, wenn ich die Positionen in der Liste gespeichert habe? Das Problem ist doch eigentlich, dass ich nur eine Grafik zur Verfügung habe und mit der Liste mehrere Grafiken speichern kann und damit doch die Schüsse erstellen kann. Was bringen mir denn da die Positionen der Schüsse? Oder brauch ich denn 2 Listen, wo einmal die Pos und dann der Sprite drinnen ist? Und wie schaff ich das denn, das die Positionen von einander unabhängig sind? Danke für eine Antwort.
Du musst doch nicht mehrfach die Grafik speichern. Die reicht einmal, die ist ja nie anders. Aber du *musst* jede Schusskoordinate speichern. Sonst geht's nicht.
Und Variablen uebergibt man zB via Konstruktor, so dass ein Ship immer einen Laser als Argument bekommt.
Und Variablen uebergibt man zB via Konstruktor, so dass ein Ship immer einen Laser als Argument bekommt.