Space Invaders Aliens sollen sich nicht überlappen
Verfasst: Montag 20. März 2023, 13:57
Hi!
Ich programmiere gerade space invaders und ärgere mich darüber, dass sich die Aliens überlappen. Kann mir da evtl jemand weiterhelfen?
Ich programmiere gerade space invaders und ärgere mich darüber, dass sich die Aliens überlappen. Kann mir da evtl jemand weiterhelfen?
Code: Alles auswählen
import pygame
import random
import math
# ToDo
# - Nur ein enemy bei kollision --> bei remove wenn level implementiert
# - level implementieren
# - bei terminierung kleine explosion
# - Aliens sollen sich nicht überlappen
# - bosse grüner laserstrahl
# - t- fighter schießen 2 schuss auf einmal
# - bei Mauskick schießen
# - Vollbild implementieren
# - Pause implementieren
# - wenn alle 3 herzen weg, spaceship weg, riesen explosion, game over
# - class SpeedShootPU(PowerUps):
# - doube shoot PU erstellen
class Game:
def __init__(self, width, height):
pygame.init()
self.width = width # 7
self.height = height # 7
self.screen = pygame.display.set_mode((self.width, self.height)) # 7
pygame.display.set_caption("Space Invaders") # 5
self.running = True # 4
self.clock = pygame.time.Clock() # 6
self.background_img = pygame.image.load("background123.peg").convert() # 20
self.background_img = pygame.transform.scale(self.background_img, (width, height))
self.spaceship = Spaceship(self, 368, 515, "battleship.png") # 8
self.y = 600
self.hpu = []
self.boss = []
self.hearts = []
self.enemies = [] # 15
self.speed_enemy = []
self.player_bullet_list = []
self.speed_enemy_bullet_list = []
self.score = 0
self.counter = 0
self.enemy_shoot_counter = 0
self.clock = pygame.time.Clock()
self.heart_lives = 3
self.boss_lives = [1, 2, 3]
self.speed_enemy_lives = [1, 2]
self.ufo_lives = [1]
self.start_boss_lives = 3
self.start_speed_enemy_lives = 2
self.start_ufo_lives = 1
self.health_power_up_counter = random.randint(300, 600)
self.double_shoot_pu_counter = random.randint(500, 900)
self.shield_pu_counter = 0
self.pixel = 64
self.present_lives = 0
self.normal_speed = 5
self.speed_speed = 10
# shield-Attributes
self.shield_countdown = 6 # Countdown
self.shield_bool = False
self.shield_last_count = pygame.time.get_ticks()
self.shield_pu = []
self.shield_symbol = []
self.spaceship_shield = []
self.shield_pu_counter_pin = random.randint(100, 300)
self.shield_pu.append(ShieldPU(self, random.randint(0, 736), random.randint(-130, -60), "shield_pu.png"))
self.shield_symbol.append(ShieldSymbol(self, 20, 50, "shield_pu.png"))
self.hearts.append(Hearts(self, 20, 30, "heart.png"))
self.hearts.append(Hearts(self, 36, 30, "heart.png"))
self.hearts.append(Hearts(self, 52, 30, "heart.png"))
self.hpu.append(HealthPowerUp(self, random.randint(0, 736), random.randint(-130, -60), "passion.png"))
for i in range(0):
self.speed_enemy.append(
SpeedEnemy(self, random.randint(0, 736), random.randint(-130, -60), "t-fighter.png"))
for i in range(5):
self.boss.append(Boss(self, random.randint(0, 736), random.randint(-130, -60), "death-star.png"))
for i in range(3): # 15
self.enemies.append(Enemy(self, random.randint(0, 736), random.randint(-130, -60), "ufo.png")) # 15
while self.running: # 4
self.clock.tick(60) # 6 setzt die FPS
self.spaceship.check_collision_enemy(self.enemies)
self.spaceship.check_collision_enemy(self.speed_enemy)
self.spaceship.check_collision_enemy(self.boss)
# Beweglicher Bildschirm
self.rel_y = self.y % self.background_img.get_rect().height # 20
self.screen.blit(self.background_img, (0, self.rel_y - self.background_img.get_rect().height))
if self.rel_y < height:
self.screen.blit(self.background_img, (0, self.rel_y))
self.y += 1
for i in self.spaceship_shield:
i.update(self.spaceship)
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.KEYDOWN: # 10
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
self.spaceship.move(-10) # 10.4
if event.key == pygame.K_SPACE: # 13
self.spaceship.fire_bullet(self.player_bullet_list, "laser.png", Bullet)
if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
self.spaceship.move(10)
if event.key == pygame.K_UP or event.key == pygame.K_w:
self.spaceship.move_y(-10)
if event.key == pygame.K_DOWN or event.key == pygame.K_s:
self.spaceship.move_y(10)
if event.type == pygame.KEYUP: # 10.5
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
self.spaceship.move(10)
if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
self.spaceship.move(-10)
if event.key == pygame.K_UP or event.key == pygame.K_w:
self.spaceship.move_y(10)
if event.key == pygame.K_DOWN or event.key == pygame.K_s:
self.spaceship.move_y(-10)
# t-fighter shoot back
self.enemy_shoot_counter += 1
if self.enemy_shoot_counter >= 100:
for enemy in self.speed_enemy:
enemy.fire_bullet(self.speed_enemy_bullet_list, "laser_grey.png", SpeedBullet)
self.enemy_shoot_counter = 0
for bullet in self.speed_enemy_bullet_list:
if bullet.is_fired:
bullet.bullet_update()
else:
self.speed_enemy_bullet_list.remove(bullet)
if len(self.hearts) == 0:
self.speed_enemy_bullet_list.clear()
self.spaceship.update(0, 0) # 9
# 13.3
for bullet in self.player_bullet_list:
if bullet.is_fired:
bullet.bullet_update()
else: # 14.1
self.player_bullet_list.remove(bullet)
for enemy_speed in self.speed_enemy:
enemy_speed.update(self.speed_speed, 60)
enemy_speed.check_collision_player_bullet(self.player_bullet_list, self.speed_enemy_lives,
self.start_speed_enemy_lives)
if enemy_speed.y >= 536:
self.change_position_g_o()
self.print_game_over()
break
for end_boss in self.boss:
end_boss.check_collision_player_bullet(self.player_bullet_list, self.boss_lives, self.start_boss_lives)
end_boss.update(self.normal_speed, 60)
if end_boss.y >= 536:
self.change_position_g_o()
self.print_game_over()
break
for enemy in self.enemies:
enemy.update(self.normal_speed, 60)
enemy.check_collision_player_bullet(self.player_bullet_list, self.ufo_lives, self.start_ufo_lives)
if enemy.y >= 536: # 17
self.change_position_g_o()
self.print_game_over()
break
############################################################################################################################################################################
for enemy in self.boss:
enemy.check_collision_between_aliens(self.enemies)
for boss in self.boss:
boss.check_collision_between_aliens(self.boss)
for speed_enemy in self.speed_enemy:
speed_enemy.check_collision_between_aliens(self.speed_enemy)
self.spaceship.check_collision_enemy_bullet(self.speed_enemy_bullet_list)
# 23 Health PowerUp einfügen
if len(self.hearts) < 3:
self.counter += 1
if self.counter >= self.health_power_up_counter:
for heart in self.hpu:
heart.update()
self.spaceship.check_collision_hpu(self.hpu)
if heart.y > 600:
self.counter = 0
heart.powerup = False
self.hpu.remove(heart)
self.hpu.append(
HealthPowerUp(self, random.randint(0, 736), random.randint(-130, -60), "passion.png"))
# Shield Pu einfügen
self.shield_pu_counter += 1
if self.shield_pu_counter >= self.shield_pu_counter_pin:
for i in self.shield_pu:
i.update()
self.spaceship.check_collision_spu(self.shield_pu)
if i.y > 600:
self.shield_pu_counter = 0
i.x = random.randint(0, 736)
i.y = random.randint(-130, -60)
if self.shield_countdown > 0 and self.shield_bool == True:
for i in self.shield_symbol:
i.update(i)
self.print_shield_counter()
self.shield_count_timer = pygame.time.get_ticks()
if self.shield_count_timer - self.shield_last_count > 1000:
self.shield_countdown -= 1
self.shield_last_count = self.shield_count_timer
if self.shield_countdown <= 0:
self.shield_bool = False
self.spaceship_shield.pop()
self.check_0_hearts()
for heart in self.hearts:
heart.update(heart)
self.print_score()
pygame.display.update()
def change_position_g_o(self):
for i in self.enemies:
i.y = 1000
for i in self.speed_enemy:
i.y = 1000
for i in self.boss:
i.y = 1000
def print_game_over(self):
go_font = pygame.font.Font("freesansbold.ttf", 64)
go_text = go_font.render("GAME OVER", True, (255, 255, 255))
score_font1 = pygame.font.Font("freesansbold.ttf", 16)
go_text_score = score_font1.render("Dein Punktestand: " + str(self.score), True, (100, 200, 10))
self.screen.blit(go_text, (200, 250))
self.screen.blit(go_text_score, (325, 350))
def print_score(self):
score_font = pygame.font.Font("freesansbold.ttf", 16)
score_text = score_font.render("Punkte: " + str(self.score), True, (155, 200, 255))
self.screen.blit(score_text, (8, 8))
def check_0_hearts(self):
if len(self.hearts) <= 0:
self.change_position_g_o()
self.print_game_over()
for i in self.hpu:
i.powerup = False
def print_shield_counter(self): # countdown
countdown_font = pygame.font.Font("freesansbold.ttf", 32)
countdown_text = countdown_font.render(str(self.shield_countdown), True, (255, 255, 255))
self.screen.blit(countdown_text, (20, 50))
########################################################################################################################
class Spaceships:
def __init__(self, game, x, y, spaceship_img):
self.x = x # 8
self.y = y # 8
self.change_y = 60 # 15.2 # 10
self.game = game
self.change_x = 5
self.spaceship_img = pygame.image.load(spaceship_img) # 9
self.change_x_spaceship = 0
self.change_y_spaceship = 0
def fire_bullet(self, list_bullet_object, bullet_img, bullet_object): # 13
list_bullet_object.append(bullet_object(self.game, self.x, self.y, bullet_img))
list_bullet_object[-1].fired() # 13.2
def move_y(self, speed):
self.change_y_spaceship += speed
def move(self, speed): # 10.2
self.change_x_spaceship += speed
def check_collision_player_bullet(self, list_object, present_lives, total_enemy_lives):
for bullet in list_object:
distance = math.sqrt(math.pow(self.x - bullet.x, 2) + math.pow(self.y - bullet.y, 2))
if distance < 35:
bullet.is_fired = False
present_lives.pop()
if len(present_lives) == 0:
self.game.score += total_enemy_lives
self.x = random.randint(0, 736)
self.y = random.randint(-130, 60)
for i in range(total_enemy_lives):
present_lives.append(total_enemy_lives)
#ToDo###############################################################################################################################################################
def check_collision_between_aliens(self, list_object):
for bullet in list_object:
distance = math.sqrt(math.pow(self.x - bullet.x, 2) + math.pow(self.y - bullet.y, 2))
if distance < 35:
bullet.x =
#ToDo###############################################################################################################################################################
def update(self, change_x, change_y):
self.x += self.change_x # 15.2
if self.x >= 736:
self.change_x = - change_x
self.y += change_y
elif self.x <= 0:
self.y += change_y
self.change_x = + change_x
self.game.screen.blit(self.spaceship_img, (self.x, self.y))
def check_collision_enemy(self, list_object):
for enemy in list_object: # 21
distance = math.sqrt(math.pow(self.x - enemy.x, 2) + math.pow(self.y - enemy.y, 2))
if (distance - self.game.pixel / 2) < 35:
enemy.x = random.randint(0, 736)
enemy.y = random.randint(-130, -60)
if self.game.shield_bool == False:
self.game.hearts.pop()
else:
pass
self.game.check_0_hearts()
# elif (distance - self.game.pixel/2) < 35 and ShieldPU.powerups():
# print("")
############################################################################
class Spaceship(Spaceships):
def update(self, change_x, change_y): # 11
self.x += self.change_x_spaceship # 10.3
self.y += self.change_y_spaceship
if self.x < 0: # 12
self.x = 0
elif self.x > 736:
self.x = 736
elif self.y < 0:
self.y = 0
elif self.y > 536:
self.y = 536
self.game.screen.blit(self.spaceship_img, (self.x, self.y)) # 9
def check_collision_hpu(self, list_object):
for pu in list_object: # Health- PowerUp auf kollision checken
distance = math.sqrt(math.pow(self.x - (pu.x - 13), 2) + math.pow(self.y - (pu.y - 10), 2))
if distance < 35:
if len(self.game.hearts) == 2: # Wenn 2 Herzen: an letzter Stelle hinzufügen und hpu entfernen
self.game.hpu.pop()
self.game.hearts.append(Hearts(self.game, 52, 30, "heart.png"))
self.game.hpu.append(
HealthPowerUp(self.game, random.randint(0, 736), random.randint(-130, -60), "passion.png"))
self.game.counter = 0
if len(self.game.hearts) == 1:
self.game.hpu.pop()
self.game.hearts.append(Hearts(self.game, 36, 30, "heart.png"))
self.game.hpu.append(
HealthPowerUp(self.game, random.randint(0, 736), random.randint(-130, -60), "passion.png"))
self.game.counter = 0
def check_collision_spu(self, list_object):
for pu in list_object: # shield- PowerUp auf kollision checken
distance = math.sqrt(math.pow(self.x - (pu.x - 13), 2) + math.pow(self.y - (pu.y - 10), 2))
if distance < 35:
list_object.pop()
self.game.spaceship_shield.append(ShieldSpaceship(self.game, self.x, self.y, "shield.png"))
self.game.shield_bool = True
# start timer
def check_collision_enemy_bullet(self, list_object):
for bullets in list_object:
distance = math.sqrt(math.pow(self.x - bullets.x, 2) + math.pow(self.y - bullets.y, 2))
if distance < 35:
bullets.is_fired = False
if self.game.shield_bool == False:
self.game.hearts.pop()
self.game.check_0_hearts()
else:
pass
########################################################################################################################
# Powerup classes
class PowerUps:
def __init__(self, game, x, y, powerup_img):
self.x = x
self.y = y
self.change_y = 5
self.game = game
self.powerup_img = pygame.image.load(powerup_img)
self.powerup = False
def powerups(self):
self.powerup = True
def update(self):
self.y += self.change_y
self.game.screen.blit(self.powerup_img, (self.x, self.y))
class HealthPowerUp(PowerUps):
pass
class DoubleShootPU(PowerUps):
pass
class ShieldPU(PowerUps):
pass
class Hearts:
def __init__(self, game, x, y, image):
self.x = x
self.y = y
self.game = game
self.heart = True #################################################################################################################################################
self.img = pygame.image.load(image)
def heart(self):
self.heart = True
def update(self, object):
self.game.screen.blit(self.img, (object.x, object.y))
class ShieldSymbol(Hearts):
pass
class ShieldSpaceship(Hearts):
pass
############################################################################
# Enemy-Classes
class SpeedEnemy(Spaceships):
pass
class Boss(Spaceships):
pass
class Enemy(Spaceships): # 15
pass
########################################################################################################
# Bullet Classes
class Bullet: # 13
def __init__(self, game, x, y, bullet_img):
self.x = x
self.y = y
self.is_fired = False
self.bullet_speed = 10
self.game = game
self.bullet_img = pygame.image.load(bullet_img)
def fired(self): # 13.2
self.is_fired = True
def bullet_update(self):
self.y -= self.bullet_speed # 14
if self.y < -20:
self.is_fired = False
self.game.screen.blit(self.bullet_img, (self.x + 30, self.y))
class SpeedBullet(Bullet):
def bullet_update(self):
self.y += self.bullet_speed
if self.y > 600:
self.is_fired = False
self.game.screen.blit(self.bullet_img, (self.x + 30, self.y))
if __name__ == "__main__":
game = Game(800, 600)
# if len(enemy.bullets) > 0:
# unnötiger check, for loop läuft ja nur bei größer 0
# if bullet.fired(): # falscher check hier
# die update methode wird nur alle 10 ticks aufgerufen. das geht nicht
# unnötige if. for loop läuft nur wenn mehr als 0
# if len(self.spaceship.bullets) > 0: