from typing import Any import random import pygame from pygame.sprite import Sprite from bullet import Bullet3, Bullet4, Bullet5 class Enemy(Sprite): # 敌人的基类 def __init__(self, ai_game): super().__init__() # 获取屏幕设置 self.screen = ai_game.screen self.screen_rect = ai_game.screen.get_rect() self.settings = ai_game.settings # 自身速度 self.speed_x = 2.0 self.speed_y = 2.0 def update(self, *args: Any, **kwargs: Any) -> None: self.moving() self.fire() def moving(self): self.rect.y += self.speed_y self.rect.x += self.speed_x if self.rect.y > self.settings.screen_height or \ self.rect.left > self.screen_rect.width or \ self.rect.right < 0: self.kill() def fire(self): pass class Rock(Enemy): def __init__(self, ai_game): super().__init__(ai_game) # 继承父类的类属性 # 导入图片 self.image_original = random.choice(self.settings.rocks_images).convert() # 从所有图片中随机取一个,并convert self.image_original.set_colorkey(self.settings.BLACK) # 将白色背景设置为透明 self.image = self.image_original self.rect = self.image.get_rect() self.radius = self.rect.height / 2 # pygame.draw.circle(self.image, self.settings.RED, self.rect.center, self.radius) # 固定出现位置 self.rect.x = random.randrange(0, self.settings.screen_width - self.rect.width) self.rect.y = 0 - self.rect.height # 速度 self.speed_x = random.randrange(-8, 8) self.speed_y = random.randrange(6, 16) # 方向检测 self.direction = 1 # 转动 self.degree = 3 self.total_degree = 0 def moving(self): self.rotate() self.rect.y += self.speed_y self.rect.x += self.speed_x * self.direction if self.rect.right > self.screen_rect.width or self.rect.left < 0: self.direction *= -1 if self.rect.y > self.settings.screen_height: self.kill() def rotate(self): self.total_degree += self.degree self.total_degree %= 360 self.image = pygame.transform.rotate(self.image_original, self.total_degree) center = self.rect.center self.rect = self.image.get_rect(center=center) class Alien1(Enemy): # 外星飞船 def __init__(self, ai_game): super().__init__(ai_game) # 继承父类的类属性 # 导入图片 self.image = random.choice(self.settings.alien1_image).convert() self.image.set_colorkey(self.settings.BLACK) self.rect = self.image.get_rect() # 进入的固定位置 self.rect.x = random.randrange(0, self.settings.screen_width - self.rect.width) self.rect.y = 0 - self.rect.height # 半径 self.radius = self.rect.height / 2 # 速度 self.speed_x = 0 self.speed_y = random.randrange(2, 4) # 开火时间 self.target = ai_game.ship self.auto_fire_time = 0 self.fire_rate = random.randrange(45, 55) def update(self, *args: Any, **kwargs: Any) -> None: self.moving() self.fire() def fire(self): if self.target.alive: if self.auto_fire_time == 0: bullet = Bullet4(self) # bullet.rect.center = self.rect.center self.settings.enemy_bullets.add(bullet) self.auto_fire_time += 1 if self.auto_fire_time > self.fire_rate: self.auto_fire_time = 0 class Alien2(Enemy): # ufo飞船 def __init__(self, ai_game): super().__init__(ai_game) # 继承父类的类属性 # 导入图片 self.rotate = False self.original = None self.image = random.choice(self.settings.alien2_image).convert() self.image.set_colorkey(self.settings.BLACK) self.rect = self.image.get_rect() # 进入的固定位置 self.rect.x = random.randrange(0, self.settings.screen_width - self.rect.width) self.rect.y = 0 - self.rect.height # 半径 self.radius = self.rect.height / 2 # 速度 self.speed_x = random.randrange(-1, 1) self.speed_y = random.randrange(5, 10) # 方向检测 self.direction = 1 # 目标为飞船 self.target = ai_game.ship # 外星飞船转向 self.angle = 0 self.angle_total = 0 # 向量 self.vect = pygame.Vector2 # 开火时间 self.auto_fire_time = 0 def update(self, *args: Any, **kwargs: Any) -> None: self.moving() self.rotate_to_ship() self.fire() def rotate_to_ship(self): self.get_ship_position() # 返回一个角度,和飞船的相对角度 if not self.rotate: self.original = self.image self.rotate = True if self.rotate: center = self.rect.center self.image = pygame.transform.rotate(self.original, -self.angle - 270) self.rect = self.image.get_rect(center=center) def get_ship_position(self): pos2 = self.vect(self.target.rect.centerx, self.target.rect.centery) # 飞船的坐标 pos1 = self.vect(self.rect.centerx, self.rect.centery) # 自身的坐标 pos0 = self.vect(0, 0) self.angle = pos0.angle_to(pos2 - pos1) # print(self.angle) def fire(self): if self.target.hp >= 0: if self.auto_fire_time == 0: bullet = Bullet3(self) bullet.rect.center = self.rect.center self.settings.enemy_bullets.add(bullet) self.auto_fire_time += 1 if self.auto_fire_time > 10: self.auto_fire_time = 0 class Alien3(Enemy): # Boss def __init__(self, ai_game): super().__init__(ai_game) # 继承父类的类属性 # 导入图片 self.images = self.settings.alienBoss_images # 列表 self.frame = 0 self.image = self.images[self.frame] self.image = pygame.transform.scale2x(self.image) self.rect = self.image.get_rect() self.last_frame = 14 self.last_time = pygame.time.get_ticks() self.now_time = pygame.time.get_ticks() self.now_time = None self.frame_rate = 0 self.temp = 0 # 进入的固定位置 self.rect.midbottom = ai_game.screen_rect.midtop self.rect.y = 0 - self.rect.height * 2 self.radius = self.rect.width / 2 # 速度 self.direction = 1 self.speed_x = 0.0 self.speed_x_flag = 0 self.speed_y = 4.0 # 开火 self.vect = pygame.Vector2 self.auto_fire_time = 0 self.fire_flag1 = 30 self.auto_fire_time2 = 0 self.fire_flag2 = 1 self.auto_fire_time3 = 0 self.fire_flag3 = 30 self.target = ai_game.ship self.angle = None # 生命值 self.hp = 200 self.alive = 1 def update(self, *args: Any, **kwargs: Any) -> None: self.change_image() self.moving() self.rotate_to_ship() self.fire() def change_image(self): if self.frame <= self.last_frame: self.image = self.images[self.frame] self.image = pygame.transform.scale2x(self.image) self.frame += 1 else: self.frame = 0 def moving(self): self.rect.y += self.speed_y self.rect.x += self.speed_x * self.direction if self.hp < 100 and self.speed_x_flag == 1: self.speed_x *= 2 self.speed_x_flag = 2 if self.rect.bottom == 200 and self.speed_x_flag == 0: while True: if self.speed_x != 0: break self.speed_x = 3 self.speed_y = 0 self.speed_x_flag = 1 if self.rect.right > self.screen_rect.width or self.rect.left < 0: self.direction *= -1 if self.rect.y > self.settings.screen_height: self.kill() def fire(self): if self.target.alive: if self.auto_fire_time == 0 and self.hp > 150: # 直线子弹和旋转子弹初级 bullet3 = Bullet3(self) bullet3.rect.center = self.rect.center bullet4 = Bullet4(self) self.settings.enemy_bullets.add(bullet3, bullet4) elif self.auto_fire_time == 0 and self.hp > 85: # 直线子弹和旋转子弹中级 bullet3 = Bullet3(self) bullet3.rect.center = self.rect.center bullet4 = Bullet4(self) self.settings.enemy_bullets.add(bullet3, bullet4) self.auto_fire_time += 1 if self.auto_fire_time > self.fire_flag1: self.auto_fire_time = 0 if self.hp <= 100: self.fire_flag1 = 20 if self.auto_fire_time2 == 0 and self.hp <= 80: # 旋转子弹高级 bullet3 = Bullet3(self) bullet3.rect.center = self.rect.center self.settings.enemy_bullets.add(bullet3) self.auto_fire_time2 += 1 if self.auto_fire_time2 > self.fire_flag2: self.auto_fire_time2 = 0 if self.auto_fire_time3 == 0 and self.hp <= 40: # 旋转子弹高级和超级光波 bullet5 = Bullet5(self) self.settings.boss_bullets.add(bullet5) self.auto_fire_time3 += 1 if self.auto_fire_time3 > self.fire_flag3: self.auto_fire_time3 = 0 def rotate_to_ship(self): self.get_ship_position() # 返回一个角度,和飞船的相对角度 def get_ship_position(self): pos2 = self.vect(self.target.rect.centerx, self.target.rect.centery) # 飞船的坐标 pos1 = self.vect(self.rect.centerx, self.rect.centery) # 自身的坐标 pos0 = self.vect(0, 0) self.angle = pos0.angle_to(pos2 - pos1)