Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Pygame Calculate Angle of Reflection of Collision betweeen masks

I encountered an issue in my brick breaker game where the paddle has round edges and i want to reflect the ball with perfect angle, i was using angle and sin and cos for the direction, but i moved to vectors after a recommendation, i made a similar problem for the sake of simplicity.
here is the code:

import sys

import pygame

pygame.init()

w, h = 1200, 800
screen = pygame.display.set_mode((w, h))
clock = pygame.Clock()

class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((10, 10))
        self.image.set_colorkey((0,0,0))
        pygame.draw.circle(self.image, (255, 0, 0), (5, 5), 3)
        self.rect = self.image.get_rect(topleft = (x, y) )
        self.mask = pygame.mask.from_surface(self.image)
        self.velocity = pygame.Vector2(0, -10)

    def update(self, circlex, circley, circle_mask):
        if self.rect.y < 0 or self.rect.y > 800:
            self.kill()
        if self.rect.x < 0 or self.rect.x > 1200:
            self.kill()

        self.rect.y += self.velocity.y
        offset = circlex - self.rect.x, circley - self.rect.y
        if p := self.mask.overlap(circle_mask, offset):
            v = pygame.Vector2(p)
            self.velocity.reflect_ip(v)


    def draw(self, screen):
        screen.blit(self.image, self.rect)


circle = pygame.Surface((400, 400))
pygame.draw.circle(circle, (255, 255, 255), (200, 200), 150)
circle_rect = circle.get_rect(topleft = (400, 100))
circle.set_colorkey((0, 0, 0))
circle_mask = pygame.mask.from_surface(circle)

gun = pygame.Surface((100, 40))
gun_rect = gun.get_rect(topleft = (200, 750))
gun.fill("red")

bullets = pygame.sprite.Group()

while True:
    mx, my = pygame.mouse.get_pos()
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if e.type == pygame.MOUSEBUTTONDOWN:
            b = Bullet(mx, 750)
            bullets.add(b)

    screen.fill((30, 30, 30))


    gun_rect.centerx = mx
    screen.blit(gun, gun_rect)
    screen.blit(circle, circle_rect)

    bullets.update(circle_rect.x, circle_rect.y, circle_mask)
    bullets.draw(screen)

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

the issue is the bullet is getting straight through the circle, if you could explain how vector works that would be great.
vid

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Change the position by both components of the direction vector

self.rect.center += self.velocity

Detect the collision of the circle with the bullet, not the other way around:

offset = self.rect.x - circle_rect.x, self.rect.y - circle_rect.y
if p := circle_mask.overlap(self.mask, offset):

The reflection vector is the vector from the center of the circle the the hit position:

v = pygame.Vector2(p) - (circle_rect.width/2, circle_rect.height/2)

Complete update method:

class Bullet(pygame.sprite.Sprite):
    # [...]

    def update(self, circle_rect, circle_mask):
        if self.rect.y < 0 or self.rect.y > 800:
            self.kill()
        if self.rect.x < 0 or self.rect.x > 1200:
            self.kill()

        self.rect.center += self.velocity
        offset = self.rect.x - circle_rect.x, self.rect.y - circle_rect.y
        if p := circle_mask.overlap(self.mask, offset):
            v = pygame.Vector2(p) - (circle_rect.width/2, circle_rect.height/2)
            self.velocity.reflect_ip(v)
            
# [...]

while True:
    # [...]

    bullets.update(circle_rect, circle_mask)

    # [...]

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading