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: