1

I am making a covid simulation and the balls to bounce off each other, but when it collides with a red ball I need it to become red. However, I'm not entirely sure how to do it. My current code goes as follows:

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(5, 795)
        self.rect.y = random.randint(150, 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 < 5 or self.pos.x + self.radius > 790:
            self.dir.x *= -1
        if self.pos.y - self.radius < 150 or self.pos.y + self.radius > 700:
            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)

    def changeColor(self, newColor):
        self.color = newColor
        pygame.draw.circle(self.image, self.color, center, self.radius, width=0)

class Infected(Cell):
    def __init__(self, color, speed, width, height):
        super().__init__('RED', speed, width, height)
        self.color = color
        self.pos.x = 345
        self.pos.y = 295
        centre = [self.pos.x, self.pos.y]
        pygame.draw.circle(self.image, self.color, centre, self.radius, width=0)

pygame.init()

screen = pygame.display.set_mode(SCREEN_SIZE)
pygame.display.set_caption("Covid-19 Simualtion")

all_cells = pygame.sprite.Group()
redcell = Infected('RED', 2, 10, 10)
all_cells.add(redcell)
for _ in range(100):
    cell = Cell(GREEN1, 2, 10, 10)
    all_cells.add(cell)

This code allows the balls to bounce off each other. Also, I was wondering if it's possible to cast classes, for example, if I have a cell that belongs to a Class healthy(cell) can I cast it into Class infected(cell) upon impact.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • You should ask one question per post, see [ask]. And for your second question, you should give an example of a situation in which you need that behavior as opposed to storing that kind of thing as, say, a class attribute. – Random Davis Dec 28 '20 at 20:44
  • No, you cant change the type of an object. – Rabbid76 Dec 28 '20 at 20:47

1 Answers1

0

This question can only be answered with knowledge of your previous question: Random systematic movement in pygame.

You have to change the color attribute and redraw the image Surface. Add a method changeColor:

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

    def changeColor(self, newColor):
        self.color = newColor
        pygame.draw.circle(self.image, self.color, center, self.radius, width=0)

Call the method when you want to change the color. Assuming you have a variabel RED for the red color:

RED = (255, 0, 0) # just an example use your red color here

In pygame you can even define the color by a string instead of a tuple. However, it is important to always use the same color:

RED = 'RED'

Test if the color of a particle is RED and change the color:

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)

            if self.color == RED:
                other_cell.changeColor(RED)
            elif other_cell.color == RED:
                self.changeColor(RED)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thanks rabid for the help, however after combining this with my current simulation code it didnt work – Ismail Hussain Dec 28 '20 at 21:02
  • No error came up, but the cells did not change color upon collision – Ismail Hussain Dec 28 '20 at 21:05
  • I have editted the code and where ive placed it, but rather then the cells changing color it creates another red cell, and i cant delete the original green one – Ismail Hussain Dec 28 '20 at 21:07
  • otherwise i had attempted to also delete the green cell when the red is created, but it just forms in another random place – Ismail Hussain Dec 28 '20 at 21:08
  • Yep, upon editting that the cells still would not change color. I attempted editting the method for colour change also since it said that there is no centre, so i took ~~~round(self.pos.x)~~~ and ~~~round(self.pos.y)~~~ as parameters for my centre and thrn in the subprogram said ~~~centre = [round(self.pos.x), round(self.pos.y)]~~~ but still recieve the error there is no centre – Ismail Hussain Dec 28 '20 at 21:14
  • Hi rabid, i have taken multiple attempts editting it. I have changed it again to : if self.color == RED: other_cell.changeColor(RED, center) elif other_cell.color == RED: self.changeColor(RED, center) self.rect.centerx = round(self.pos.x) self.rect.centery = round(self.pos.y) def changeColor(self, newColor, center): self.color = newColor pygame.draw.circle(self.image, self.color, center, self.radius, width=0). – Ismail Hussain Dec 28 '20 at 21:18
  • i am attempting to learn, but using what you have told me didnt work – Ismail Hussain Dec 28 '20 at 21:18
  • i understood from what you told me about the 'red' issue that one was a string while the other was a constant representing the colour, hence why i it back to be RED – Ismail Hussain Dec 28 '20 at 21:19
  • The problem is, when you say self.color that checks the color off other_cell, but i dont see how to check the color of the cell that it is colliding with – Ismail Hussain Dec 28 '20 at 21:26
  • in the code you have explained to me, it checks if either is red and should change the the other if it is, but that doesnt work for some reason – Ismail Hussain Dec 28 '20 at 21:27
  • yep, thanks, i understand, since if checks one cell and elif checks the other, however i am really struggling to understand why this doesnt work when implemented into my code – Ismail Hussain Dec 28 '20 at 21:32
  • @IsmailHussain I can't help you as I can't see and debug your application – Rabbid76 Dec 28 '20 at 21:33