How to make randomly generated balloons that show up every time you shoot a bullet?

Viewed 234

I'm trying to make it so that my game will randomly generated balloons at the top and push every other balloon down to make space for the new balloons when I shoot a bullet. I have 6 balloon classes and was trying to make them get randomly generated, but the codes I have tried to make for it is ending up in failures.

At first I tried to tell it when my bullet disappears then just print something but the problem is that the code I used would instantly make it disappear. I also tried drawing new balloons when the bullet collides with balloon's, but I'm I'm not sure where to place the balloons and how to move them.

This is what I tried

for bullet in bullets:
    if bullets.pop(bullets.index(bullet)):
        print("collide")

My full code

import pygame,math,random
pygame.init()

# Windowing screen width and height
width = 500
height = 500
window = pygame.display.set_mode((width,height))

# Name of window
pygame.display.set_caption("Game")

# The Background
background = pygame.image.load("img/BG.png")

def blitRotate(surf, image, pos, originPos, angle):
    # calcaulate the axis aligned bounding box of the rotated image
    w, h         = image.get_size()
    sin_a, cos_a = math.sin(math.radians(angle)), math.cos(math.radians(angle)) 
    min_x, min_y = min([0, sin_a*h, cos_a*w, sin_a*h + cos_a*w]), max([0, sin_a*w, -cos_a*h, sin_a*w - cos_a*h])

    # calculate the translation of the pivot 
    pivot        = pygame.math.Vector2(originPos[0], -originPos[1])
    pivot_rotate = pivot.rotate(angle)
    pivot_move   = pivot_rotate - pivot

    # calculate the upper left origin of the rotated image
    origin = (pos[0] - originPos[0] + min_x - pivot_move[0], pos[1] - originPos[1] - min_y + pivot_move[1])

    # get a rotated image
    rotated_image = pygame.transform.rotate(image, angle)

    # rotate and blit the image
    surf.blit(rotated_image, origin)
    
