Python Forum
[PyGame] positioning the laser
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] positioning the laser
#1
Hello dear experts,

I have a last difficult problem to solve with my space invaders clone.
I need some help with this. It involves the boss's turret rotating on its own axis while aiming at the moving player.
The turret has 2 cannons.

I would like to work out a solution for the right cannon only first (I will try to apply the solution to the left cannon later).

The turret rotates and aims at the player, firing a laser every few seconds. I managed to get the laser to fire at the current angle of the right cannon.
The problem is the positioning of the laser when firing - its end should be at the end of the right cannon at the start of firing.

In the picture "positioning is not correct" you can see what is hapening - the laser is not at the right cannon's end.
You can see where the laser is placed when rotating the gun.

I tried to make a modell where the right cannon's end is (point(x,y)) when the gun rotates around the point(end_boss_centerx, end_boss_centery) with the angle alpha.

I made a drawing, which I used to get a formula for the x component and the y component of the gun's end.

The gun is orientated downwards on its picture. Because of this the angle in my code is angle = alpha - 90.

I isolated the problem of the firing end boss from my original code in a code snippet to can better focus on it.
And it is easier for someone how wants to help me too, I think.

I don't know how to make it right and can't go further.

It would be great if someone could help me to position the laser in the right place.

(I attached some pictures.)

Thanks a lot in advance!!

import pygame
from math import radians, sin, cos
import math

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 = "gun4.png"
laser_image_path = "endboss_laser.png"


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


# Create EndBossGun class
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))
        self.image = pygame.transform.rotate(self.gun_image, self.angle + 90)
        self.rect = self.image.get_rect(center=(self.x, self.y))
        return self.angle


# Create EndBossLaser class
class EndBossLaser(pygame.sprite.Sprite):
    def __init__(self, angle):
        super().__init__()
        self.angle = angle
        self.image = pygame.image.load(laser_image_path)
        self.image = pygame.transform.rotate(self.image, angle - 90)
        self.rect = self.image.get_rect()
        l = math.sqrt(11 ** 2 + 70 ** 2)
        beta = math.asin(70 / l)
        xpos = l * cos(beta - angle)
        ypos = l * sin(beta - angle)
        self.rect.center = end_boss_centerx + xpos, end_boss_centery + ypos

    def update(self, speed, angle):
        pass

# Initialize objects
end_boss_centerx = screen_width / 2
end_boss_centery = 195

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_group = pygame.sprite.Group()



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:
                end_boss_laser = EndBossLaser(angle)
                end_boss_laser_group.add(end_boss_laser)
                last_end_boss_shot = time_now

            if len(end_boss_group) == 0:
                game_over = 1

            if game_over == 0:
                end_boss_gun.update()
                spaceship.update()
                single_bullet_group.update()
                end_boss_group.update()
                end_boss_laser_group.update(1, angle)
                end_boss_gun_group.update()
                explosion_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()
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

Forum Jump:

User Panel Messages

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