Menu
CoddyTech

Hover Highlight

Part of the The Game Loop section of Coddy's Pygame journey. Lesson 15 of 32.

Testing gx <= x <= gx + 30 every time gets long. Pygame has a class for rectangles, pygame.Rect, that keeps a position and a size together and does these tests for you:

gem = pygame.Rect(225, 165, 30, 30)

if gem.collidepoint(event.pos):
    score += 1

gem.collidepoint(point) is True when the point is inside the Rect. You can still read and change gem.x and gem.y, and a Rect names its own points: gem.midtop, gem.midright, gem.midbottom and gem.midleft are the middles of its sides, which are the gem's four corners.

The same test with the pointer's position tells you the player is pointing at the gem. Games show that with a highlight:

if gem.collidepoint(pygame.mouse.get_pos()):
    pygame.draw.rect(screen, (255, 196, 0), gem.inflate(10, 10), 2)

gem.inflate(10, 10) is a new Rect 10 pixels wider and taller with the same centre, so the outline sits 5 pixels outside the gem.

challenge icon

Challenge

Easy
  1. Replace gx, gy = 225, 165 with gem = pygame.Rect(225, 165, 30, 30), and use gem.x and gem.y where you used gx and gy.
  2. Draw the gem from [gem.midtop, gem.midright, gem.midbottom, gem.midleft], and test clicks with gem.collidepoint(event.pos).
  3. After the gem, when the pointer is on it, draw a yellow (255, 196, 0) outline of gem.inflate(10, 10), 2 pixels wide.

Try it yourself

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Gem Hunt")
clock = pygame.time.Clock()

gx, gy = 225, 165
score = 0

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            x, y = event.pos
            if gx <= x <= gx + 30 and gy <= y <= gy + 30:
                score += 1
                gx = random.randint(15, 435)
                gy = random.randint(55, 315)

    screen.fill((30, 30, 46))
    gem_points = [(gx + 15, gy), (gx + 30, gy + 15), (gx + 15, gy + 30), (gx, gy + 15)]
    pygame.draw.polygon(screen, (80, 220, 255), gem_points)
    for i in range(score):
        pygame.draw.rect(screen, (240, 110, 180), (10 + 10 * i, 14, 8, 8))
    mouse_x, mouse_y = pygame.mouse.get_pos()
    pygame.draw.circle(screen, (240, 240, 240), (mouse_x, mouse_y), 10, 2)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

All lessons in The Game Loop

Practice on your own: Pygame playground