You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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)