wrong update (“move”) function of endboss laser, please help me to correct it (python / pygame)

I’m programming an endboss for my space invaders game.
I don’t provide the full code of my game, but just the part I’ve got problems with. (It would be to much content and it would be hard to orientate.)
So I post some dummy code to work with (I will implement the solved problem to the whole code later).

(The instantiation of the endboss laser is in line 166.)

In the class EndBossLaser:
with “def init” and “def rotate_laser_around_endboss_center” the laser is placed at the EndBossGun’s tip.
This works perfect. To check this, I commented out “def update” of the EndBossLaser class – everything works fine.

I’ve got problems with the “def update” of the EndBossLaser class.
When I don’t comment out “def update” of the EndBossLaser class the problems occurs.

In picture1 you can see that, if the player is right downwards of the endboss’s center, the laser comes correctely out of the endboss’s gun.

In picture2 you can see the problem:
There is an offset.

When the “def update” of the EndBossLaser class is commented out, the laser stays at the gun’s tip, no matter in which angle the gun is rotated, everything works fine.

When I don’t comment out “def update” of the EndBossLaser class, the part which moves the laser is active. The error must be in this function.

I don’t know how to correct this.

It would be great, if someone could tell me how to make it right!!

Thank you very much 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"
end_boss_gun_length = 100


# how to entry
# pygame.transform.rotate(degrees)
# math.cos(radians)


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))
        gun_tip_x = end_boss_centerx + end_boss_gun_length * math.cos(self.angle / 180 * math.pi)
        gun_tip_y = end_boss_centery + end_boss_gun_length * math.sin(self.angle / 180 * math.pi)
        return self.angle, gun_tip_x, gun_tip_y


# 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_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.image = pygame.transform.rotate(self.clean_image, angle)
        self.rect = self.image.get_rect()
        # laser starts at the gun's end
        self.rect.center = self.x, self.y

    def rotate_laser_around_endboss_center(self, point, pivot_point=(end_boss_centerx, end_boss_centery)):
        # justify laser in the same angle of the gun
        angle_radians = self.angle / 180 * math.pi
        # point: is the point to be rotated
        x, y = point
        # pivot_point: is the point around which the point is rotated
        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
        # qx, qy: new position of the point which was rotated
        self.rect.center = qx, qy

    def update(self):
        self.x += math.cos(self.angle / 180 * math.pi)
        self.y += math.sin(self.angle / 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, gun_tip_x, gun_tip_y = 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(gun_tip_x, gun_tip_y, angle)
                end_boss_laser_group.add(end_boss_laser)
                end_boss_laser.rotate_laser_around_endboss_center(end_boss_laser_start_pos)
                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()
[![enter image description here][1]][1]

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật