Python Forum
[PyGame] Ammo is random, but it shouldn't
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] Ammo is random, but it shouldn't
#1
Hello.
I have a little problem in my game, that I am coding with pygame.
I've tried adding ammo, to my shurikans, that you can't spam them.
I've set the SHURIKAN_AMMO to 20, and I can shoot 2 times. When it is at 500, I can shoot like 56 times.

Here's the code (parts of it):

class Player(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.weapon = 'shurikan'
        self.shoot_ammo = True
        self.SHURIKAN_AMMO = 500

    def get_keys(self):
                if keys[pg.K_SPACE]:
                    if self.weapon == 'shurikan' and self.shoot_ammo == True:
                        self.SHURIKAN_AMMO -= 1
                        if self.SHURIKAN_AMMO < 0:
                            self.SHURIKAN_AMMO = 0
                        if self.SHURIKAN_AMMO == 0:
                            self.shoot_ammo = False
                        if self.SHURIKAN_AMMO > 0:
                            self.shoot()

        def shoot(self):
        if self.shoot_ammo == True:
            now = pg.time.get_ticks()
            if now - self.last_shot > WEAPONS[self.weapon]['rate']:
                self.last_shot = now
                dir = vec(1, 0).rotate(-self.rot)
                pos = self.pos + BARREL_OFFSET.rotate(-self.rot)
                self.vel = vec(-WEAPONS[self.weapon]['rate'], 0).rotate(-self.rot)
                for i in range(WEAPONS[self.weapon]['count']):
                    spread = uniform(-WEAPONS[self.weapon]['spread'], WEAPONS[self.weapon]['spread'])
                    Blowpipe(self.game, pos, dir.rotate(spread))
I have made a list, for the different weapons, where rate, spread and other things are in. This is the one, for the shurikan:

WEAPONS['shurikan'] = {'img': 'shurikan.png',
                       'speed': 575,
                       'lifetime': 800,
                       'rate': 400,
                       'kickback': 0,
                       'spread': 2,
                       'damage': 12,
                       'size': 'shurikan',
                       'count': 1}
I really don't know, why this is happening. If you have an idea, then please tell me. Thanks so much.

Piethon.
Reply
#2
(Oct-04-2019, 10:29 AM)Piethon Wrote: I've set the SHURIKAN_AMMO to 20, and I can shoot 2 times. When it is at 500, I can shoot like 56 times.

The only thing i see out of place is your shoot method is indented too much, but you possibly accidentally did that when posting. You would have to make a small example of your code that illustrates the problem. Or simply put your entire code on github so that we can run it. There are a lot of other variables that are missing that could effect it.
Recommended Tutorials:
Reply
#3
I've debugged it and it watched the self.BLOWPIPE_AMMO
At the beginning it was 20.
After shooting once it was 15
After shooting twice it was 9
After shooting three times it was 3.
I could only shoot 3 times. I have no idea why. I'll look through my code and look if I'll find something. I've not, I'll put it on Github.

I did that a few times, and it seems to subtract a random number every time. In the same file I am using uniform and randint from the random module, but I don't think this has an effect on it, because it is in another class.
Reply
#4
(Oct-04-2019, 02:32 PM)Piethon Wrote: I've debugged it and it watched the self.BLOWPIPE_AMMO
At the beginning it was 20.
After shooting once it was 15
After shooting twice it was 9
After shooting three times it was 3.
I could only shoot 3 times. I have no idea why. I'll look through my code and look if I'll find something. I've not, I'll put it on Github.

Then this probably is the cause:
    def get_keys(self):
                if keys[pg.K_SPACE]:
                    if self.weapon == 'shurikan' and self.shoot_ammo == True:
                        self.SHURIKAN_AMMO -= 1
Is this ran in the event phase or every frame (update phase)? Is keys all pressed keys? If so then you need to switch it to only under the event of space bar pressed so it only does it once. If it is all keys pressed, then even for a fraction of a keyboard press this is executing multiple times.

Your game is running lets say at 60 frames per second. If you run that code every frame is it running 60 times per second. Even if you have tapped it quickly, will result in running numerous times (5-6) which seems to be your case. So i am assuming you did not put that in the event loop? For example this code should be under
for event in pygame.event.get():
    if event == pygame.KEYDOWN:
        if event.key == pygame.SPACE:
            shoot()
This will restrict it to doing it only once instead of being held down.

If your not sure what i mean. What is the code where get_keys is executed? And what is keys defined as?
Recommended Tutorials:
Reply
#5
So keys is defined as:

keys = pg.key.get_pressed()
I imported pygame as pg. So you mean, I should make an event loop?
Well...my shoot stuff is in a sprites.py file, in the class player. In that player class there is an __init__, a get_keys(self), a shoot(self) and an update(self) section. In my main.py file, there is an event loop.
So you mean I should do it like this? :

def events(self):
    for event in pg.event.get():
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_SPACE:
                if self.player.weapon == 'shurikan' and self.player.shoot_ammo == True:
                        self.player.SHURIKAN_AMMO -= 1
                        if self.player.SHURIKAN_AMMO < 0:
                            self.player.SHURIKAN_AMMO = 0
                        if self.player.SHURIKAN_AMMO == 0:
                            self.player.shoot_ammo = False
                        if self.player.SHURIKAN_AMMO > 0:
                            self.player.shoot()
That is now in my main.py. I set the ammo to 5. I can shoot 4 times. When it is 10, I can shoot 9 times.
Well...now it is always one less, than the SHURIKAN_AMMO. At least, it is not random anymore, but do you now, why it is always one less, than it's supposed to be?

Edit: I've debugged it again and it always goes down by 1 when I shoot. But when the Ammo is 1, I somehow can't shoot anymore. I've tried adding something like this in the event loop:

# Event loop
if self.player.BLOWPIPE_AMMO == 1:
    self.player.shoot()
But somehow, that didn't work.
Thank you so much for you help!
Reply
#6
you subract the ammo before even shooting. So when you have it set to 10, before you even shoot, it is set to 9. So when it finally gets to 1, it is set to 0 before you even shoot. Reduce the ammo count only on the same line as shoot(). Also you have redundant if condition in there checking if it is less than 0 or 0 to set it to 0. You might as well use an else clause, as if it is not less than 0 or 0 itself, than it must be greater than 0 allowing to shoot.

                if self.player.weapon == 'shurikan' and self.player.shoot_ammo == True:
                        if self.player.SHURIKAN_AMMO <= 0:
                            self.player.SHURIKAN_AMMO = 0
                            self.player.shoot_ammo = False
                        else:
                            self.player.shoot()
                            self.player.SHURIKAN_AMMO -= 1
Recommended Tutorials:
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020