2

I'm trying to run the following code:

import pygame

WIDTH, HEIGHT = 800, 500
FPS = 60
DR_RUIN_WIDTH, DR_RUIN_HEIGHT = 800, 1200
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Dr. Ruin Rap Performance")
BG = pygame.transform.scale(pygame.image.load("files/bg.png"), (WIDTH, HEIGHT)).convert()
DR_RUIN_IMAGE = pygame.image.load("files/drruinsprite.png")
DR_RUIN = pygame.transform.scale(DR_RUIN_IMAGE, (DR_RUIN_WIDTH, DR_RUIN_HEIGHT))
DR_RUIN_BACK_IMAGE = pygame.image.load("files/drruinspriteback.png")
DR_RUIN_BACK = pygame.transform.scale(DR_RUIN_BACK_IMAGE, (DR_RUIN_WIDTH, DR_RUIN_HEIGHT))
BLUE = "#7c15ea"


def draw_window():
    WIN.blit(BG, (0, 0))
    WIN.blit(DR_RUIN, (15, -275))
    pygame.draw.rect(WIN, BLUE, pygame.Rect(0, 450, 800, 50))
    pygame.display.update()
    pygame.time.delay(14000)
    WIN.blit(DR_RUIN_BACK, (15, -275))
    pygame.display.update()
    pygame.time.delay(1000)
    WIN.blit(DR_RUIN, (15, -275))
    pygame.display.update()


def main():
    clock = pygame.time.Clock()
    run = True
    while run:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                break

        draw_window()
    pygame.quit()
    exit()


if __name__ == "__main__":
    pygame.mixer.init()
    song = pygame.mixer.Sound("files/ruinsong (2).mp3")
    pygame.mixer.music.set_volume(0.7)
    song.play()
    main()

When I try to exit the program while it's running, the window isn't responding and a message pops up informing me that the window isn't responding. It also happens when I spam click on the window. Can someone please help me fix this?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Roni
  • 597
  • 5
  • 21
  • 1
    What do you expect by `pygame.time.delay(14000)`? This is a delay of 14 seconds! – Rabbid76 Aug 18 '21 at 20:41
  • @Rabbid76, but I need to wait 14 seconds and then change the picture to the next one – Roni Aug 18 '21 at 20:42
  • `draw_window()` is called in the application loop. Therefore your application is delayed and delayed and delayed... – Rabbid76 Aug 18 '21 at 20:44
  • @Rabbid76, then how do I manage it so that the program waits 14 seconds after displaying the first image, and then displays the next image? – Roni Aug 18 '21 at 20:45

2 Answers2

1

how do I manage it so that the program waits 14 seconds after displaying the first image, and then displays the next image?

Use pygame.time.get_ticks() to return the number of milliseconds since pygame.init() was called. Calculate the time that has passed since the application loop started:

def main():
    clock = pygame.time.Clock()
    start_time = pygame.time.get_ticks()
    run = True
    while run:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
        
        current_time = pygame.time.get_ticks()
        elapsed_time = current_time - start_time
        if elapsed_time > 15000:
            start_time = current_time 
 
        draw_window(elapsed_time)
        
    pygame.quit()
    exit()

Draw the scene depending on the elapsed time:

def draw_window(elapsed_time):
    WIN.blit(BG, (0, 0))

    if elapsed_time > 14000:
        WIN.blit(DR_RUIN_BACK, (15, -275))
    else:
        WIN.blit(DR_RUIN, (15, -275))
    
    pygame.draw.rect(WIN, BLUE, pygame.Rect(0, 450, 800, 50))
    pygame.display.update()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
0

@Rabbid76's solution works very well, and I've found another solution as well:

import pygame
pygame.init()

WIDTH, HEIGHT = 800, 500
FPS = 60
DR_RUIN_WIDTH, DR_RUIN_HEIGHT = 800, 1200
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Dr. Ruin Rap Performance")
BG = pygame.transform.scale(pygame.image.load("files/bg.png"), (WIDTH, HEIGHT)).convert()
DR_RUIN_IMAGE = pygame.image.load("files/drruinsprite.png")
DR_RUIN = pygame.transform.scale(DR_RUIN_IMAGE, (DR_RUIN_WIDTH, DR_RUIN_HEIGHT))
DR_RUIN_BACK_IMAGE = pygame.image.load("files/drruinspriteback.png")
DR_RUIN_BACK = pygame.transform.scale(DR_RUIN_BACK_IMAGE, (DR_RUIN_WIDTH, DR_RUIN_HEIGHT))
BLUE = "#7c15ea"
pygame.time.set_timer(pygame.USEREVENT, 14000)


def draw_window():
    WIN.blit(BG, (0, 0))
    WIN.blit(DR_RUIN, (15, -275))
    pygame.draw.rect(WIN, BLUE, pygame.Rect(0, 450, 800, 50))
    pygame.display.update()


def next_img():
    WIN.blit(DR_RUIN_BACK, (15, -275))
    pygame.display.update()
    pygame.time.set_timer(pygame.USEREVENT, 0)
    pygame.event.pump()
    pygame.time.delay(600)
    WIN.blit(DR_RUIN, (15, -275))
    pygame.display.update()


def main():
    clock = pygame.time.Clock()
    run = True
    while run:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                break

            if event.type == pygame.USEREVENT:
                next_img()

        draw_window()
    pygame.quit()
    exit()


if __name__ == "__main__":
    pygame.mixer.init()
    song = pygame.mixer.Sound("files/ruinsong (2).mp3")
    pygame.mixer.music.set_volume(0.7)
    song.play()
    main()
Roni
  • 597
  • 5
  • 21
  • There is still a delay of 0.6 seconds in your solution (`pygame.time.delay(600)`). The application will not respond for 0.6 seconds. – Rabbid76 Aug 18 '21 at 21:10
  • @Rabbid76, I know, I did it on purpose. After the image switches to the next one, I want to wait for 600 milliseconds and then switch the image back to the first one – Roni Aug 18 '21 at 21:11
  • On some systems the solution will not work, because you need to call `pygame.event.pump()` after `pygame.display.update()` and before `delay`. See [How to wait some time in pygame?](https://stackoverflow.com/questions/18839039/how-to-wait-some-time-in-pygame) – Rabbid76 Aug 18 '21 at 21:13
  • @Rabbid76, oh ok. I added it – Roni Aug 18 '21 at 21:15