I am new to pymunk and I want to make a L-shaped body like this.
I read that it is possible to have two shapes attached to same body but the best I got is this.
The code I used is this:
import pymunk
import pygame
import pymunk.pygame_util
pygame.init()
size = 640, 240
screen = pygame.display.set_mode(size)
draw_options = pymunk.pygame_util.DrawOptions(screen)
space = pymunk.Space()
space.gravity = 0, 90
b0 = space.static_body
segment = pymunk.Segment(b0, (0, 200), (640, 200), 4)
segment.elasticity = 1
body = pymunk.Body(mass=1, moment=10)
body.position = 300, 50
box = pymunk.Poly.create_box(body, (100, 50))
box.elasticity = 0.9
box.friction = 0.8
box2 = pymunk.Poly.create_box(body, (50, 100))
space.add(body, box, box2, segment)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill(color="GRAY")
space.debug_draw(draw_options)
pygame.display.update()
space.step(0.01)
pygame.quit()
Is there any way to do make a L-shaped body?
Thanks in advance!
The problem is that both Poly shapes that are created with the shorthand create_box
method are created with their center at the position of the body they are attached to. So the two boxes are positioned on top of each other.
To fix this you need to use the more generic Poly
constructor. In this way you can pick the positions as you want.
If I just take your picture and write up the coordinates times 10, it would be something like this:
box = pymunk.Poly(body, [(0, 0), (60, 0), (60, 30), (0, 30)])
box.elasticity = 0.9
box.friction = 0.8
box2 = pymunk.Poly(body, [(0, 30), (30, 30), (30, 60), (0, 60)])
box2.elasticity = 0.9
box2.friction = 0.8
However, note that the coordinates are relative to the body they are attached to, and the center of gravity is where the body is positioned. That means that the resulting L shape will behave as if its a hollow shape with a super heavy stone in one corner.
If this is not what you want to can adjust the coordinates, for example like this (I just subtracted 30 from each one. This can probably be tweaked even more depending on what your goal is):
box = pymunk.Poly(body, [(-30, -30), (30, -30), (30, 0), (-30, 0)])
box.elasticity = 0.9
box.friction = 0.8
box2 = pymunk.Poly(body, [(-30, 0), (0, 0), (0, 30), (-30, 30)])
box2.elasticity = 0.9
box2.friction = 0.8
This is the easiest to understand way (at least I think so), but there are two other options available. You can instead give a translate pymunk.Transform
as an option to the Poly
constructor, with the downside that it is less obvious what the result will be. Or you can move the center of gravity on the body with the center_of_gravity
property, with the downside that when you look at the position of the body it will still be at the "corner" of the shape.