import math from typing import Any import random import pygame from pygame.sprite import Sprite class Bullet(Sprite): # 子弹的基类 def __init__(self, ai_game): # 此处的ai_game 是一ship对象 super().__init__() # 获取屏幕设置 self.screen = ai_game.screen self.screen_rect = ai_game.screen.get_rect() self.settings = ai_game.settings self.speed_x = 0.0 self.speed_y = 5.0 def update(self, *args: Any, **kwargs: Any) -> None: self.moving() def moving(self): self.rect.centerx += self.speed_x self.rect.centery += self.speed_y if self.rect.top > self.screen_rect.height or \ self.rect.top < 0 or self.rect.left < 0 or \ self.rect.right > self.screen_rect.width: self.kill() class Bullet1(Bullet): # 按下r键的追踪导弹 def __init__(self, ai_game): super().__init__(ai_game) # 获取飞船 self.attached_ship = ai_game # 获取子弹的图片 self.image = pygame.image.load("resource/image/bullet1.png").convert() self.image.set_colorkey(self.settings.BLACK) self.rect = self.image.get_rect() self.original = None # 子弹速度 self.speed = 16 self.speed_x = 2 self.speed_y = 2 # 子弹位置 self.rect.center = ai_game.rect.midtop # 子弹跟踪精灵 self.target = random.choice(self.settings.aliens.sprites()) self.rotate = False # 图片旋转 self.angle = 0 self.dis_pos = math.sqrt(pow(self.settings.screen_width, 2) + pow(self.settings.screen_height, 2)) # 向量 self.vect = pygame.Vector2 # 播放声音 sound = pygame.mixer.Sound("resource/Bonus/sfx_laser2.ogg") sound.set_volume(0.1) sound.play() def update(self, *args: Any, **kwargs: Any) -> None: self.moving() def moving(self): # self.get_close_position() if self.target in self.settings.aliens: self.get_enemy_position() if not self.rotate: self.original = self.image self.rotate = True if self.rotate: center = self.rect.center # 获取旋转前的rect的中心 self.image = pygame.transform.rotate(self.original, -self.angle - 90) # 将原始图片进行旋转,保证不会失真 self.rect = self.image.get_rect(center=center) # 将旋转后的rect的中心与旋转前的中心对齐,保证rect也同图片一起改变 angle = self.angle * math.pi / 180 self.speed_x = self.speed * math.cos(angle) self.speed_y = self.speed * math.sin(angle) self.rect.centerx += self.speed_x self.rect.centery += self.speed_y * random.randrange(1, 3) elif self.rect.centery < 0 or self.rect.centerx > self.screen_rect.width or self.rect.centerx < 0: self.kill() else: self.rect.centerx += self.speed_x self.rect.centery += self.speed_y def get_enemy_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) def get_close_position(self): # 飞船和所有外星人的最短距离、也可以改为子弹和外星人距离最近的,欧几里得距离 if len(self.settings.aliens.sprites()) > 0: for alien in self.settings.aliens: pos1 = self.vect(alien.rect.centerx, alien.rect.centery) # 敌人的位置 pos2 = self.vect(self.rect.centerx, self.rect.centery) pos0 = pos2.distance_to(pos1) if pos0 < self.dis_pos: self.dis_pos = pos0 self.target = alien class Bullet2(Bullet): # 按下空格的子弹 def __init__(self, ai_game): super().__init__(ai_game) # 获取子弹的图片 self.image = pygame.image.load("resource/Lasers/laserRed01.png").convert() self.rect = self.image.get_rect() # 子弹设置 self.speed_x = 0 self.speed_y = 12.0 # 子弹的位置 self.rect.midbottom = ai_game.rect.midtop # 播放声音 sound = pygame.mixer.Sound("resource/Bonus/sfx_laser1.ogg") sound.set_volume(0.2) sound.play() def update(self, *args: Any, **kwargs: Any) -> None: self.moving() def moving(self): self.rect.x += self.speed_x self.rect.y -= self.speed_y if self.rect.bottom < 0: self.kill() class Bullet3(Bullet): # 敌人的子弹类 def __init__(self, ai_game): super(Bullet3, self).__init__(ai_game) # 获取子弹的图片 self.image = pygame.image.load("resource/image/bullet3.png") self.image = pygame.transform.rotate(self.image, 180) self.rect = self.image.get_rect() self.rect.bottom = ai_game.rect.bottom # 子弹的固定位置 self.angle = ai_game.angle self.speed = 5.0 self.speed_x = self.speed * math.cos(self.angle) self.speed_y = self.speed * math.sin(self.angle) def update(self, *args: Any, **kwargs: Any) -> None: self.moving() class Bullet4(Bullet): # 敌人的子弹类 def __init__(self, ai_game): super().__init__(ai_game) # 获取子弹的图片 self.image = pygame.image.load("resource/Lasers/laserBlue03.png") self.image = pygame.transform.rotate(self.image, 180) self.rect = self.image.get_rect() # 子弹的固定位置 self.rect.center = ai_game.rect.midbottom # 子弹速度 self.speed_y = 8.0 def update(self, *args: Any, **kwargs: Any) -> None: self.moving() class Bullet5(Bullet): # boss的子弹类 def __init__(self, ai_game): super().__init__(ai_game) # 获取子弹的图片 self.images = self.settings.light_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 = 9 self.temp = 0 self.rect.center = ai_game.rect.midbottom # 子弹速度 self.speed_y = 8.0 def update(self, *args: Any, **kwargs: Any) -> None: self.change() self.moving() def change(self): if self.frame <= self.last_frame and self.temp == 0: self.image = self.images[self.frame] self.image = pygame.transform.scale2x(self.image) self.frame += 1 if self.frame >= 10: self.temp = 1 elif self.temp == 1: self.frame -= 1 self.image = self.images[self.frame] self.image = pygame.transform.scale2x(self.image) if self.frame == 0: self.temp = 0