def determine_target(self): class default: #This is a default class that has all the variables needed to move the homing bullet upwards. class rect: center = (self.pos.x, -100) rect = rect @classmethod def alive(cls): return False self.target = min(self.game.enemy_hitboxes, key=lambda x: self.pos.dist_from(PVector.from_tuple(x.rect.center)), default=default) self.target_pos = PVector.from_tuple(self.target.rect.center)
def __init__(self, game, weapon_level, pos): super().__init__(game.special_effects) i = game.frame % 50 + 1 # between 1 and 50 image = GFX[f'fire1_ {i//10}{i%10}'] # If number is less than 10, will have 0 at start size = (PVector.from_tuple(image.get_size()) / 10 * weapon_level).trunc() self.image = pygame.transform.scale(image, tuple(size)) self.rect = self.image.get_rect(center=tuple(pos))
def update_img(self): self.target = self.find_target_pos() angle = self.pos.angle_to(self.target) # radians self.bullet_pos = self.pos.project(angle, self.radius) rot_ang = degrees(angle) + 90 self.image = self.orig_image.copy() o_dim = PVector.from_tuple(self.turret_image.get_size()) rot_turret_image = pygame.transform.rotate(self.turret_image.copy(), rot_ang) n_dim = PVector.from_tuple(rot_turret_image.get_size()) top_left_adjust = (n_dim - o_dim) / 2 # explanation: when we rotate an image, new padding will be automatically added to fit the new dimensions. # Pygame blits images using top left. # This means the original "center" will be moved to somewhere that's not the center. # To be precise, it will be shifted (n.width-o.width)/2 pixels right, # since "extra" padding is added to the right and the left extra space. # It will also be shifted the same value down. Therefore we shift the center back. self.image.blit(rot_turret_image, tuple(-top_left_adjust)) self.image.blit(self.gun_image, (0, 0))
def update(self, *args): self.frame += 1 if self.frame > 90: self.kill() else: orig_image = GFX[f'explosion_100{self.frame//10}{self.frame%10}'] dimensions = PVector.from_tuple(orig_image.get_size()) self.image = pygame.transform.scale( orig_image, tuple((dimensions * self.ratio).trunc())) self.rect = self.image.get_rect(center=tuple(self.pos))
def move(self): if self.direction.x * self.direction.y in {-1, 1}: self.direction *= sqrt(0.5) # diagonal movement self.pos += self.direction * self.speed self.rect = self.image.get_rect(center=tuple(self.pos)) oob = self.rect.clamp(SCREENRECT) if oob != self.rect: # If we have to move the rectangle to keep it within screen boundaries # self.direction.x = 0 # Stop moving to the side self.rect = oob self.pos = PVector.from_tuple(oob.center)
def spawn_enemies(self): if self.frame % 60 == 1: # enemy_dict[f'{randint(1,5)}'](self, PVector(randint(0, 600), 0)) # enemy_dict[f'{7}'](self, PVector(randint(0, 600), 1000)) pass enemies = self.enemy_spawn_dict.get(str(self.frame)) if enemies: for enemy in enemies: new_enemy = enemy_dict[enemy](self, PVector.from_tuple( enemies[enemy])) if 'Boss' in new_enemy.__class__.__name__: self.boss = new_enemy self.enemy_spawn_dict.pop(str(self.frame))
def __init__(self, game, pos): super().__init__(game, pos) self.starting_pos = PVector.from_tuple(pos) self.target_pos = self.find_target_pos() s = self.starting_pos v = self.target_pos if not abs(s.x - v.x) <= self.vert_travel_threshold: self.a: float = float(s.y - v.y) / float(((s.x - v.x) ** 2)) self.image = GFX['e_private0'] self.orig_image = GFX['e_private0'] self.image_rotation = 0 self.rect = self.image.get_rect(center=tuple(self.starting_pos)) self.log: str = "" self.hitbox.image = pygame.Surface((20, 20)) self.hitbox.rect: pygame.Rect = self.hitbox.image.get_rect( center=(self.pos.x, self.pos.y - 6)) # hit box is the "engine" part
def update_direc(self): # print(target_pos) self.target_pos = PVector.from_tuple(self.target.rect.center) self.speed = min(self.max_speed, self.speed + 0.1) self.angle = self.pos.angle_to(self.target_pos) self.direction = PVector(0, 0).project(self.angle, self.speed)