1

Basically. I am trying to make a tower defense game and I need the towers to shoot at the enemy and for the bullet to follow that enemy at a certain speed until they hit it. I have already written all the code however I, for some reason, cannot get the 'tracking' method to work for the bullet. I thought I could do this simply by using polar to cartesian conversions however I must be over looking something as the bullet does not go anywhere near its target.

This is what I have:

def follow(self):
    dx = (self.rect.x + 4) - (self.target.rect.x + 15)
    dy = (self.rect.y + 4) - (self.target.rect.y + 15)
    angle = math.atan2(dy, dx)
    x = self.speed * math.cos(angle)
    y = self.speed * math.sin(angle)
    self.rect.x += x
    self.rect.y += y

1 Answers1

2

self.rect.x and self.rect.y are integral values. If you add an floating point value, which is less than 1.0, then the result won't change.

I recommend to use pygame.math.Vector2 to mange the position in floating point coordinates. Set the position of the bullet in the constructor:

self.pos = pygame.math.Vector2(self.rect.center)

Calculate the direction vector from the bullet to the target:

dir = pygame.math.Vector2(self.target.rect.center) - self.pos

Use .length() to calculate the distance to the target. Calculate the normalized direction from the bullet to the target by dividing by distance. The normalized vector is a Unit vector with a length of 1.0:

distance = dir.length()
if distance > 0:
    dir = dir / distance

Update the position and the rectangle. Ensure that the bullet doesn't "go through" the target, by limiting the movement of the bullet by the distance to the target (min(distance, self.speed)):

self.pos += dir * min(distance, self.speed)
self.rect.center = self.pos

The code may look somehow like this:

class Bullet:

    def __init__(self, [...]):

        self.rect = [...]

        self.pos = pygame.math.Vector2(self.rect.center)

    def follow(self):
        
        dir = pygame.math.Vector2(self.target.rect.center) - self.pos
        distance = dir.length()
        if distance > 0:
            dir = dir / distance

        self.pos += dir * min(distance, self.speed)
        self.rect.center = self.pos
Rabbid76
  • 202,892
  • 27
  • 131
  • 174