im trying to make a covid simulation with pygame, and i want to have different boxes (rectangles) that my circles can't leave , however after many searching i only learned about collisions between two rectangles or circles but only from outside. can you help me ? i also want to know if is it possible to have collisions between a rect and drawn shape with pygame draw functions? thanks here is my actual code
import pygame
import random
import numpy as np
background = (255, 255, 255)
screen_width = 700
screen_height = 500
class person(pygame.sprite.Sprite):
def __init__(self, x, y, image, radius, speed=[0, 0]):
super(person, self).__init__()
self.radius = radius
self.surf = pygame.image.load(image).convert_alpha()
self.surf.set_colorkey((255, 255, 255), pygame.RLEACCEL)
self.surf = pygame.transform.scale(self.surf, [radius, radius])
#self.surf = pygame.Surface((20, 20))
#self.surf.fill(background)
#pygame.draw.circle(self.surf, (255, 0, 0), (10, 10), 10)
self.pos = np.array([x, y], dtype=np.float64)
self.speed = np.asarray(speed, dtype=np.float64)
self.rect = self.surf.get_rect(center=[self.pos[0], self.pos[1]])
def update(self):
self.pos += self.speed
speed_norm = np.sqrt(self.speed[0]**2+self.speed[1]**2)
if speed_norm > 5:
self.speed /= speed_norm
self.speed += np.random.rand(2) * 2 - 1
# rebound
x, y = self.pos
if x < 10:
self.speed[0] *= -1
if x > screen_width - 30:
self.speed[0] *= -1
if y < 10 or y > screen_height - 30:
self.speed[1] *= -1
# hitbox
self.rect = self.surf.get_rect(center=[self.pos[0]+self.radius/2, self.pos[1]+self.radius/2])
pygame.draw.rect(screen, (0, 0, 255), self.rect, 5)
def respawn(self, image):
return person(self.rect.x, self.rect.y, image, self.radius)
def bounce(self):
self.speed *= -1
pygame.init()
screen = pygame.display.set_mode([screen_width, screen_height])
susceptible = pygame.sprite.Group()
infected = pygame.sprite.Group()
recovered = pygame.sprite.Group()
all_pers = pygame.sprite.Group()
for i in range(4):
x, y = random.randint(20, screen_width-30), random.randint(20, screen_height-30)
hamid = person(x, y, '/Users/yosh/Downloads/blue-circle-emoji.png', 50)
susceptible.add(hamid)
all_pers.add(hamid)
for j in range(1):
mahmoud = person(20, 20, '/Users/yosh/Documents/red_Circle.png', 50)
infected.add(mahmoud)
all_pers.add(mahmoud)
nbr_coll = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
sw = screen_width
sh = screen_height
screen.fill(background)
# pygame.rect (dis cote gch x,dis cote haut y, largeur, longueur)
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(0, 0, sw/2, sh/2), 5)
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(0, sh/2, sw / 2, sh / 2), 5)
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(sw/2, 0, sw / 2, sh / 2), 5)
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(sw/2, sh/2, sw / 2, sh / 2), 5)
for entity in all_pers:
screen.blit(entity.surf, entity.pos)
entity.update()
# collision
coll = pygame.sprite.groupcollide(susceptible, infected, True, False)
for guy in coll:
nbr_coll += len(coll)
new = guy.respawn(image='/Users/yosh/Documents/red_Circle.png')
new.bounce()
infected.add(new)
all_pers.add(new)
# statistics
time = pygame.time.get_ticks()
font = pygame.font.Font('freesansbold.ttf', 20)
text1 = font.render('nombre de collision = '+str(nbr_coll), True, (255, 200, 0))
text2 = font.render('temps = '+str(time//1000), True, (0, 0, 0))
text1Rect = text1.get_rect()
text2Rect = text2.get_rect()
text1Rect.center = (screen_width/2, 20)
text2Rect.center = (screen_width/2, 40)
screen.blit(text1, text1Rect)
screen.blit(text2, text2Rect)
# fps
pygame.time.Clock().tick(60)
# time limit
if pygame.time.get_ticks() >= 60000:
running = False
pygame.display.flip()
pygame.quit()