# Player class
class Player:
    def __init__(self,x,y,width,height,color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.color = color
        self.speed = 4
        self.cannon = pygame.image.load("img/Cannon.png")
        self.cannon = pygame.transform.scale(self.cannon,(self.cannon.get_width()//2, self.cannon.get_height()//2))
        self.rect = pygame.Rect(x,y,width,height)
        self.hitbox = (self.x,self.y,30,30)
        self.image = self.cannon
        self.rect  = self.image.get_rect(center = (self.x, self.y))
        self.look_at_pos = (self.x, self.y)

        self.isLookingAtPlayer = False
        self.look_at_pos = (x,y)

        self.angle = 0
    def get_rect(self):
        self.rect.topleft = (self.x,self.y)
        return self.rect

    def get_pivot(self):
        player_rect = self.cannon.get_rect(center = self.get_rect().center)
        return player_rect.centerx, player_rect.top + 103

    def get_angle(self):
        pivot_abs = self.get_pivot()
        dx = self.look_at_pos[0] - pivot_abs[0]
        dy = self.look_at_pos[1] - pivot_abs[1]
        return math.degrees(math.atan2(-dy, dx))

    def get_top(self):
        pivot_x, pivot_y = self.get_pivot()
        angle = self.get_angle()
        length = 100
        top_x = pivot_x + length * math.cos(math.radians(angle))
        top_y = pivot_y - length * math.sin(math.radians(angle))
        return top_x, top_y

    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.hitbox)

        gun_size = self.image.get_size()
        pivot_abs = self.get_pivot()
        pivot_rel = (gun_size[0] // 2, 105)
        angle = self.get_angle() - 90
        
        pygame.draw.rect(window,self.color,self.rect)
        blitRotate(window, self.image,pivot_abs, pivot_rel, angle)
        
    def lookAt( self, coordinate ):
        self.look_at_pos = coordinate


        

# Players gun
class projectile(object):
    def __init__(self,x,y,dirx,diry,color):
        self.x = x
        self.y = y
        self.dirx = dirx
        self.diry = diry
        self.pin = pygame.image.load("img/Pin.png")
        self.pin = pygame.transform.scale(self.pin,(self.pin.get_width()//6, self.pin.get_height()//6))
        self.rect = self.pin.get_rect()
        self.center = ( self.x, self.y )
        self.speed = 10
        self.color = color
        self.hitbox = (self.x + 20, self.y, 30,40)
    def move(self):
        self.x += self.dirx * self.speed
        self.y += self.diry * self.speed
    def draw(self):
        self.rect.center = (round(self.x), round(self.y))
        
        angle = math.degrees(math.atan2(-self.diry, self.dirx)) - 90
        rotated_pin = pygame.transform.rotate(self.pin, angle)
        rotated_rect = rotated_pin.get_rect(center = self.rect.center)

        window.blit(rotated_pin, rotated_rect)
        self.hitbox = (self.x + 20, self.y,30,30)
        
# Green balloon
class Gballoon:
    def __init__(self,x,y,width,height,color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.balloon = [pygame.image.load("img/Green_balloon" + str(i) + ".png") for i in range(1,2)]
        self.balloon2 = [pygame.image.load("img/Green_balloon" + str(i) + ".png") for i in range(1,7)]
        self.color = color
        self.speed = 2
        self.rect = pygame.Rect(x,y,width,height)
        self.fps = 10
        self.clock = pygame.time.Clock()
        self.next_frame_time = 0
        self.anim_index = 0
        self.hitbox = (self.x - 50, self.y - 18, 40, 40)
        self.balloon = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon]
        self.balloon2 = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon2]
        self.direction = "greenpop"
        self.direction = "balloon"
    def get_rect(self):
        self.rect.topleft = (self.x,self.y)
        return self.rect
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect,2)
        pygame.draw.rect(window,self.color,self.hitbox)
        self.hitbox = (self.x + 35, self.y + 0, 40, 40)
        # calling the balloon and balloon2 in and image list
        if self.direction == "balloon":
            image_list = self.balloon
        elif self.direction == "greenpop":
            image_list = self.balloon2
        # Is it time to show next frame
        time_now = pygame.time.get_ticks()
        if (time_now > self.next_frame_time):
            # Time until the next game
            inter_time_delay = 1000 // self.fps
            self.next_frame_time = time_now + inter_time_delay
            # Showing next frame
            self.anim_index += 1
            if self.anim_index >= len(image_list):
                self.anim_index = 0

        if self.anim_index >= len(image_list):
            self.anim_index = 0
        green_image = image_list[self.anim_index]
                    

        green_rect = green_image.get_rect(center = self.get_rect().center)
        green_rect.centerx
        green_rect.centery += 5
        window.blit(green_image,green_rect)


class Bballoon:
    def __init__(self,x,y,width,height,color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.balloon = [pygame.image.load("img/Blue_balloon" + str(i) + ".png") for i in range(1,2)]
        self.balloon2 = [pygame.image.load("img/Blue_balloon" + str(i) + ".png") for i in range(1,7)]
        self.color = color
        self.speed = 2
        self.rect = pygame.Rect(x,y,width,height)
        self.fps = 10
        self.clock = pygame.time.Clock()
        self.next_frame_time = 0
        self.anim_index = 0
        self.hitbox = (self.x - 50, self.y - 18, 40, 40)
        self.balloon = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon]
        self.balloon2 = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon2]
        self.direction = "greenpop"
        self.direction = "balloon"
    def get_rect(self):
        self.rect.topleft = (self.x,self.y)
        return self.rect
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect,2)
        pygame.draw.rect(window,self.color,self.hitbox)
        self.hitbox = (self.x + 35, self.y + 0, 40, 40)
        # calling the balloon and balloon2 in and image list
        if self.direction == "balloon":
            image_list = self.balloon
        elif self.direction == "greenpop":
            image_list = self.balloon2
        # Is it time to show next frame
        time_now = pygame.time.get_ticks()
        if (time_now > self.next_frame_time):
            # Time until the next game
            inter_time_delay = 1000 // self.fps
            self.next_frame_time = time_now + inter_time_delay
            # Showing next frame
            self.anim_index += 1
            if self.anim_index >= len(image_list):
                self.anim_index = 0

        if self.anim_index >= len(image_list):
            self.anim_index = 0
        green_image = image_list[self.anim_index]
                    

        green_rect = green_image.get_rect(center = self.get_rect().center)
        green_rect.centerx
        green_rect.centery += 5
        window.blit(green_image,green_rect)


class Oballoon:
    def __init__(self,x,y,width,height,color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.balloon = [pygame.image.load("img/Orange_balloon" + str(i) + ".png") for i in range(1,2)]
        self.balloon2 = [pygame.image.load("img/Orange_balloon" + str(i) + ".png") for i in range(1,7)]
        self.color = color
        self.speed = 2
        self.rect = pygame.Rect(x,y,width,height)
        self.fps = 10
        self.clock = pygame.time.Clock()
        self.next_frame_time = 0
        self.anim_index = 0
        self.hitbox = (self.x - 50, self.y - 18, 40, 40)
        self.balloon = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon]
        self.balloon2 = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon2]
        self.direction = "greenpop"
        self.direction = "balloon"
    def get_rect(self):
        self.rect.topleft = (self.x,self.y)
        return self.rect
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect,2)
        pygame.draw.rect(window,self.color,self.hitbox)
        self.hitbox = (self.x + 35, self.y + 0, 40, 40)
        # calling the balloon and balloon2 in and image list
        if self.direction == "balloon":
            image_list = self.balloon
        elif self.direction == "greenpop":
            image_list = self.balloon2
        # Is it time to show next frame
        time_now = pygame.time.get_ticks()
        if (time_now > self.next_frame_time):
            # Time until the next game
            inter_time_delay = 1000 // self.fps
            self.next_frame_time = time_now + inter_time_delay
            # Showing next frame
            self.anim_index += 1
            if self.anim_index >= len(image_list):
                self.anim_index = 0

        if self.anim_index >= len(image_list):
            self.anim_index = 0
        green_image = image_list[self.anim_index]
                    

        green_rect = green_image.get_rect(center = self.get_rect().center)
        green_rect.centerx
        green_rect.centery += 5
        window.blit(green_image,green_rect)


