2

I am trying to model physics in pymunk and display using pygame and it works well so far with circles and a simple line. The problem I have is that I am trying to model a rectangle.

In pymunk that is a ploygon and I can create it using:-

def create_rect(space, pos):
body = pymunk.Body(1,100,body_type= pymunk.Body.DYNAMIC)
body.position = pos
poly_dims = [(100,10),(200,10),(200,15),(100,15)]
shape = pymunk.Poly(body,poly_dims)
space.add(body,shape)
return shape

I can get the position of the body which starts off falling and print using pygame with:-

pos_x = int(board.body.position.x)
pos_y = int(board.body.position.y)
pygame.draw.circle (screen,(0,0,0),(pos_x,pos_y),10)

But I cannot seem to obtain the moving co-ordinates of the Polygon edges to then print using pygame.

v = board.get_vertices()
print(v)
pygame.draw.polygon(screen,(0,0,0),v,1)

Vertices

[Vec2d(100.0, 10.0), Vec2d(200.0, 10.0), Vec2d(200.0, 15.0), Vec2d(100.0, 15.0)]

Which looks good, however the co-ordinates never change.

Then I tried:-

pos = board.body.position
print('Position')
print(pos)

which outputs

Position Vec2d(530.5760282186911, 545.8604346347887)

And the position does change, but you cannot print the polygon with a 2D vector, you need all the vertices to do it. And presumably when the polygon hits a surface it will rotate etc. I just want to model a rectangle and I am stuck on this one point !

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Iain
  • 51
  • 1
  • 6

1 Answers1

1

If you need the vertices in world coordinates then you have to transform the vertices. Follow the example in the Pymunk documentation (see get_vertices()) and write a function that draws a polygon from the transformed vertices:

def drawShape(surf, color, shape):
    pts = []
    for v in shape.get_vertices():
        x, y = v.rotated(shape.body.angle) + shape.body.position
        pts.append((round(x), round(surf.get_width() - y)))
    pygame.draw.polygon(surf, color, pts, True)

Minimal example

import pygame, math
import pymunk

pygame.init()
screen = pygame.display.set_mode((200, 200))

def create_rect(space, pos, angle):
    body = pymunk.Body(1, 100, body_type= pymunk.Body.DYNAMIC)
    body.position = pos
    body.angle = angle
    poly_dims = [(-50, 0), (50, 0), (50, 5), (-50, 5)]
    shape = pymunk.Poly(body,poly_dims)
    space.add(body,shape)
    return shape

def drawShape(surf, color, shape):
    pts = []
    for v in shape.get_vertices():
        x, y = v.rotated(shape.body.angle) + shape.body.position
        pts.append((round(x), round(surf.get_width() - y)))
    pygame.draw.polygon(surf, color, pts, True)

space = pymunk.Space()
space.gravity = (0, 0)
board = create_rect(space, (100, 100), math.pi / 4)

clock = pygame.time.Clock()
run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    screen.fill((255, 255, 255))
    drawShape(screen, (255, 0, 0), board)
    pygame.display.flip()

pygame.quit()

Alternatively you can use the pymunk.pygame_util Module. Minimal example:

import pygame, math
import pymunk
import pymunk.pygame_util

pygame.init()
screen = pygame.display.set_mode((200, 200))
draw_options = pymunk.pygame_util.DrawOptions(screen)

def create_rect(space, pos, angle):
    body = pymunk.Body(1, 100, body_type= pymunk.Body.DYNAMIC)
    body.position = pos
    body.angle = angle
    poly_dims = [(-50, 0), (50, 0), (50, 5), (-50, 5)]
    shape = pymunk.Poly(body,poly_dims)
    space.add(body,shape)
    return shape

space = pymunk.Space()
space.gravity = (0, 0)
board = create_rect(space, (100, 100), math.pi / 4)

clock = pygame.time.Clock()
run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    screen.fill((255, 255, 255))
    space.debug_draw(draw_options)
    pygame.display.flip()

pygame.quit()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174