Space Invaders Aliens sollen sich nicht überlappen

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.
Wired1.0.
User
Beiträge: 31
Registriert: Montag 23. Januar 2023, 20:25

Habe 3s jetzt doch alles mit der vererbung gelöst :)

Möchte momentan alle codeblöcke im main-loop in Funktionen packen. Dabei erhalte ich aber jetzt komischerweise diesen Fehler den ich nicht verstehe da ich ja eigentlich oben alles definiert habe.

Code: Alles auswählen

speed_enemy_shoot_last_count = pygame.time.get_ticks()




def speed_enemy_shoot(speed_enemy_last_count, time_to_shoot):
    speed_enemy_shoot_count = 600
    if time_to_shoot - speed_enemy_last_count > speed_enemy_shoot_count and len(speed_enemy_group) > 0:
        shooting_speed_enemy = choose_shooting_alien(speed_enemy_group)
        speed_enemy_bullet = Bullet(shooting_speed_enemy.rect.centerx, shooting_speed_enemy.rect.bottom,
                                    "death_star_laser1.png", 10)
        enemy_bullet_group.add(speed_enemy_bullet)
        return time_to_shoot




while True:
    time_now = pygame.time.get_ticks()
    speed_enemy_shoot_last_count = speed_enemy_shoot(speed_enemy_shoot_last_count, time_now)


Error: 
  File "/home/kali/PycharmProjects/pythonProject5/main.py", line 532, in <module>
    speed_enemy_shoot_last_count = speed_enemy_shoot(speed_enemy_shoot_last_count, time_now)
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kali/PycharmProjects/pythonProject5/main.py", line 463, in speed_enemy_shoot
    if time_to_shoot - speed_enemy_last_count > speed_enemy_shoot_count and len(speed_enemy_group) > 0:
       ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for -: 'int' and 'NoneType'
Benutzeravatar
grubenfox
User
Beiträge: 612
Registriert: Freitag 2. Dezember 2022, 15:49

speed_enemy_shoot liefert einen time_to_shoot nur dann zurück wenn die If-Bedingung erfüllt ist. Falls nicht, wird None zurückgeliefert.
Wired1.0.
User
Beiträge: 31
Registriert: Montag 23. Januar 2023, 20:25

Liegt auf jeden Fall am return oder besser gesagt an der Variabel welcher ich den return Wert zuweise aber ich verstehe nicht, warum das nicht geht
Wired1.0.
User
Beiträge: 31
Registriert: Montag 23. Januar 2023, 20:25

Ah ok dann packe ich die if Anweisung in den main loop. Mal sehen ob es dann fu ktioniert
Wired1.0.
User
Beiträge: 31
Registriert: Montag 23. Januar 2023, 20:25

Hat geklappt danke dafür :)

Hätte noch eine Frage. Und zwar geht es um folgenden Code:

Code: Alles auswählen

class DoubleShootPowerUp(PowerUp):

    def __init__(self, x, y):
        image = "flame.png"
        super().__init__(image, x, y)

    def apply(self, player):
        player.add_shoot_bar()
        
class PlayerSpaceship(Spaceships):
    def __init__(self):
        x = 400
        y = 515
        image = "battleship.png"
        speed = 0
        lives = 3
        super().__init__(image, speed, lives, x, y)
        self.amo = 0
        self.double_shoot = False
        self.shield_bool = False
        self.dead = False
        self.z = True
        self.move_choice = random.choice([-5, 5])
        self.last_shot = pygame.time.get_ticks()
        self.angle = 0

    def check_collision(self, game_score):
        if pygame.sprite.spritecollide(self, powerup_group, True):
            if self.shield_bool:
                pass
            else:
                for sprite in powerup_group.sprites():
                    sprite.apply(self)

Das Problem hierbei (und bei den anderen Powerups) ist, dass die collision detected wird, das powerup wird "gekillt" aber es springt nicht in die apply()- Methode. Das Problem muss beim übergebenen Parameter liegen. Ich übergebe ja player in der apply Methode aber anscheinend klappt das nicht, wenn ich in der check_collision-Methode einfach self übergebe. Habe daran gedacht bei der Mutterklasse evtl ein neues Attribut zu erstellen und da dann PlayerSpaceship drin zu speichern und dann darüber zu arbeiten aber dann würde ich ja in der apply()-Methode wieder eine globale Variable nehmen.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Code: Alles auswählen

if bedingung:
     pass
else:
    machwas..
ist ein absolutes Anti-Pattern. Wenn du keinen if-Zweig hast, dann nimm eben

Code: Alles auswählen

if not bedingung:
    machwas
Und das man kein Powerup bekommt, wenn man ein Shield hat, ist wirklich gewollte? Faende ich als Spieler ja eher kacke. Und warum iterierst du nicht ueber das Ergebnis deiner Kollisionsabfrage? Denn so bekommt man ja *jedes* Powerup, das auf Bildschirm zu sehen ist, wenn auch nur eines damit kollidiert.

Also alles in allem noch einiges an Logikfehlern, die auch mit dem Problem zu tun haben werden.
Wired1.0.
User
Beiträge: 31
Registriert: Montag 23. Januar 2023, 20:25

Der Schild funktioniert wie die raumschiffschilde in Star Wars (wenn die hochgefahren sind dann kommt nix mehr durch bis sie wieder runtergefahren sind :D)
Es wird immer nur jeweils ein powerup nach einer gewissen Zeit "spawnen" - sonst wäre das Spiel zu leicht in meinen Augen (die powerup_group ist eine "GroupSingle" -Gruppe)
Antworten