class Pballoon:
    def __init__(self,x,y,width,height,color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.balloon = [pygame.image.load("img/Pink_balloon" + str(i) + ".png") for i in range(1,2)]
        self.balloon2 = [pygame.image.load("img/Pink_balloon" + str(i) + ".png") for i in range(1,7)]
        self.color = color
        self.speed = 2
        self.rect = pygame.Rect(x,y,width,height)
        self.fps = 10
        self.clock = pygame.time.Clock()
        self.next_frame_time = 0
        self.anim_index = 0
        self.hitbox = (self.x - 50, self.y - 18, 40, 40)
        self.balloon = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon]
        self.balloon2 = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon2]
        self.direction = "greenpop"
        self.direction = "balloon"
    def get_rect(self):
        self.rect.topleft = (self.x,self.y)
        return self.rect
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect,2)
        pygame.draw.rect(window,self.color,self.hitbox)
        self.hitbox = (self.x + 35, self.y + 0, 40, 40)
        # calling the balloon and balloon2 in and image list
        if self.direction == "balloon":
            image_list = self.balloon
        elif self.direction == "greenpop":
            image_list = self.balloon2
        # Is it time to show next frame
        time_now = pygame.time.get_ticks()
        if (time_now > self.next_frame_time):
            # Time until the next game
            inter_time_delay = 1000 // self.fps
            self.next_frame_time = time_now + inter_time_delay
            # Showing next frame
            self.anim_index += 1
            if self.anim_index >= len(image_list):
                self.anim_index = 0

        if self.anim_index >= len(image_list):
            self.anim_index = 0
        green_image = image_list[self.anim_index]
                    

        green_rect = green_image.get_rect(center = self.get_rect().center)
        green_rect.centerx
        green_rect.centery += 5
        window.blit(green_image,green_rect)


