0

I've been watching a bunch of tutorials and new to pygame and coding in general. None of the tutorials I watched helped me with this. What i'm aiming for is for the buttons to change the button to a different colour when the user hovers over the button. Below is my entire code for the main menu so far.

import pygame
import time
import random

pygame.init()

size = (800, 600)
screen = pygame.display.set_mode(size)

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)


pygame.display.set_caption("Basketball Shootout")
clock = pygame.time.Clock()

#GAME INTRO

def game_intro():

    intro = True

    while intro:
        for event in pygame.event.get():
            #print(event)
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

#Font's and text
font = pygame.font.SysFont ("Times New Norman", 60)
text = font.render ("", True, WHITE)

#Background Image
background_images = pygame.image.load("greybackground.jpg").convert()
screen.blit(background_images, [0,0])
screen.blit(text, (150, 50))

#Background Music
pygame.mixer.music.load('game.ogg')
pygame.mixer.music.set_endevent(pygame.constants.USEREVENT)
pygame.mixer.music.play()
pygame.display.update()
clock.tick(15)

#BUTTONS
screen.blit(text, (150, 50))
pygame.draw.rect(screen,(0,0,0),(300,300,205,80));
pygame.draw.rect(screen,(0,0,0),(300,400,205,80));
pygame.draw.rect(screen,(0,0,0),(300,500,205,80));

font = pygame.font.SysFont ("Times New Norman, Arial", 30)
text = font.render ("START", True, WHITE)
screen.blit(text, (340, 320))
font = pygame.font.SysFont ("Times New Norman, Arial", 30)
text = font.render ("OPTIONS", True, WHITE)
screen.blit(text, (340, 420))
font = pygame.font.SysFont ("Times New Norman, Arial", 30)
text = font.render ("ABOUT", True, WHITE)
screen.blit(text, (340, 520))

pygame.display.flip();

#Quit Pygame
game_intro()
pygame.quit
Cian Mc
  • 49
  • 7

2 Answers2

0

I recommend storing the button data (text surface, rect, color) in a list of lists. When the mouse moves, pygame.MOUSEMOTION events get added to the event queue. In the event loop check if the mouse moved and then iterate over your buttons and set the color of colliding buttons to the hover color, reset the others to black. Blit the rects and text surfaces in a for loop as well.

import pygame


pygame.init()

screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
HOVER_COLOR = (50, 70, 90)
# Don't define new font objects in your while loop (that's inefficient).
FONT = pygame.font.SysFont ("Times New Norman", 60)
# If the text surfaces and button rects don't change,
# you can define them once outside of the while loop.
text1 = FONT.render("START", True, WHITE)
text2 = FONT.render("OPTIONS", True, WHITE)
text3 = FONT.render("ABOUT", True, WHITE)
rect1 = pygame.Rect(300,300,205,80)
rect2 = pygame.Rect(300,400,205,80)
rect3 = pygame.Rect(300,500,205,80)
# The buttons consist of a text surface, a rect and a color.
buttons = [
    [text1, rect1, BLACK],
    [text2, rect2, BLACK],
    [text3, rect3, BLACK],
    ]

def game_intro():
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            elif event.type == pygame.MOUSEMOTION:
                for button in buttons:
                    # button[1] is the rect. Use its collidepoint method with
                    # the `event.pos` (mouse position) to detect collisions.
                    if button[1].collidepoint(event.pos):
                        # Set the button's color to the hover color.
                        button[2] = HOVER_COLOR
                    else:
                        # Otherwise reset the color to black.
                        button[2] = BLACK

        screen.fill((20, 50, 70))

        # Draw the buttons with their current colors at their rects.
        # You can unpack the button lists directly in the head of the loop.
        for text, rect, color in buttons:
            pygame.draw.rect(screen, color, rect)
            screen.blit(text, rect)

        pygame.display.flip()
        clock.tick(15)


game_intro()
pygame.quit()

I'd actually recommend defining a Button class, but I'm not sure if you're already familiar with classes/object-oriented programming.

The buttons also need callback functions to actually do something. Take a look at my answer here: https://stackoverflow.com/a/47664205/6220679

skrx
  • 19,980
  • 5
  • 34
  • 48
  • Thanks for your answer it helped a lot, although I am having trouble changing the background image. When I tried to implement your code into my own source it would only show me the background image and wouldn't show the buttons. – Cian Mc Jul 30 '18 at 01:52
  • You probably have to rearrange the drawing section of your code. Blit the background first, then the buttons and finally call `pygame.display.flip()`. By the way, you only need to call `pygame.display.flip` or `pygame.display.update` once per frame. – skrx Jul 30 '18 at 01:58
  • Thanks it finally works, i'm starting to use the callback functions – Cian Mc Jul 30 '18 at 02:27
0

I would recommend creating a function for this:

    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()

    if x + w > mouse[0] > x and y + h > mouse[1] > y:
        gameDisplay.blit(active, (x, y))
    else:
        gameDisplay.blit(inactive, (x, y))

and then in you game intro call you function like this:

def game_intro():

    intro = True

    while intro:
        for event in pygame.event.get():
            #print(event)
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        # For example
        button(100, 350, 195, 80, startBtn, startBtn_Hover)

This is what each parameter means:

  • x: x-coordinate of button
  • y: y-coordinate of button
  • w: width of button
  • h: height of button
  • active: picture when mouse is hovered over button
  • inactive: picture when button is idle
turivishal
  • 34,368
  • 7
  • 36
  • 59
IT_Guys
  • 27
  • 4