Skip to content Skip to sidebar Skip to footer

Make Bullets Fire Off In The Direction The Player Is Facing

I was just getting some help to figure out how to get my player fire bullets when I realized that they only go (kinda expected this but however as only had y value for movement). I

Solution 1:

Add 2 attributes self.lastX and self.lastY to the class Player and change the attributes when the player changes the direction:

classPlayer(py.sprite.Sprite):
    def__init__(self):
        # [...]

        self.lastX = 0
        self.lastY = -10defupdate(self):
        # [...]
        self.rect.x += self.Xspeed
        self.rect.y += self.Yspeed

        if self.Xspeed != 0or self.Yspeed != 0:
            self.lastX = self.Xspeed
            self.lastY = self.Yspeed  

Add an argument Xspeed ans Yspeed to the class Bullet

classBullet(py.sprite.Sprite):
    def__init__(self, x, y, Xspeed, Yspeed):
        py.sprite.Sprite.__init__(self)
        self.image = py.Surface((5, 5))
        self.image.fill(YELLOW)
        self.rect = self.image.get_rect()
        self.rect.bottom = y
        self.rect.centerx = x
        self.Xspeed = Xspeed
        self.Yspeed = Yspeed

    defupdate(self):
        self.rect.x += self.Xspeed
        self.rect.y += self.Yspeed
        # [...]

Set the attributes when the bullet spawns

classPlayer(py.sprite.Sprite):
    # [...]defShoot(self):
       return Bullet(self.rect.centerx, self.rect.centery, self.lastX, self.lastY)

Alternatively it is also possible to set the speed dependent on the direction to the mouse cursor.

Get the position of the player and the mouse cursor and compute the x and y distance (Vector ):

pos = self.rect.center
mpos = py.mouse.get_pos()
vx = mpos[0] - pos[0]
vy = mpos[1] - pos[1]

If the mouse position and the bullet position are equal, that does not make any sense, thus the bullet is skipped

if vx == 0and vy == 0:
    returnNone

Of course this vector is far to long, if you would use it for the direction (Xspeed, Yspeed) directly, then the bullet would step to the mouse cursor in one turn. In the following I use pygame.math.Vector2, because it provides the handy method scale_to_length, that scales a vector to a specified Euclidean length:

direction = py.math.Vector2(vx, vy)
direction.scale_to_length(10)

Now the x and y component of the vector contain the x and y component of the speed. Since the components are floating point values, they are round to integral values:

return Bullet(pos[0], pos[1], round(direction.x), round(direction.y))

Method Shoot:

classPlayer(py.sprite.Sprite):
    # [...]defShoot(self):
        pos = self.rect.center
        mpos = py.mouse.get_pos()
        vx, vy = mpos[0] - pos[0], mpos[1] - pos[1]
        if vx == 0and vy == 0:
            returnNone
        direction = py.math.Vector2(vx, vy)
        direction.scale_to_length(10) 
        return Bullet(pos[0], pos[1], round(direction.x), round(direction.y))

Note, if you set the bullet dependent on the direction to the mouse cursor, then it may be useful to spawn the bullet by a mouse click:

while running:
    # [...]for event in py.event.get():
        if event.type == py.QUIT:
            # [...]elif event.type == py.MOUSEBUTTONDOWN:
             if event.button == 1:
                New_bullet = player.Shoot()
                if New_bullet:
                    all_sprites.add(New_bullet)
                    bullets.add(New_bullet)

Solution 2:

You can use pygames Vector2 to move in any direction. You calculate the angle of the player you can use that.

classPlayer(py.sprite.Sprite):
    def__init__(self):
        ...
        self.angle = 0defrotate(self, mouse_x, mouse_y):
        ...
        self.angle = -angle #make negative otherwise it will be going away from mousedefShoot(self):
         return Bullet(self.rect.centerx, self.rect.top, py.math.Vector2(1,0).rotate(self.angle))

then in your bullet class, get the direction and add to its position

classBullet(py.sprite.Sprite):
    def__init__(self, x, y, Dir):
        ...
        self.Dir = Dir

    defupdate(self):
        self.rect.y += self.Dir[1] * self.speed
        self.rect.x += self.Dir[0] * self.speed
        ...

Post a Comment for "Make Bullets Fire Off In The Direction The Player Is Facing"