|
|
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)
|