DEV Community

Lingjun Jiang
Lingjun Jiang

Posted on

First program using Pymunk

import pymunk as pm
from pymunk.vec2d import Vec2d
import pygame
from pygame.locals import QUIT

# Initialize Pygame
pygame.init()
screen = pygame.display.set_mode((600, 600))
clock = pygame.time.Clock()

# Create a space
space = pm.Space()

# Create a center body
center_mass = 10
center_moment = pm.moment_for_poly(center_mass, [(-100, -100), (100, -100), (100, 100), (-100, 100)])
center_body = pm.Body(center_mass, center_moment)
center_body.position = Vec2d(300, 300)  # Center of the screen

# Create a vertex body
vertex_mass = 1
vertex_radius = 20  # Enlarged radius
vertex_moment = pm.moment_for_circle(vertex_mass, 0, vertex_radius)
vertex_body = pm.Body(vertex_mass, vertex_moment)
vertex_body.position = Vec2d(400, 400)  # Position at one of the vertices

# Create shapes
center_shape = pm.Poly(center_body, [(-100, -100), (100, -100), (100, 100), (-100, 100)])
vertex_shape = pm.Circle(vertex_body, vertex_radius)
vertex_shape.sensor = True

# Add bodies and shapes to the space
space.add(center_body, center_shape)
space.add(vertex_body, vertex_shape)

# Create a PinJoint
ancher1 = Vec2d(100, 100)  # Relative to center_body
ancher2 = Vec2d(0, 0)  # Relative to vertex_body
pj = pm.PinJoint(center_body, vertex_body, ancher1, ancher2)

# Add the PinJoint to the space
space.add(pj)

# Main loop
running = True
while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False

    # Clear screen
    screen.fill((255, 255, 255))

    # Step the simulation
    space.step(1/60.0)

    # Draw the center body
    center_pos = center_body.position
    pygame.draw.polygon(screen, (102, 178, 255), [(center_pos.x + x, center_pos.y + y) for x, y in [(-100, -100), (100, -100), (100, 100), (-100, 100)]])

    # Draw the vertex body
    vertex_pos = vertex_body.position
    pygame.draw.circle(screen, (0, 0, 0), (int(vertex_pos.x), int(vertex_pos.y)), vertex_radius)

    # Draw the PinJoint
    pygame.draw.line(screen, (255, 102, 102), (center_pos.x + ancher1.x, center_pos.y + ancher1.y), (vertex_pos.x + ancher2.x, vertex_pos.y + ancher2.y), 2)

    # Update the display
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
Enter fullscreen mode Exit fullscreen mode

The meaning of ancher1 and ancher2: they are relative position to respective body position! (see the part of drawing PinJoint). For example the "(0,0)" means the pin is put on the body position exactly, while ancher1 has an offset, for example, the body center is (0,0) and the body has a shape with rectangular [(-1, -1), (1, -1), (1, 1) (-1, 1)] and we actually put the pin related to body1 on the four vertices.

In a word, this part gives a point a realistic circle body and pin this circle body at the original coordinate of point.

Image description

Top comments (0)