I am making a Covid simulator and need my balls to move around randomly. However, I want them to stay moving in the first random direction that the chose, and only chnage direction if it hits another cell or hits the wall.
My current code is as follow:
import random
import pygame
# --- constants --- (UPPER_CASE_NAMES)
GREEN1 = (0, 255, 0) # Healthy cells
RED = (255, 0, 0) # Infected cells
GREEN2 = (0, 100, 0) # Healthy cells not susecptible
BLACK = (0, 0, 0) # Dead cells
WHITE = (255, 255, 255)
BACKGROUND_COLOR = (225, 198, 153)
SCREEN_SIZE = (800, 800)
# --- classes --- (CamelCaseNames)
# class keeep only one cell so it should has name `Cell` instead of `Cells`
class Cell(pygame.sprite.Sprite):
def __init__(self, color, speed, width, height):
super().__init__()
self.color = color
self.speed = speed
self.image = pygame.Surface([width, height])
self.image.fill(WHITE)
self.image.set_colorkey(WHITE)
self.radius = width // 2 # 25
center = [width // 2, height // 2]
pygame.draw.circle(self.image, self.color, center, self.radius, width=0)
self.rect = self.image.get_rect()
self.rect.x = random.randint(0, 400)
self.rect.y = random.randint(50, 700)
self.pos = pygame.math.Vector2(self.rect.center)
self.dir = pygame.math.Vector2(1, 0).rotate(random.randrange(360))
def update(self):
self.pos += self.dir * self.speed
if self.pos.x - self.radius < 0 or self.pos.x + self.radius > SCREEN_SIZE[0]:
self.dir.x *= -1
if self.pos.y - self.radius < 0 or self.pos.y + self.radius > SCREEN_SIZE[1]:
self.dir.y *= -1
for other_cell in all_cells:
if all_cells != self:
distance_vec = self.pos - other_cell.pos
if 0 < distance_vec.length_squared() < (self.radius * 2) ** 2:
self.dir.reflect_ip(distance_vec)
other_cell.dir.reflect_ip(distance_vec)
self.rect.centerx = round(self.pos.x)
self.rect.centery = round(self.pos.y)
# --- functions --- (lower_case_names)
# empty
# --- main --- (lower_case_names)
pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE)
pygame.display.set_caption("Covid-19 Simualtion")
speed = [0.5, -0.5]
# - objects -
all_cells = pygame.sprite.Group() # PEP8: lower_case_name
for _ in range(5):
cell = Cell(GREEN1, 5, 10, 10) # PEP8: lower_case_name
all_cells.add(cell)
# - loop -
clock = pygame.time.Clock()
end = False
while not end:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
end = True
# - upadates (without draws) -
all_cells.update()
# - draws (without updates) -
screen.fill(BACKGROUND_COLOR)
pygame.draw.rect(screen, BLACK, (0, 50, 400, 700), 3)
all_cells.draw(screen)
pygame.display.flip()
clock.tick(30) # to use less CPU
# - end
pygame.quit() # some system may need it to close window
I was wondering if there was a way to do this, really grateful for any help. Thanks in advance. I tried copy the first answer below into my pycharm but it didnt work, so now i have put my full code up as opposed to one section in case it is needed. Sorry for not putting it all before