Search code examples
pythonpygamecollision-detectionchipmunkpymunk

Pymunk/Chipmunk2d - dynamic bodies colliding with static bodies generating collsion impulses


Can static bodies apply collision impulses to dynamic bodies?

Here's a little recording of what my code does:

Recording

As you can see, the two dynamic triangles collide with each other and are stopped by the static line. however, the behaviour is not what I want. If I had only one triangle, it would be skidding down the ledge on just one vertex --> the static body does not inflict any sort of torque or counter forces (I'm no physicist) on the triangles.

Does this mean I should just use dynamic bodies as obstacles, with really high mass? My reasoning for using static ones is that I plan on having lots of obstacles in my sim, with dynamic bodies crashing into them. Is it feasible to construct the entire environment using dynamic bodies? What am I missing?

I'm using pymunk and pygame for this btw. Appreciate any help that I can get😀

import pygame
import pymunk
import pymunk.pygame_util

pygame.init()
screen = pygame.display.set_mode((1000, 500))

space = pymunk.Space()
space.gravity = 0, -0.07

# triangle creation func, takes position arguments
def create_tri(x, y):
    pos = pygame.math.Vector2(x, y)
    points = (0, 0), (50, 0), (25, 50)

    moment = pymunk.moment_for_poly(1, points)
    body = pymunk.Body(1, moment)
    body.position = pos

    shape = pymunk.Poly(body, points)
    return body, shape

# creating 2 triangles
tri2 = create_tri(100, 400)
space.add(tri2[0], tri2[1])

# temporary obstacle setup
line_moment = pymunk.moment_for_segment(0, (0, 0), (600, -300), 10)
line_body = pymunk.Body(10, line_moment, body_type=pymunk.Body.STATIC)
line_body.position = (0, 300)

line_shape = pymunk.Segment(line_body, (0, 0), (600, -300), 10)
space.add(line_shape)

# Main loop
game_running = True
while game_running:
   ev = pygame.event.poll()
   if ev.type == pygame.QUIT:
       pygame.quit()
   screen.fill((255, 255, 255))
   draw_options = pymunk.pygame_util.DrawOptions(screen)
   space.debug_draw(draw_options)
   space.step(0.02)
   pygame.display.flip()



Solution

  • The problem is that the center of gravity of the triangle is in the corner (0,0). Meaning all its mass is in that point which is why it doesnt turn and slide down on the side.

    One way to fix it is to adjust so that (0,0) is in the middle of the triangle:

    points = (-25, -25), (25, -25), (0, 25)

    Another way is to transform the vertices of the triangle when creating the shape, by translating them -25 in each direction:

    shape = pymunk.Poly(body, points, pymunk.Transform(tx=-25,ty=-25))