The Crate Hides the Gem
Part of the The Game Loop section of Coddy's Pygame journey. Lesson 18 of 35.
The crate is drawn before the gem, so the gem shows on top of it. For a crate the gem can hide under, draw the crate after the gem: what is drawn last covers what is already there.
Then a press on the crate must not reach the gem's test and catch a gem the player cannot see. Two if tests both run. With elif, the second runs only when the first was false, so only one of them takes the press:
if crate.collidepoint(event.pos):
dragging = True
elif gem.collidepoint(event.pos):
print("Got it!")Test what is drawn on top first. A press on the crate then never reaches the gem behind it.
A darker edge makes a box look solid. Draw the same Rect again in a darker colour with a width, and only its outline is drawn, over the fill.
Challenge
EasyLet the crate hide the gem, and keep a press on it from catching the gem.
- Move the crate's draw line to after the gem's outline, and below it draw
crateagain in(110, 70, 35)with width3, as its edge. - In the
MOUSEBUTTONDOWNbranch, change the gem'siftoelif, below the crate's test.
Press Play, drag the crate onto the gem and click it: the gem stays hidden and no pink mark appears. Then Check.
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()
gem = pygame.Rect(225, 165, 30, 30)
crate = pygame.Rect(40, 230, 60, 60)
dragging = False
score = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if crate.collidepoint(event.pos):
dragging = True
if gem.collidepoint(event.pos):
score += 1
gem.x = random.randint(15, 435)
gem.y = random.randint(55, 315)
elif event.type == pygame.MOUSEBUTTONUP:
dragging = False
elif event.type == pygame.MOUSEMOTION and dragging:
crate.move_ip(event.rel)
screen.fill((30, 30, 46))
pygame.draw.rect(screen, (150, 100, 50), crate)
gem_points = [gem.midtop, gem.midright, gem.midbottom, gem.midleft]
pygame.draw.polygon(screen, (80, 220, 255), gem_points)
if gem.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen, (255, 196, 0), gem.inflate(10, 10), 2)
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