Python Forum
[PyGame] positioning the laser
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] positioning the laser
#3
Let pygame do the math. Below I use a 2D vector to compute the location of the rotated part relative to the base object. For you the rotated part is the laser, and the base object is the turret.
import pygame
from PIL import Image


class Block(pygame.sprite.Sprite):
    """Simple sprite that creates a rectamgle image."""
    def __init__(self, color, width, height):
        super().__init__()
        pygame.sprite.Sprite.__init__(self)
        image = Image.new("RGBA", (width, height), color)
        self.image = pygame.image.fromstring(image.tobytes(), image.size, image.mode)
        self.clean_image = self.image.copy()
        self.rect = self.image.get_rect()

    @property
    def center(self):
        """Return center of image."""
        return self.rect.center

    @center.setter
    def center(self, coordinates):
        """Set center of image."""
        self.rect.center = coordinates

    def rotate(self, angle):
        """Rotate angle degreec CCW about the center."""
        center = self.center
        self.image = pygame.transform.rotate(self.clean_image, angle)
        self.rect = self.image.get_rect()
        self.center = center


class Component(Block):
    """A sprite that is part of a component sprite."""
    def __init__(self, color, width, height, offset):
        super().__init__(color, width, height)
        self.base = None
        self.offset = pygame.math.Vector2(offset)

    def rotate(self, angle):
        """Rotate angle degrees CCW about the base."""
        super().rotate(angle)
        self.center = self.base.center + self.offset.rotate(-angle)


class Composite:
    """A "sprite" made up of multiple sprites."""
    def __init__(self, base):
        self.base = base
        self.parts = []
        self.group = pygame.sprite.Group(base)
        self.angle = 0
        self.x, self.y = base.center

    def add_part(self, part):
        """Add a part that moves witht he base."""
        part.base = self.base
        self.parts.append(part)
        self.group.add(part)

    def move(self, dx=0):
        """Move the sprites forward or backward."""
        x, y = pygame.math.Vector2(dx, 0).rotate(-self.angle)
        self.x += x
        self.y += y
        self.base.center = self.x, self.y

    def rotate(self, angle):
        """Increment/decrement the rotation angle.."""
        self.angle = (self.angle + angle) % 360

    def draw(self, screen):
        """Update and draw all the sprites."""
        for sprite in self.group:
            sprite.rotate(self.angle)
        self.group.draw(screen)


pygame.init()
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

turret = Composite(Block("yellow", 30, 60))
turret.add_part(Component("blue", 60, 10, (45, 20)))
turret.add_part(Component("green", 80, 5, (55, 0)))
turret.add_part(Component("red", 60, 10, (45, -20)))
turret.add_part(Component("green", 10, 20, (100, 0)))

running = True
key_down = None
dx = 1
rx = 0.5
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            key_down = event.key
        elif event.type == pygame.KEYUP:
            key_down = None

    if key_down == pygame.K_LEFT:
        turret.rotate(rx)
    elif key_down == pygame.K_RIGHT:
        turret.rotate(-rx)
    elif key_down == pygame.K_UP:
        turret.move(dx)
    elif key_down == pygame.K_DOWN:
        turret.move(-dx)

    screen.fill("black")
    turret.draw(screen)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
flash77 likes this post
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