Space Invaders Schussystem

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
Raphael_155
User
Beiträge: 23
Registriert: Sonntag 12. September 2021, 06:01

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()
Sirius3
User
Beiträge: 17793
Registriert: Sonntag 21. Oktober 2012, 17:20

`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.
Raphael_155
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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Antworten