Python Forum
[PyGame] positioning the laser
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] positioning the laser
#5
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!!

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()

Attached Files

Thumbnail(s)
       
Reply


Messages In This Thread
positioning the laser - by flash77 - Jun-16-2024, 01:31 PM
RE: positioning the laser - by flash77 - Jun-17-2024, 02:48 PM
RE: positioning the laser - by deanhystad - Jun-19-2024, 03:10 AM
RE: positioning the laser - by flash77 - Jun-24-2024, 05:56 PM
RE: positioning the laser - by flash77 - Jun-27-2024, 05:23 PM
RE: positioning the laser - by deanhystad - Yesterday, 07:28 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020