pygame-community / pygame-ce

🐍🎮 pygame - Community Edition is a FOSS Python library for multimedia applications (like games). Built on top of the excellent SDL library.
https://pyga.me
773 stars 120 forks source link

Add Circle `contains()` #2791

Closed itzpr3d4t0r closed 1 month ago

itzpr3d4t0r commented 3 months ago

This PR adds the Circle.contains() method for checking when a shape (Rect/Frect/Circle for now) or point falls completely inside the circle.

I have also made a ltl program to test stuff, feel free to use it as you wish:

import pygame
from pygame.draw import circle as draw_circle, rect as draw_rect
from pygame.geometry import Circle

pygame.init()

screen = pygame.display.set_mode((800, 800))
pygame.display.set_caption("Circle contains test")

running = True
c = Circle(400, 400, 200)

r = pygame.Rect(100, 100, 200, 200)
fr = pygame.Rect(100, 100, 200, 200)
c2 = Circle(400, 400, 100)

C_T = (0, 255, 0)
C_F = (255, 0, 0)

font = pygame.font.SysFont("Arial", 25, True)

shape_ix = 0

shapes = {
    0: [c2, font.render("Circle", True, (255, 255, 255))],
    1: [r, font.render("Rect", True, (255, 255, 255))],
    2: [fr, font.render("FRect", True, (255, 255, 255))],
}
info_text = font.render("mouse wheel to change shape", True, (255, 255, 255))

clock = pygame.Clock()

while running:
    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEWHEEL:
            if event.y > 0:
                shape_ix = (shape_ix + 1) % len(shapes)
            else:
                shape_ix = (shape_ix - 1) % len(shapes)

    shape, text = shapes[shape_ix]
    if c.contains(shape):
        color = C_T
    else:
        color = C_F

    shape.center = pygame.mouse.get_pos()

    screen.fill(0)

    draw_circle(screen, color, c.center, c.radius, 1)

    if isinstance(shape, pygame.Rect):
        draw_rect(screen, color, shape, 1)
    elif isinstance(shape, pygame.geometry.Circle):
        draw_circle(screen, color, shape.center, shape.radius, 1)

    screen.blit(text, text.get_rect(center=(400, 60)))
    screen.blit(info_text, info_text.get_rect(center=(400, 30)))

    pygame.display.flip()

pygame.quit()

Credits

Geometry Project: For code, docs and tests: @novialriptide @Emc2356 @itzpr3d4t0r @ScriptLineStudios @avaxar @Matiiss @newpaxonian @maqa41 @blankRiot96 Also thanks to @Starbuck5 for kickstarting the idea and the occasional help!

Functionality added in this PR

oddbookworm commented 1 month ago

Pull main to rerun CI That sysfont lint fail should be fixed