class Pballoon:
    def __init__(self,x,y,width,height,color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.balloon = [pygame.image.load("img/Purple_balloon" + str(i) + ".png") for i in range(1,2)]
        self.balloon2 = [pygame.image.load("img/Purple_balloon" + str(i) + ".png") for i in range(1,7)]
        self.color = color
        self.speed = 2
        self.rect = pygame.Rect(x,y,width,height)
        self.fps = 10
        self.clock = pygame.time.Clock()
        self.next_frame_time = 0
        self.anim_index = 0
        self.hitbox = (self.x - 50, self.y - 18, 40, 40)
        self.balloon = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon]
        self.balloon2 = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon2]
        self.direction = "greenpop"
        self.direction = "balloon"
    def get_rect(self):
        self.rect.topleft = (self.x,self.y)
        return self.rect
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect,2)
        pygame.draw.rect(window,self.color,self.hitbox)
        self.hitbox = (self.x + 35, self.y + 0, 40, 40)
        # calling the balloon and balloon2 in and image list
        if self.direction == "balloon":
            image_list = self.balloon
        elif self.direction == "greenpop":
            image_list = self.balloon2
        # Is it time to show next frame
        time_now = pygame.time.get_ticks()
        if (time_now > self.next_frame_time):
            # Time until the next game
            inter_time_delay = 1000 // self.fps
            self.next_frame_time = time_now + inter_time_delay
            # Showing next frame
            self.anim_index += 1
            if self.anim_index >= len(image_list):
                self.anim_index = 0

        if self.anim_index >= len(image_list):
            self.anim_index = 0
        green_image = image_list[self.anim_index]
                    

        green_rect = green_image.get_rect(center = self.get_rect().center)
        green_rect.centerx
        green_rect.centery += 5
        window.blit(green_image,green_rect)


class Rballoon:
    def __init__(self,x,y,width,height,color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.balloon = [pygame.image.load("img/Red_balloon" + str(i) + ".png") for i in range(1,2)]
        self.balloon2 = [pygame.image.load("img/Red_balloon" + str(i) + ".png") for i in range(1,7)]
        self.color = color
        self.speed = 2
        self.rect = pygame.Rect(x,y,width,height)
        self.fps = 10
        self.clock = pygame.time.Clock()
        self.next_frame_time = 0
        self.anim_index = 0
        self.hitbox = (self.x - 50, self.y - 18, 40, 40)
        self.balloon = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon]
        self.balloon2 = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon2]
        self.direction = "greenpop"
        self.direction = "balloon"
    def get_rect(self):
        self.rect.topleft = (self.x,self.y)
        return self.rect
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect,2)
        pygame.draw.rect(window,self.color,self.hitbox)
        self.hitbox = (self.x + 35, self.y + 0, 40, 40)
        # calling the balloon and balloon2 in and image list
        if self.direction == "balloon":
            image_list = self.balloon
        elif self.direction == "greenpop":
            image_list = self.balloon2
        # Is it time to show next frame
        time_now = pygame.time.get_ticks()
        if (time_now > self.next_frame_time):
            # Time until the next game
            inter_time_delay = 1000 // self.fps
            self.next_frame_time = time_now + inter_time_delay
            # Showing next frame
            self.anim_index += 1
            if self.anim_index >= len(image_list):
                self.anim_index = 0

        if self.anim_index >= len(image_list):
            self.anim_index = 0
        green_image = image_list[self.anim_index]
                    

        green_rect = green_image.get_rect(center = self.get_rect().center)
        green_rect.centerx
        green_rect.centery += 5
        window.blit(green_image,green_rect)
        

        


        


# The color white
white = (255,255,255)

# The xy cords, width, height and color of my classes[]

playerman = Player(350,385,34,75,white)

green1 = Gballoon(180,200,110,40,white)
blue1 = Bballoon(330,250,110,40,white)
orange1 = Oballoon(100,200,110,40,white)
pink1 = Oballoon(300,250,110,40,white)
purple1 = Pballoon(400,250,110,40,white)
red1 = Rballoon(300,200,110,40,white)

# A list for my classess
 
greens = [green1]
blues = [blue1]
oranges = [orange1]
pinks = [pink1]
purples = [purple1]
reds = [red1]



