1
\$\begingroup\$

I am trying to make my enemy bullets attack the player but it only attack its x and y how could I make it curve instead of zigzagging VIDEO the bullets only attack the y axis and it wont curve or go to the player only attacks 2 positions

this goes on my main loop and appends projectiles

         for shootss in shootsright:

                if shootss.x < 500 and shootss.x > 0:

                    if enemyshoots1.x < playerman.x:

                        shootss.x +=  5
                    else:
                        shootss.x -= 5
                else:
                    shootsright.pop(shootsright.index(shootss))
                if shootss.y < 500 and shootss.y >0:
                    if enemyshoots1.y < playerman.y:
                        shootss.y += 5
                    else:
                        shootss.y -= 5
                else:
                    shootsright.pop(shootsright.index(shootss))


            if len(shootsright) < 2:
                    shootsright.append(Bools(round(enemyshoots1.x+enemyshoots1.width-107),round(enemyshoots1.y + enemyshoots1.height-50),(0,0,0)))
                # projectile class for each of the bullets

my enemy bullets class

    # enemys bullets
    ksud = pygame.image.load("heart.png")
    class Bools(object):
       def __init__(self, x, y,color):
           self.x = x
           self.y = y
           self.ksud = pygame.image.load("heart.png")
           self.hitbox  = self.ksud.get_rect()
           self.rect  = self.ksud.get_rect()
           self.rect.topleft = (self.x,self.y)
           self.speed = 10
           self.color = color
           self.hitbox = (self.x + 57, self.y + 33, 29, 52) # NEW
       def draw(self, window):
            self.rect.topleft = (self.x,self.y)
            player_rect = self.ksud.get_rect(center = self.rect.center) 
            player_rect.centerx += 0 # 10 is just an example
            player_rect.centery += 0 # 15 is just an example
            window.blit(self.ksud, player_rect)
            self.hitbox = (self.x + 97, self.y + 33, 10, 10) # NEW
            window.blit(self.ksud,self.rect)



I have something similar for the player where ever I click it appends bullets how could I change it to append bullets at the player without the click?

                # this is for the bullets
                    if len(bullets) < 2:
                        shootsound.play()

                        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)
        # this is displaying the bullets for the player            
            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))


\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Your problem is here:

            if enemyshoots1.x < playerman.x:
                shootss.x +=  5
            else:
                shootss.x -= 5

            if enemyshoots1.y < playerman.y:
                shootss.y += 5
            else:
                shootss.y -= 5

If you want the bullet to move straight towards the player, you need to employ some trigonometry. Unfortunately, I have never used PyGame, and its been quite some time since I used python, so the best I can give you is some C#-looking psuedocode. You will want something like this:

//define bullet speed
float bulletSpeed = 5.0f;

//the number of degrees or radians between your bullet spawn and player
//this is possible using the screen or world coordinates of your 
//sprites and some built in functions to calculate the angle
float angle = angle from player.x / player.y and bulletSpawn.x/bulletSpawn.y;

//again, use built in functions to calculate these values:
float xMagnitude = cosine of angle;
float yMagnitude = sine of angle;

//update the bullet
shootss.x += xMagnitude * bulletSpeed;
shootss.y += yMagnitude * bulletSpeed;

Of course, it would be much better to cache the x and y magnitudes as a member variable in the bullet instance so that you aren't calculating these values for every bullet every frame.

EDIT:

Try something like this.

# enemys bullets
ksud = pygame.image.load("heart.png")
class Bools(object):
   def __init__(self, x, y,color, xspeed, yspeed):
       self.x = x
       self.y = y
       self.xspeed = xspeed
       self.yspeed = yspeed
       self.ksud = pygame.image.load("heart.png")
       self.hitbox  = self.ksud.get_rect()
       self.rect  = self.ksud.get_rect()
       self.rect.topleft = (self.x,self.y)
       self.speed = 10
       self.color = color
       self.hitbox = (self.x + 57, self.y + 33, 29, 52) # NEW
   def draw(self, window):
        self.rect.topleft = (self.x,self.y)
        player_rect = self.ksud.get_rect(center = self.rect.center) 
        player_rect.centerx += 0 # 10 is just an example
        player_rect.centery += 0 # 15 is just an example
        window.blit(self.ksud, player_rect)
        self.hitbox = (self.x + 97, self.y + 33, 10, 10) # NEW
        window.blit(self.ksud,self.rect)

and

    for shootss in shootsright:
            shootss.x += shootss.xspeed
            shootss.y += shootss.yspeed
            if shootss.x > 500 or shootss.x < 0 or shootss.y > 500 or shootss.y < 0:
                shootsright.pop(shootsright.index(shootss))



        if len(shootsright) < 2:
            start_x = round(enemyshoots1.x+enemyshoots1.width-107
            start_y = round(enemyshoots1.y + enemyshoots1.height-50)
            target_x = playerman.x+playerman.width//2
            target_y = playerman.y+playerman.width//2
                    dir_x, dir_y = target_x - start_x, target_y - start_y
                    distance = math.sqrt(dir_x**2 + dir_y**2)
                    if distance > 0:
                        shootsright.append(Bools(start_x,start_y,(0,0,0),dir_x, dir_y))```

EDIT:

The last part of code makes the bullets fly to fast. A solution for this problem was found here

\$\endgroup\$
4
  • \$\begingroup\$ I have something similar for my player where ever I click with my mouse bullets append but how can I change it for the enemy so it attacks the player? script \$\endgroup\$ Jun 16, 2020 at 2:55
  • \$\begingroup\$ This script does not include any input handling or event listening. Look at this line: new_bullet = projectile(start_x, start_y, dir_x/distance, dir_y/distance, (0,0,0)). If you can find the projectile class, im willing to bet that the constructor (init in python, i believe) includes an example of how to get the x and y magnitudes from start and target positions. You need to add something similar to your bools class. \$\endgroup\$
    – sirreldar
    Jun 16, 2020 at 14:46
  • \$\begingroup\$ See edit to answer \$\endgroup\$
    – sirreldar
    Jun 16, 2020 at 15:21
  • \$\begingroup\$ the bullets dont seem to appear on the screen even though I draw it am I doing something wrong? in my main loop heres is my full code if you want to check it out script I changed the name of the bullet class to Boolss and I didnt forget about the appending the Boolss as well \$\endgroup\$ Jun 16, 2020 at 18:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .