Why is this pygame program not working so when I hover over the computer screen it turns blue?

Posted on

Question :

Why is this pygame program not working so when I hover over the computer screen it turns blue?

Hello I am quite new to pygame and I am trying to make an intro for a game where the user hovers over the computer screen and the screen then turns blue so indicate that when you press it the game will start. However, the blue rect simply isn’t showing up?
By the way, the introScreen is a like a gif but constructed from many different frames.

This is my code:

import pygame
import pygame.gfxdraw
import threading

pygame.init()

width = 800
height = 600
fps = 30
clock = pygame.time.Clock()

white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)

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

def introLoop():

    while intro:

        for i in range(0, 26):

            clock.tick(8)

            i = str(i)

            introScreen = pygame.image.load("introScreen/" + i + ".gif")
            introScreen = pygame.transform.scale(introScreen, (width, height))

            screen.blit(introScreen, (30, 30))

            pygame.display.flip()

def gameLoop(): 

    while intro:

        mouseX, mouseY = pygame.mouse.get_pos()
        startRectArea = pygame.Rect(279, 276, 220, 128) 

        if startRectArea.collidepoint(mouseX, mouseY):

            StartRect = pygame.draw.rect(screen, blue, (279, 276, 220, 128), 0)

            pygame.display.update()

    for event in pygame.event.get():

        holder = 0



introThread = threading.Thread(target = introLoop)
gameThread = threading.Thread(target = gameLoop)

intro = True

introThread.start()
gameThread.start()

There is no error message it just doesn’t display the blue rect?
Please help as I need this for a school project.

Asked By: JayMBH

||

Answer #1:

To use multithreading in PyGame, you’ve to consider 2 things:

  1. Process an event loop in the main thread

  2. Do all the drawing on and the update of the window in a single thread. If there is an “intro” thread and a “game” thread, then the “intro” thread has to terminate first, before the “game” thread can start.

In the main thread (program) you’ve to declare the threads and to initialize the control (state) variables. Start the “intro” thread immediately and run the event loop.
I recommend to implement at least the pygame.QUIT, which signals that the program has to be terminated (run = False).
Further it can be continuously checked if the mouse is in the start area (inStartRect = startRectArea.collidepoint(*pygame.mouse.get_pos())):

introThread = threading.Thread(target = introLoop)
gameThread = threading.Thread(target = gameLoop)

run = True
intro = True
inStartRect = False
startRectArea = pygame.Rect(279, 276, 220, 128) 

introThread.start()

while run:
    if intro:
        inStartRect = startRectArea.collidepoint(*pygame.mouse.get_pos())
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.MOUSEBUTTONDOWN and inStartRect:
            intro = False

In the intro thread the entire intro screen has to be drawn, including the background and the blue start area. If the intro is finished (the game is started), then at the end of the intro thread the main game loop is started:

def introLoop():

    i = 0
    while run and intro:
        clock.tick(8)

        filename = "introScreen/" + str(i) + ".gif"
        i = i+1 if i < 26 else 0

        introScreen = pygame.image.load(filename)
        introScreen = pygame.transform.scale(introScreen, (width, height))

        screen.blit(introScreen, (30, 30))
        if inStartRect:
            pygame.draw.rect(screen, blue, (279, 276, 220, 128), 0)
        pygame.display.flip()

    gameThread.start()

The game thread starts, when the intro thread terminates. So the game thread can do the drawing of the game scene:

def gameLoop(): 

    while run:
        clock.tick(60)

        screen.fill(red)

        # [...]

        pygame.display.flip()
        clock.tick(60)
Answered By: Rabbid76

Answer #2:

Try passing intro directly into the introLoop function. Pass arguments into the thread with the args parameter…

introThread = threading.Thread(target=introLoop, args=(intro))

You will also have to redefine the function as well:

def introLoop(intro):
Answered By: Jack Walsh

Answer #3:

Try converting the images you want to load with .convert()

pygame.image.load("image file path").convert()

Or try converting the image to an image with .convert_alpha()

pygame.image.load("image file path").convert_alpha()

Pygame finds it MUCH easier and faster to load images that are converted with .convert(), and with .convert_alpha() it converts the images with their alpha layers (E.G. Transparency…) Hope this helps!

for more information, see these google results:

I recommend the first link, although this link is pretty pointless

Answered By: P3tray

Leave a Reply

Your email address will not be published.