# This is where my balloons get hit by the bullet and disappers
# redrawing window
def redrawwindow():
    window.fill((0,0,0))

    # Drawing the window in
    window.blit(background,(0,0))

    # drawing the player in window
    playerman.draw()

    # Drawing all my ballons in window
    
    for Gballoon in greens:
        Gballoon.draw()

    for Bballoon in blues:
        Bballoon.draw()

    for Oballoon in oranges:
        Oballoon.draw()

    for Pballoon in purples:
        Pballoon.draw()

    for Rballoon in reds:
        Rballoon.draw()


    # Drawing the players bullet
    for bullet in bullets:
        bullet.draw()

# Frames for game
fps = 30
clock = pygame.time.Clock()
#projectile empty list
bullets = []
# main loop
run = True
while run:
    clock.tick(fps)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False


        if event.type == pygame.MOUSEBUTTONDOWN:

            if len(bullets) < 6700:
                mousex, mousey = pygame.mouse.get_pos()
                start_x, start_y = playerman.get_top()
                mouse_x, mouse_y = event.pos
                dir_x, dir_y = mouse_x - start_x , mouse_y - start_y
                distance = math.sqrt(dir_x**2 + dir_y**2)
                if distance > 0:
                    new_bullet = projectile(start_x, start_y, dir_x/distance, dir_y/distance, (0,0,0))
                    bullets.append(new_bullet)

    for bullet in bullets[:]:
        bullet.move()
        if bullet.x < 0 or bullet.x > 900 or bullet.y < 0 or bullet.y > 900:
            bullets.pop(bullets.index(bullet))



    # Making game detect when to del the ballon
    for bullet in bullets:
        for Gballoon in greens:
            if bullet.rect.colliderect(Gballoon.hitbox):
                Gballoon.direction = "greenpop"
                bullets.pop(bullets.index(bullet))

    for Gballoon in greens:
        for one in range(len(greens)-1,-1,-1):
            if greens[one].anim_index == 5:
                del greens[one]

    for i in range(len(greens)):
        for j in range(i+1, len(greens)):
            if greens[i].rect.colliderect(greens[j]): 
                greens[i].direction = "greenpop"
                greens[j].direction = "greenpop"

    for bullet in bullets:
        if bullets.pop(bullets.index(bullet)):
            print("collide")


    # gun rotation
    mousex, mousey = pygame.mouse.get_pos()
    if not playerman.isLookingAtPlayer:
        playerman.lookAt((mousex, mousey))

   
                    
    # telling game that key means when a key get pressed
    keys = pygame.key.get_pressed()

    # The player moving when the key a is pressed
    if keys[pygame.K_a] and playerman.x > playerman.speed:
        playerman.x -= playerman.speed

    # The player moving when the key d is pressed
    if keys[pygame.K_d] and playerman.x < 500 - playerman.width - playerman.speed:
        playerman.x += playerman.speed

    # Calling the redraw function
    redrawwindow()
    # updating game
    pygame.display.update()
# quiting the game
pygame.quit()

1 Answers

So, your code had a few issue, the main one was where you did

for Gballoon in greens:
    Gballoon.draw()

because this overrides the class Gballoon, you cannot use it as a type anymore afterwards. Are you used to code in C#? It looks as a foreach C# loop ;)

Also, you had a lot of redundant code, I modified it to reduce the number of lines, although it is still improvable, it is now much shorter and easier to read.

The code below does what I think you want: each time a bullet touches a balloon, this balloon pops, a new balloon is created randomly (both position and color) and all balloons move down a bit.

import pygame,math,random
pygame.init()

# some variables for display purposes
BALLOON_W, BALLOON_H = 110, 40
X_MIN, X_MAX, Y_MIN, Y_MAX = 0, 500, 0, 30
BALLOONS_Y_INCREMENT = 20
N_NEW_BALLOONS = 3


# Windowing screen width and height
width = 500
height = 500
window = pygame.display.set_mode((width,height))

# Name of window
pygame.display.set_caption("Game")

