I want to make a player that can shoot bullets. To do this i tried defining a shoot
function that gets called when space bar is pressed. The function looks like this (p is the player object btw):
class bullet: def __init__(self): self.x = None self.y = None self.radius = 10 self.shooting = False self.speed = 5 def shoot(self): self.shooting = True if self.shooting == True: self.x = (p.x + 60) self.y = (p.y + 25) self.x += self.speed self.y += self.speed pygame.draw.circle(d, (0, 0, 0), (self.x, self.y), self.radius) shoot()
I was hoping that the function would keep calling itself and the bullet would keep moving forward. However what actually happens is when i press space, it gives me an error
shoot() NameError: name 'shoot' is not defined
How i called the function:
while True: d.fill((98, 98, 98)) p.draw() for event in pygame.event.get(): pass if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: b.shoot()
Something i observed is that if i remove the recursion shoot()
at the end of the shoot()
function, it runs but the bullet stays in the same place as long as the space is being held down(as expected as recursion was removed). How can i fix this problem? Thanks
Advertisement
Answer
shoot
is not a function, strictly speaking. It’s an instance method, and must be invoked from a bullet
object. You need to use
self.shoot()
for recursion.
However, this is a poor way to keep the bullet moving. This is a job for a loop. Recursion is best used when you’re calling the routine with a smaller version of the problem; this is just a continuance.
while self.shooting == True: self.x = (p.x + 60) self.y = (p.y + 25) self.x += self.speed self.y += self.speed pygame.draw.circle(d, (0, 0, 0), (self.x, self.y), self.radius)
This raises the question of how you intend to quit moving the bullet. You need something like
self.shooting = (self.x <= x_limit) and (self.y <= y_limit)
Where x/y_limit are the upper bounds in that movement direction.