0

I made my projectile shoot left and right by buttons but that would be boring clicking alot of buttons how do make it shoot with with my mouse? at any position x,y

 # projectile class
    if keys[pygame.K_f]:     
        for bullet in bullets:
            if bullet.x < 500 and bullet.x > 0:
                bullet.x += bullet.speed 
            else:
                bullets.pop(bullets.index(bullet))
        if len(bullets) < 2:  
                bullets.append(projectile(round(playerman.x+playerman.width//2),round(playerman.y + playerman.height-54),(0,0,0)))
    if keys[pygame.K_g]:     
        for bullet in bullets:
            if bullet.x < 500 and bullet.x > 0:
                bullet.x -= bullet.speed 
            else:
                bullets.pop(bullets.index(bullet))
        if len(bullets) < 2:  
            bullets.append(projectile(round(playerman.x+playerman.width//2),round(playerman.y + playerman.height-54),(0,0,0)))
    # Jump and Collisions

and this is my projectile class

class projectile(object):
   def __init__(self, x, y,color):
       self.x = x
       self.y = y
       self.slash = pygame.image.load("heart.png")
       self.rect  = self.slash.get_rect()
       self.rect.topleft = ( self.x, self.y )
       self.speed = 10
       self.color = color

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

       window.blit(slash, self.rect)

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Habib Ismail
  • 69
  • 5
  • 16

1 Answers1

2

You have to add the moving direction (dirx, diry) to the class projectile. Further add a method which moves the bullet:

class projectile(object):
   def __init__(self, x, y, dirx, diry, color):
       self.x = x
       self.y = y
       self.dirx = dirx
       self.diry = diry
       self.slash = pygame.image.load("heart.png")
       self.rect  = self.slash.get_rect()
       self.rect.topleft = ( self.x, self.y )
       self.speed = 10
       self.color = color

   def move(self):
       self.x += self.dirx * self.speed
       self.y += self.diry * self.speed

   def draw(self, window):
       self.rect.topleft = (round(self.x), round(self.y))

       window.blit(slash, self.rect)

Compute the direction form the player to the mouse when the mouse button is pressed and spawn a new bullet. The direction is given by the vector form the player to the muse position (mouse_x - start_x, mouse_y - start_y). The vector has to be normalized (Unit vector) by dividing the vector components by the Euclidean distance:

for event in pygame.event.get():
    # [...]

    if event.type == pygame.MOUSEBUTTONDOWN:

        if len(bullets) < 2:  

            start_x, start_y = playerman.x+playerman.width//2, playerman.y + playerman.height-54
            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)

Move the bullets in a loop in te main application loop and remove the bullet if it is out of the window

run = True
while run:

    # [...]

    for event in pygame.event.get():
        # [...]

    for bullet in bullets[:]:
        bullet.move()

        if bullet.x < 0 or bullet.x > 500 or bullet.y < 0 or bullet.y > 500:
            bullets.pop(bullets.index(bullet))

    # [...]

Example code

runninggame = True
while runninggame:
    clock.tick(FPS)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            runninggame = False


        if event.type == pygame.MOUSEBUTTONDOWN:

            if len(bullets) < 2:  

                start_x, start_y = playerman.x+playerman.width//2, playerman.y + playerman.height-54
                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 > 800 or bullet.y < 0 or bullet.y > 800:
            bullets.pop(bullets.index(bullet))

    # [...]
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • am I doing something wrong it says `vector.x is not defined` [main loop](https://gyazo.com/ac887e5b06e38a82128da82ccb546632) – Habib Ismail May 24 '20 at 20:03
  • also everything works but the only problem is the bullets dont show up on my screen https://gyazo.com/7cfbc47d17bfe7ecf3af64981627109d – Habib Ismail May 24 '20 at 20:24
  • like this for bullet in bullets: or for bullet in bullets[:] <-- if I do that I am getting an error – Habib Ismail May 24 '20 at 20:32
  • https://gyazo.com/491854497e47d81834f68700f78343a6 <-- idk if I am missing something but when I click it only loads 1 of my bullets and it does not move them anywhere and when I click again it does not show the projectiles nor does it move my full code: https://pastebin.com/raw/eugJ9dhG – Habib Ismail May 24 '20 at 20:38
  • sorry if I am asking to much questions about the code but now when I click nothing shows up [script](https://gyazo.com/1ea5320ce90f72adaf972ef128976f09) [game vid](https://gyazo.com/23807c5bff5a65f6b559419225373e21) – Habib Ismail May 24 '20 at 20:55
  • 1
    @HabibIsmail The issue is in the method `move` of the class `projectile`. `+=` rather than `+`, of course. I've fixed that in the answer. Furthermore it has to be `if bullet.x < 0 or bullet.x > 800 or bullet.y < 0 or bullet.y > 800:` (800 rather than 500). – Rabbid76 May 24 '20 at 21:39
  • 1
    it works great thank u so much! – Habib Ismail May 24 '20 at 21:56