Search code examples
pythonpygamephysicspymunk

How to update the Radius of a circle continusly in Pygame and Pymunk


I made a simple test scene in Pygame and Pymunk which just drops a boucy ball on a line, which I want to grow every time a collision happens.

import pygame, sys, pymunk


pygame.init()
screen = pygame.display.set_mode((800, 800))
clock = pygame.time.Clock()
space = pymunk.Space()
space.gravity = (0, 500)


#Varibales
CircleRadius = 10



# create ball
BallBody = pymunk.Body(1, 100, body_type=pymunk.Body.DYNAMIC)
BallBody.position = 400, 400

BallShape = pymunk.Circle(BallBody, CircleRadius)
BallShape.elasticity = 0.9
BallShape.collision_type = 1
space.add(BallBody, BallShape)

# Create Container
SegmentBody = pymunk.Body(body_type=pymunk.Body.STATIC)

SegmentShape = pymunk.Segment(SegmentBody, (200, 600), (600, 600), 10)
SegmentShape.elasticity = 1
SegmentShape.collision_type = 2
space.add(SegmentBody, SegmentShape)

#handle collisions
def Collision(arbiter, space, data):
    print("Collision")
    global CircleRadius
    CircleRadius += 2


handler = space.add_collision_handler(1, 2)
handler.separate = Collision

#main game loop
while True:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    screen.fill((0, 0, 0))
    #draw bodys in pygame
    Bx, By = BallBody.position
    pygame.draw.circle(screen, (255, 0, 0), (int(Bx), int(By)), CircleRadius)

    Sx, Sy = SegmentBody.position
    pygame.draw.line(screen, (255, 0, 0), (200, 600), (600, 600), 10)
    space.step(1 / 50)

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

The problem is that everytime there is a collision the Pygame visual grows, but not the actual Pymunk physical body.

I have tried using ChatGPT but nothing from it worked, nor could I find any answers online.


Solution

  • You have to create a new pymunk.Segment and then replace the old segment with the new segment:

    def Collision(arbiter, space, data):
        print("Collision")
        global CircleRadius, SegmentShape
        CircleRadius += 2
        space.remove(SegmentShape)
        SegmentShape = pymunk.Segment(SegmentBody, (200, 600), (600, 600), CircleRadius)
        SegmentShape.elasticity = 1
        SegmentShape.collision_type = 2
        space.add(SegmentShape)