user5173712
user5173712

Reputation:

How to make a perfect circlular pattern for bullet hell in pygame?

I'm messing around making a bullet hell game using pygame. I'm trying to make a circular spread pattern. The following piece of code has had me stuck. Below is the class of my bullet with an update function that updates the bullets position

class Bullet(pygame.sprite.Sprite):

def __init__(self, angle):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load(os.path.join(img_folder, "bullet.png")).convert()
    self.image.set_colorkey(BLACK)
    self.rect = self.image.get_rect()
    self.rect.center = (WIDTH / 2 , HEIGHT / 2)
    self.angle = angle
    self.counter = 0
    self.speedx = 5
    self.speedy = 5

def update(self):

    self.rect.x += self.speedx * math.cos(math.radians(self.angle)) 
    self.rect.y += self.speedy * math.sin(math.radians(self.angle))
    if(self.rect.right > 640 or self.rect.left < 0 or self.rect.bottom > 480 or self.rect.top < 0):
        self.kill()

The patterns group function was created as

for x in range(12):
    bullet_sprite1.add(Bullet(angle))
    angle += 30

While the pattern is generated it does not create a perfect circle as you can see here

How can I go about making it a perfect circular spread

Upvotes: 1

Views: 1313

Answers (1)

skrx
skrx

Reputation: 20468

This problem occurs because pygame.Rects can't have floats as their x and y coordinates and pygame just truncates the floats that you assign to the rect. You can add two more attributes self.posx and self.posy to store and update the actual position and then assign them to self.rect.center.

class Bullet(pygame.sprite.Sprite):

    def __init__(self, angle):
        # Rest of the attributes omitted.
        self.speedx = 5 * math.cos(math.radians(self.angle)) 
        self.speedy = 5 * math.sin(math.radians(self.angle))
        self.posx = self.rect.centerx
        self.posy = self.rect.centery

    def update(self):
        self.posx += self.speedx
        self.posy += self.speedy
        self.rect.center = (self.posx, self.posy)
        if (self.rect.right > 640 or self.rect.left < 0
                or self.rect.bottom > 480 or self.rect.top < 0):
            self.kill()

You could also use vectors.

from pygame.math import Vector2

class Bullet(pygame.sprite.Sprite):

    def __init__(self, angle):
        # Rest of the attributes omitted.
        self.rect = self.image.get_rect(center=(WIDTH / 2 , HEIGHT / 2))
        self.velocity = Vector2(1, 0).rotate(angle) * 5
        self.pos = Vector2(self.rect.center)

    def update(self):
        self.pos += self.velocity
        self.rect.center = self.pos

Upvotes: 0

Related Questions