Make Bullets Fire Off In The Direction The Player Is Facing
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"