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\$
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

| improve this answer | |
\$\endgroup\$
  • \$\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\$ – Habib Ismail Jun 16 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 at 14:46
  • \$\begingroup\$ See edit to answer \$\endgroup\$ – sirreldar Jun 16 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\$ – Habib Ismail Jun 16 at 18:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.