# The Background
background = pygame.image.load("img/BG.png")

def blitRotate(surf, image, pos, originPos, angle):
    # calculate the axis aligned bounding box of the rotated image
    w, h         = image.get_size()
    sin_a, cos_a = math.sin(math.radians(angle)), math.cos(math.radians(angle)) 
    min_x, min_y = min([0, sin_a*h, cos_a*w, sin_a*h + cos_a*w]), max([0, sin_a*w, -cos_a*h, sin_a*w - cos_a*h])

    # calculate the translation of the pivot 
    pivot        = pygame.math.Vector2(originPos[0], -originPos[1])
    pivot_rotate = pivot.rotate(angle)
    pivot_move   = pivot_rotate - pivot

    # calculate the upper left origin of the rotated image
    origin = (pos[0] - originPos[0] + min_x - pivot_move[0], pos[1] - originPos[1] - min_y + pivot_move[1])

    # get a rotated image
    rotated_image = pygame.transform.rotate(image, angle)

    # rotate and blit the image
    surf.blit(rotated_image, origin)

# Player class
class Player:
    def __init__(self,x,y,width,height,color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.color = color
        self.speed = 4
        self.cannon = pygame.image.load("img/Cannon.png")
        self.cannon = pygame.transform.scale(self.cannon,(self.cannon.get_width()//2, self.cannon.get_height()//2))
        self.rect = pygame.Rect(x,y,width,height)
        self.hitbox = (self.x,self.y,30,30)
        self.image = self.cannon
        self.rect  = self.image.get_rect(center = (self.x, self.y))
        self.look_at_pos = (self.x, self.y)

        self.isLookingAtPlayer = False
        self.look_at_pos = (x,y)

        self.angle = 0
    def get_rect(self):
        self.rect.topleft = (self.x,self.y)
        return self.rect

    def get_pivot(self):
        player_rect = self.cannon.get_rect(center = self.get_rect().center)
        return player_rect.centerx, player_rect.top + 103

    def get_angle(self):
        pivot_abs = self.get_pivot()
        dx = self.look_at_pos[0] - pivot_abs[0]
        dy = self.look_at_pos[1] - pivot_abs[1]
        return math.degrees(math.atan2(-dy, dx))

    def get_top(self):
        pivot_x, pivot_y = self.get_pivot()
        angle = self.get_angle()
        length = 100
        top_x = pivot_x + length * math.cos(math.radians(angle))
        top_y = pivot_y - length * math.sin(math.radians(angle))
        return top_x, top_y

    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.hitbox)

        gun_size = self.image.get_size()
        pivot_abs = self.get_pivot()
        pivot_rel = (gun_size[0] // 2, 105)
        angle = self.get_angle() - 90
        
        pygame.draw.rect(window,self.color,self.rect)
        blitRotate(window, self.image,pivot_abs, pivot_rel, angle)
        
    def lookAt( self, coordinate ):
        self.look_at_pos = coordinate


# Players gun
class projectile(object):
    def __init__(self,x,y,dirx,diry,color):
        self.x = x
        self.y = y
        self.dirx = dirx
        self.diry = diry
        self.pin = pygame.image.load("img/Pin.png")
        self.pin = pygame.transform.scale(self.pin,(self.pin.get_width()//6, self.pin.get_height()//6))
        self.rect = self.pin.get_rect()
        self.center = ( self.x, self.y )
        self.speed = 10
        self.color = color
        self.hitbox = (self.x + 20, self.y, 30,40)
    def move(self):
        self.x += self.dirx * self.speed
        self.y += self.diry * self.speed
    def draw(self):
        self.rect.center = (round(self.x), round(self.y))

        angle = math.degrees(math.atan2(-self.diry, self.dirx)) - 90
        rotated_pin = pygame.transform.rotate(self.pin, angle)
        rotated_rect = rotated_pin.get_rect(center = self.rect.center)

        window.blit(rotated_pin, rotated_rect)
        self.hitbox = (self.x + 20, self.y,30,30)


# balloon
class Balloon:
    def __init__(self,x,y,width,height,color, balloon_type):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        if(balloon_type.lower() == "green"):
            self.balloon = [pygame.image.load("img/Green_Balloon" + str(i) + ".png") for i in range(1,2)]
            self.balloon2 = [pygame.image.load("img/Green_Balloon" + str(i) + ".png") for i in range(1,7)]
        elif(balloon_type.lower() == "red"):
            self.balloon = [pygame.image.load("img/Red_Balloon" + str(i) + ".png") for i in range(1,2)]
            self.balloon2 = [pygame.image.load("img/Red_Balloon" + str(i) + ".png") for i in range(1,7)]
        elif(balloon_type.lower() == "blue"):
            self.balloon = [pygame.image.load("img/Blue_Balloon" + str(i) + ".png") for i in range(1,2)]
            self.balloon2 = [pygame.image.load("img/Blue_Balloon" + str(i) + ".png") for i in range(1,7)]
        elif(balloon_type.lower() == "pink"):
            self.balloon = [pygame.image.load("img/Pink_Balloon" + str(i) + ".png") for i in range(1,2)]
            self.balloon2 = [pygame.image.load("img/Pink_Balloon" + str(i) + ".png") for i in range(1,7)]
        elif(balloon_type.lower() == "orange"):
            self.balloon = [pygame.image.load("img/Orange_Balloon" + str(i) + ".png") for i in range(1,2)]
            self.balloon2 = [pygame.image.load("img/Orange_Balloon" + str(i) + ".png") for i in range(1,7)]
        elif(balloon_type.lower() == "purple"):
            self.balloon = [pygame.image.load("img/Purple_balloon" + str(i) + ".png") for i in range(1,2)]
            self.balloon2 = [pygame.image.load("img/Purple_balloon" + str(i) + ".png") for i in range(1,7)]
        self.color = color
        self.speed = 2
        self.rect = pygame.Rect(x,y,width,height)
        self.fps = 10
        self.clock = pygame.time.Clock()
        self.next_frame_time = 0
        self.anim_index = 0
        self.hitbox = (self.x - 50, self.y - 18, 40, 40)
        self.balloon = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon]
        self.balloon2 = [pygame.transform.scale(image,(image.get_width()//6, image.get_height()//6))for image in self.balloon2]
        self.direction = "pop"
        self.direction = "balloon"
    def get_rect(self):
        self.rect.topleft = (self.x,self.y)
        return self.rect
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect,2)
        pygame.draw.rect(window,self.color,self.hitbox)
        self.hitbox = (self.x + 35, self.y + 0, 40, 40)
        # calling the balloon and balloon2 in and image list
        if self.direction == "balloon":
            image_list = self.balloon
        elif self.direction == "pop":
            image_list = self.balloon2
        # Is it time to show next frame
        time_now = pygame.time.get_ticks()
        if (time_now > self.next_frame_time):
            # Time until the next game
            inter_time_delay = 1000 // self.fps
            self.next_frame_time = time_now + inter_time_delay
            # Showing next frame
            self.anim_index += 1
            if self.anim_index >= len(image_list):
                self.anim_index = 0

        if self.anim_index >= len(image_list):
            self.anim_index = 0
        balloon_image = image_list[self.anim_index]

        rectt = balloon_image.get_rect(center = self.get_rect().center)
        rectt.centerx
        rectt.centery += 5
        window.blit(balloon_image,rectt)

# The color white
white = (255,255,255)

# The xy cords, width, height and color of my classes[]
playerman = Player(350,385,34,75,white)

green1 = Balloon(180,200,BALLOON_W,BALLOON_H,white, "green")
blue1 = Balloon(330,250,BALLOON_W,BALLOON_H,white, "blue")
orange1 = Balloon(100,200,BALLOON_W,BALLOON_H,white, "orange")
pink1 = Balloon(300,250,BALLOON_W,BALLOON_H,white, "pink")
purple1 = Balloon(400,250,BALLOON_W,BALLOON_H,white, "purple")
red1 = Balloon(300,200,BALLOON_W,BALLOON_H,white, "red")

# A list for my classess
balloons = [green1, blue1, orange1, pink1, purple1, red1]

# This is where my balloons get hit by the bullet and disappers
# redrawing window
def redrawwindow():
    window.fill((0,0,0))

    # Drawing the window in
    window.blit(background,(0,0))

    # drawing the player in window
    playerman.draw()

    # Drawing all my ballons in window
    for balloon in balloons:
        balloon.draw()

    # Drawing the players bullet
    for bul in bullets:
        bul.draw()

def create_new_balloon():
    global balloons
    # create new balloon randomly
    balloon_type = random.randint(0,5) # 0 = green, 1 = blue, ...
    x, y = random.randint(X_MIN,X_MAX), random.randint(Y_MIN, Y_MAX)
    if(balloon_type == 0):
        new_bal = Balloon(x, y, BALLOON_W, BALLOON_H, white, "green")
    if(balloon_type == 1):
        new_bal = Balloon(x, y, BALLOON_W, BALLOON_H, white, "blue")
    if(balloon_type == 2):
        new_bal = Balloon(x, y, BALLOON_W, BALLOON_H, white, "red")
    if(balloon_type == 3):
        new_bal = Balloon(x, y, BALLOON_W, BALLOON_H, white, "pink")
    if(balloon_type == 4):
        new_bal = Balloon(x, y, BALLOON_W, BALLOON_H, white, "purple")
    if(balloon_type == 5):
        new_bal = Balloon(x, y, BALLOON_W, BALLOON_H, white, "orange")
    balloons.append(new_bal)

def move_balloons_down():
    global balloons
    for balloon in balloons:
        balloon.y += BALLOONS_Y_INCREMENT

# Frames for game
fps = 30
clock = pygame.time.Clock()
#projectile empty list
bullets = []
# main loop
run = True
while run:
    clock.tick(fps)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            if len(bullets) < 6700:
                mousex, mousey = pygame.mouse.get_pos()
                start_x, start_y = playerman.get_top()
                mouse_x, mouse_y = event.pos
                dir_x, dir_y = mouse_x - start_x , mouse_y - start_y
                distance = math.sqrt(dir_x**2 + dir_y**2)
                if distance > 0:
                    new_bullet = projectile(start_x, start_y, dir_x/distance, dir_y/distance, (0,0,0))
                    bullets.append(new_bullet)

    for bullet in bullets:
        bullet.move()
        if bullet.x < 0 or bullet.x > 900 or bullet.y < 0 or bullet.y > 900:
            bullets.pop(bullets.index(bullet))

    # Making game detect when to del the ballon
    for bullet in bullets:
        for balloon in balloons:
            if bullet.rect.colliderect(balloon.hitbox):
                for _ in range(N_NEW_BALLOONS):
                    create_new_balloon()
                move_balloons_down()
                balloon.direction = "pop"
                if bullet in bullets:
                    bullets.pop(bullets.index(bullet))

    for balloon in balloons:
        for one in range(len(balloons)-1,-1,-1):
            if balloons[one].anim_index == 5:
                del balloons[one]

    # I removed this line, I don't know why you want to delete balloons that overlap
    #for i in range(len(balloons)):
    #    for j in range(i+1, len(balloons)):
    #        if balloons[i].rect.colliderect(balloons[j]): 
    #            balloons[i].direction = "pop"
    #            balloons[j].direction = "pop"

    # gun rotation
    mousex, mousey = pygame.mouse.get_pos()
    if not playerman.isLookingAtPlayer:
        playerman.lookAt((mousex, mousey))

    # telling game that key means when a key get pressed
    keys = pygame.key.get_pressed()

    # The player moving when the key a is pressed
    if keys[pygame.K_a] and playerman.x > playerman.speed:
        playerman.x -= playerman.speed

    # The player moving when the key d is pressed
    if keys[pygame.K_d] and playerman.x < 500 - playerman.width - playerman.speed:
        playerman.x += playerman.speed

    # Calling the redraw function
    redrawwindow()
    # updating game
    pygame.display.update()
# quiting the game
pygame.quit()

Let me know if you have other questions, cheers

Related