Hi, I managed to roughly rotate the laser around the center of the end boss.
I created the laser at a starting position and then rotated it by the angle alpha around the center of the end boss.
I also had to rotate the laser image itself by the angle alpha.
Unfortunately, I haven't managed to properly apply deanhystad's solution to my game yet - I'm very sorry...
So I experimented with the code I posted below.
I changed the endboss gun from a double turret into a single gun, which extension line runs through the endboss's center.
I thought it would lead to easier calculations.
Now the endboss can shoot...
When the player is right downward the endboss's center, the laser comes out of the gun correctely (picture1).
In picture2 you can see that there is an offset.
I will be very thankful for hints how this can be fixed!!
Thanks a lot in advance!!
I created the laser at a starting position and then rotated it by the angle alpha around the center of the end boss.
I also had to rotate the laser image itself by the angle alpha.
Unfortunately, I haven't managed to properly apply deanhystad's solution to my game yet - I'm very sorry...
So I experimented with the code I posted below.
I changed the endboss gun from a double turret into a single gun, which extension line runs through the endboss's center.
I thought it would lead to easier calculations.
Now the endboss can shoot...
When the player is right downward the endboss's center, the laser comes out of the gun correctely (picture1).
In picture2 you can see that there is an offset.
I will be very thankful for hints how this can be fixed!!
Thanks a lot in advance!!
import pygame from math import radians, sin, cos import math from pygame import Vector2 pygame.init() screen_width = 800 screen_height = 600 fps = 60 end_boss_cooldown = 3000 # bullet cooldown in milliseconds screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("End Boss Example") ship_image_path = "ship_4.png" gun_image_path = "singleGun.png" laser_image_path = "endboss_laser2.png" class EndBossGun(pygame.sprite.Sprite): def __init__(self, x, y, angle): super().__init__() self.x = x self.y = y self.angle = angle self.image = pygame.image.load(gun_image_path) self.gun_image = self.image.copy() self.rect = self.gun_image.get_rect() self.rect.center = (x, y) self.last_shot = pygame.time.get_ticks() def aim(self, p): # Rotate end_boss' gun x_dist = p[0] - self.x y_dist = self.y - (screen_height - 100) self.angle = math.degrees(math.atan2(y_dist, x_dist)) + 90 self.image = pygame.transform.rotate(self.gun_image, self.angle) self.rect = self.image.get_rect(center=(self.x, self.y)) return self.angle # Create EndBoss class class EndBoss(pygame.sprite.Sprite): def __init__(self, x, y, health): super().__init__() self.x = x self.y = y self.health_start = health self.health_remaining = health self.image = pygame.image.load(ship_image_path) self.rect = self.image.get_rect() self.rect.center = (x, y) # Initialize objects end_boss_centerx = screen_width / 2 end_boss_centery = 195 end_boss_center = end_boss_centerx, end_boss_centery end_boss = EndBoss(end_boss_centerx, end_boss_centery, 300) end_boss_group = pygame.sprite.Group() end_boss_group.add(end_boss) end_boss_gun = EndBossGun(end_boss_centerx, end_boss_centery, 0) end_boss_gun_group = pygame.sprite.Group() end_boss_gun_group.add(end_boss_gun) end_boss_gun_length = 100 end_boss_laser_start_pos = end_boss_centerx, end_boss_centery + end_boss_gun_length end_boss_laser_group = pygame.sprite.Group() # Create EndBossLaser class class EndBossLaser(pygame.sprite.Sprite): def __init__(self, x, y, angle): pygame.sprite.Sprite.__init__(self) self.x = x self.y = y self.angle = angle self.image = pygame.image.load(laser_image_path) self.clean_image = self.image.copy() self.rect = self.image.get_rect() # laser starts at the gun's end self.rect.center = end_boss_gun.rect.midbottom def rotate_laser_around_endboss_center(self, point, angle, pivot_point=(end_boss_centerx, end_boss_centery)): # justify laser in the same angle of the gun angle_radians = angle / 180 * math.pi x, y = point offset_x, offset_y = pivot_point adjusted_x = (x - offset_x) adjusted_y = (y - offset_y) cos_rad = math.cos(angle_radians) sin_rad = math.sin(angle_radians) qx = offset_x + cos_rad * adjusted_x + sin_rad * adjusted_y qy = offset_y + -sin_rad * adjusted_x + cos_rad * adjusted_y self.rect.center = qx, qy self.image = pygame.transform.rotate(self.clean_image, angle) def update(self): self.x += math.cos((-self.angle + 90) / 180 * math.pi) self.y += math.sin((-self.angle + 90) / 180 * math.pi) self.rect.center = self.x, self.y def draw_bg(): screen.fill((0, 0, 0)) # Dummy spaceship class for testing class Spaceship(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((50, 50)) self.image.fill((255, 255, 255)) self.rect = self.image.get_rect() self.rect.center = (screen_width // 2, screen_height - 50) def update(self): pass def move(self, x): self.rect.centerx = x spaceship = Spaceship() spaceship_group = pygame.sprite.Group() spaceship_group.add(spaceship) single_bullet_group = pygame.sprite.Group() explosion_group = pygame.sprite.Group() font40 = pygame.font.Font(None, 40) def draw_text(text, font, color, x, y): img = font.render(text, True, color) screen.blit(img, (x, y)) def play_end_boss_level(): game_over = 0 last_count = pygame.time.get_ticks() last_end_boss_shot = pygame.time.get_ticks() countdown = 3 run = True while run: p = pygame.mouse.get_pos() clock.tick(fps) draw_bg() if countdown == 0: angle = end_boss_gun.aim(p) time_now = pygame.time.get_ticks() if time_now - last_end_boss_shot > end_boss_cooldown and len(end_boss_group) > 0: # start position laser end_boss_laser = EndBossLaser(end_boss_centerx, end_boss_centery + end_boss_gun_length, angle) end_boss_laser_group.add(end_boss_laser) end_boss_laser.rotate_laser_around_endboss_center(end_boss_laser_start_pos, angle) last_end_boss_shot = time_now if len(end_boss_group) == 0: game_over = 1 if game_over == 0: spaceship.update() single_bullet_group.update() end_boss_group.update() end_boss_gun_group.update() explosion_group.update() end_boss_laser_group.update() else: if game_over == -1: draw_text('GAME OVER!', font40, (255, 255, 255), int(screen_width / 2 - 100), int(screen_height / 2 + 50)) if game_over == 1: draw_text('YOU WIN!', font40, (255, 255, 255), int(screen_width / 2 - 100), int(screen_height / 2 + 50)) if countdown > 0: draw_text('GET READY!', font40, (255, 255, 255), int(screen_width / 2 - 110), int(screen_height / 2 + 50)) draw_text(str(countdown), font40, (255, 255, 255), int(screen_width / 2 - 10), int(screen_height / 2 + 100)) count_timer = pygame.time.get_ticks() if count_timer - last_count > 1000: countdown -= 1 last_count = count_timer spaceship_group.draw(screen) single_bullet_group.draw(screen) explosion_group.draw(screen) end_boss_group.draw(screen) end_boss_gun_group.draw(screen) end_boss_laser_group.draw(screen) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False spaceship.move(p[0]) pygame.display.flip() pygame.quit() clock = pygame.time.Clock() if __name__ == "__main__": play_end_boss_level()