0

I'm trying to create a game in pygame where you are a rectangle trying to shoot a bullet towards another rectangle, when you click a mousebutton. I'm using this with the pygame.MOUSEBUTTONDOWN, as you can see here:

for event in pygame.event.get():
  if event.type == pygame.MOUSEBUTTONDOWN and ammunition > 0:
    bullets.append(Bullet(*bullet_pos))
    ammunition -= 1

**I'll include more code for reference later.

However, when I click the mouse button, it only shoots a bullet every few times I click. I checked multiple times, and there doesn't seem to be a pattern of when it does/doesn't shoot. It shoots about every 4-5 times, but that's just an estimate.

Full code, for reference:

import pygame
import math
import random
import time
pygame.init()

# Setting all variables to use later \/

width, height = 798, 552

white = pygame.Color('white')
black = pygame.Color('black')
green = pygame.Color('green')
blue = pygame.Color('blue') 
red = pygame.Color('red')
grey = pygame.Color('gray')
yellow = pygame.Color('yellow')
orange = pygame.Color('orange')
azure = pygame.Color('azure')

size_x = 100
size_y = 50

pos_x = 100
pos_y = 275

size_x_2 = 100
size_y_2 = 50

pos_x_2 = random.randint(0, 798)
pos_y_2 = random.randint(0, 552)

pos_x_3 = random.randint(0, 798)
pos_y_3 = random.randint(0, 552)

window = pygame.display.set_mode((width, height))

bullet_pos_y = random.randint(0, 552)
bullet_pos_x = 798

ammunition = 5
enemy_health = 1000
player_health = 50

font = pygame.font.SysFont('Times New Roman', 32)

shooting_x = 0
shooting_y = 0

# Setting All Variables to use later /\

class Bullet:
    def __init__(self, x, y):
      self.pos = (x, y)
      self.dir = (shooting_x - x, shooting_y - y)
      length = math.hypot(*self.dir)
      if length == 0.0:
        self.dir = (0, -1)
      else:
        self.dir = (self.dir[0]/length, self.dir[1]/length)
    
      angle = math.degrees(math.atan2(-self.dir[1], self.dir[0]))

      self.bullet = pygame.Surface((27.5, 17.5)).convert_alpha()
      self.bullet.fill((red))
      self.bullet = pygame.transform.rotate(self.bullet, angle)
      self.speed = 1

    def update(self):  
      self.pos = (self.pos[0] + self.dir[0] * self.speed, self.pos[1] + self.dir[1] * self.speed)

    def draw(self, surf):
      bullet_rect = self.bullet.get_rect(center = self.pos)
      surf.blit(self.bullet, bullet_rect)

bullets = []
keys = pygame.key.get_pressed()

# EVERYTHING BELOW THIS IS IN THE GAME LOOP, EVERYTHING ABOVE ISN'T

run = True
while run:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      run = False
  
  window.fill(black)

  # Drawing Everything
      
  character = pygame.draw.rect(window, white, (pos_x, pos_y, size_x, size_y))
  enemy = pygame.draw.rect(window, blue, (shooting_x, shooting_y, size_x, size_y))
  coin = pygame.draw.circle(window, yellow, [pos_x_2, pos_y_2], 15)
  
  # Setting Text
  
  enemy_health_text = font.render(str(enemy_health), True, white, blue)
  enemy_health_textRect = enemy_health_text.get_rect()
  enemy_health_textRect.center = (enemy.center)
  
  player_health_text = font.render(str(player_health), True, black, white)
  player_health_textRect = enemy_health_text.get_rect()
  player_health_textRect.center = (character.center[0] + 9, character.center[1])
  
  ammunition_text = font.render("ammunition remaining: " + str(ammunition), True, azure, black)
  ammunition_textRect = ammunition_text.get_rect()
  ammunition_textRect.center = (205, 25)
  
  bullet_pos = character.center
  enemy_pos = enemy.center

  # Shooting a bullet

  for event in pygame.event.get():
    if event.type == pygame.MOUSEBUTTONDOWN and ammunition > 0:
      bullets.append(Bullet(*bullet_pos))
      ammunition -= 1
  
  # Enemy Dealing Damage to Player

  if enemy.colliderect(character):
    player_health -= 1
    white = pygame.Color('red')
  if not enemy.colliderect(character):
    player_health -= 0  
    white = pygame.Color('white')
  
  mouse_pos_x, mouse_pos_y = pygame.mouse.get_pos()
  pos_x, pos_y = pygame.mouse.get_pos()
  
  # If Character collides with coin 
  
  if character.colliderect(coin):
    pos_x_2 = random.randint(0, 798)
    pos_y_2 = random.randint(100, 552)
    num = random.randint(0, 20)
    if num == 17:
      yellow = pygame.Color('purple')
      ammunition += 5
    if num != 17:
      yellow = pygame.Color('yellow')
      ammunition += 2
  elif enemy.colliderect(coin):
    pos_x_2 = random.randint(0, 798)
    pos_y_2 = random.randint(100, 552)
    enemy_health += 3
    
  # Setting the Enemy Movement
  
  if shooting_x < pos_x_2:
    shooting_x += 0.1
  if shooting_x > pos_x_2:
    shooting_x -= 0.1
  if shooting_y < pos_y_2:
    shooting_y += 0.1
  if shooting_y > pos_y_2:
    shooting_y -= 0.1
  
  # Updating/Drawing Bullets
  
  for bullet in bullets:
    bullet.update()
    
    ''' WORK ON THIS ''' 
    
    if not window.get_rect().collidepoint(bullet.pos):
      bullets.remove(bullet)

  for bullet in bullets:
    bullet.draw(window)
  
  # Making sure the player doesn't leave boundaries
  
  if pos_y >= 552:
    pos_y = 552
  if pos_y <= 0:
    pos_y = 0
  if pos_x <= 0:
    pos_x = 0
  if pos_x >= 700:
    pos_x = 700
      
  # Drawing all text on screen 
    
  window.blit(ammunition_text, ammunition_textRect)
  window.blit(enemy_health_text, enemy_health_textRect)
  window.blit(player_health_text, player_health_textRect)
 
  pygame.display.update()










 
oB1qtx
  • 1
  • 3
  • Instead of the full code or just a small piece, please post an [mcve]. – outis Sep 25 '22 at 04:44
  • 1
    Does this answer your question? [Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?](/q/58086113/90527) – outis Sep 25 '22 at 04:50
  • Please consult the [help] articles, especially "[ask]" and on [searching](/help/searching). – outis Sep 25 '22 at 04:52

1 Answers1

0

The function pygame.event.get() returns an object with all events that happens. It clears all events afterwards so nothing will be executed twice when an event occurs. So you shouldn't call it twice without checking all needed events both times. Some events might get ignored when you don't call pygame.event.get() often because it has a limit of 128 events.

As a solution you can save the events in a variable (Some events might be delayed):

events = pygame.event.get()

for event in events:
    if event.type == pygame.QUIT:
        run = False

...

for event in events:
    if event.type == pygame.MOUSEBUTTONDOWN and ammunition > 0:
        bullets.append(Bullet(*bullet_pos))
        ammunition -= 1

Or you only have one event loop:

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        run = False
    elif event.type == pygame.MOUSEBUTTONDOWN and ammunition > 0:
        bullets.append(Bullet(*bullet_pos))
        ammunition -= 1
...
Jerry
  • 401
  • 4
  • 11