3

While doing some game programming, I ran into a problem with the set_timer function. In my code, I wanted a bar which shows the current amount of food I have, which is supposed to decrease every second. However, it appears that the amount of space empty in my bar does not increase and pygame cannot detect my HUNGEREVENT. May I know what is the problem in my code?

def run(self):
        self.playing = True
        while self.playing:
            self.dt = self.clock.tick(FPS) / 1000
            self.hunger()
            self.events()
            self.update()
            self.draw()

    def hunger(self):
        HUNGEREVENT = pygame.USEREVENT + 1
        pygame.time.set_timer(HUNGEREVENT, 1000)
        self.all_sprites.update()
        pygame.display.flip()

    def food_food(self, x, y, cool):
        if cool < 0:
            cool = 0
        BAR_LENGTH = 100
        BAR_HEIGHT = 10
        fill = (cool / 100) * BAR_LENGTH
        outline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT)
        fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT)
        pygame.draw.rect(screen, GREEN, fill_rect)
        pygame.draw.rect(screen, WHITE, outline_rect, 2)

    def quit(self):
        pygame.quit()
        sys.exit()

    def update(self):
        self.all_sprites.update()


    def draw(self):
        self.screen.fill(BGCOLOR)
        self.all_sprites.draw(self.screen)
        font = pygame.font.SysFont('Arial', 15, True, False)
        self.food_food(120, 50, self.food_bar)
        text = font.render("Number of days:" , True, BLACK)
        screen.blit(text, [0, 110])
        font = pygame.font.SysFont('Arial', 30, True, False)
        text = font.render("= " + str(self.education_level), True, BLACK)
        screen.blit(text, [400, 40])
        font = pygame.font.SysFont('Arial', 30, True, False)
        text = font.render("= " + str(self.family_member), True, BLACK)
        screen.blit(text, [700, 40])
        font = pygame.font.SysFont('Arial', 30, True, False)
        text = font.render("= $" + str(self.money_bar), True, BLACK)
        screen.blit(text, [900, 40])
        self.all_sprites.update()
        pygame.display.flip()

    def events(self):
        # catch all events here
        HUNGEREVENT = pygame.USEREVENT + 1
        pygame.time.set_timer(HUNGEREVENT, 10000)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.quit()
            if event.type == HUNGEREVENT:
                self.food_bar = self.food_bar - 10
                print("hi")
                self.all_sprites.update()
                pygame.display.flip()
                if event.key == pygame.K_ESCAPE:
                    self.quit()

Thanks in advance

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Cravan PZ
  • 84
  • 1
  • 11

1 Answers1

3

Because the timer is restarted continuously pygame.time.set_time sets the timer event time and restarts the timer.

Move the call to

pygame.time.set_timer(HUNGEREVENT, 10000)

to the initialization of your application, before the main application loop. e.g:

def run(self):
    self.playing = True

    # start timer event
    self.hunger()

    while self.playing:
        self.dt = self.clock.tick(FPS) / 1000
        self.events()
        self.draw()
        self.update()

def hunger(self):
    self.HUNGEREVENT = pygame.USEREVENT + 1
    pygame.time.set_timer(HUNGEREVENT, 1000)

# [...]

def events(self):

    # HUNGEREVENT = pygame.USEREVENT + 1        <--- delete
    # pygame.time.set_timer(HUNGEREVENT, 10000) <--- delete

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
                self.quit()
        if event.type == self.HUNGEREVENT:
            # [...]

Note, the event is repeatedly created on the event queue. It is not necessary to start it continuously.


Furthermore I recommend to remove all calls to pygame.event.get() respectively pygame.display.update() from the application.
Do a single update of the display at the the end of the main application loop.e g.:

def run(self):
    self.playing = True
    self.hunger()
    while self.playing:
        self.dt = self.clock.tick(FPS) / 1000
        self.events()
        self.draw()

        # update the disaplay
        self.update()

def update(self):
    self.all_sprites.update()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • @Rabbid78 did what you suggested, this error pops out: ` Traceback (most recent call last): File "final_project.py", line 145, in g.run() File "final_project.py", line 42, in run self.events() File "final_project.py", line 94, in events if event.type == HUNGEREVENT: NameError: name 'HUNGEREVENT' is not defined ` – Cravan PZ Oct 09 '19 at 06:49
  • @CravanPZ `self.HUNGEREVENT` rather than `HUNGEREVENT` in `run` and `events` – Rabbid76 Oct 09 '19 at 06:51