I defined a function named add_spring
in the following code
import pymunk
import pymunk.pygame_util
import math
pygame.init()
wid, hei = 800, 700
window = pygame.display.set_mode((wid, hei))
def draw(space, window, draw_options):
window.fill("white")
space.debug_draw(draw_options)
pygame.display.update()
def wall(space, wid, hei):
rects = [
[(wid/2, hei - 10), (wid, 20)],
[(wid/2, 10), (wid, 20)]
]
for pos, size in rects:
body = pymunk.Body(body_type=pymunk.Body.STATIC)
body.position = pos
shape = pymunk.Poly.create_box(body, size)
shape.elasticity = 0.4
shape.friction = 0.5
space.add(body, shape)
def create_ball(space, radius, mass):
body = pymunk.Body()
body.position = (500, 350)
shape = pymunk.Circle(body, radius)
shape.mass = mass
shape.color = (55, 0, 0, 100)
space.add(body, shape)
shape.elasticity = 0.9
shape.friction = 0.4
return shape
def add_ball(space):
body = pymunk.Body()
body.position = (500, 500)
shape = pymunk.Circle(body, 20)
shape.mass = 1
shape.friction = 0.7
space.add(body, shape)
return body
def create_ball_a(space, radius, mass):
body = pymunk.Body(body_type=pymunk.Body.STATIC)
body.position = (500, 300)
shape = pymunk.Circle(body, radius)
shape.mass = mass
shape.color = (55, 0, 0, 100)
space.add(body, shape)
shape.elasticity = 0.9
shape.friction = 0.4
return shape
def create_ball_b(space, radius, mass):
body = pymunk.Body(body_type=pymunk.Body.STATIC)
body.position = (550, 300)
shape = pymunk.Circle(body, radius)
shape.mass = mass
shape.color = (55, 0, 0, 100)
space.add(body, shape)
shape.elasticity = 0.9
shape.friction = 0.4
return shape
def add_spring(var1, var2):
dlx = pymunk.DampedSpring(var1, var2, (0, 0), (0, 0), 5, 70, 0)
space.add(dlx)
def run(window, wid, hei):
run = True
clock = pygame.time.Clock()
fps = 60
dt = 1 / fps
space = pymunk.Space()
space.gravity = (0, 981)
big_ball = create_ball(space, 30, 10)
joina = create_ball_a(space, 5, 10)
joinb = create_ball_b(space, 5, 10)
j = pymunk.DampedSpring(big_ball.body, joina.body, (0, 0), (0, 0), 5, 70, 0)
space.add(j)
add_spring(joina, big_ball)
space.add(pymunk.DampedSpring(big_ball.body, joinb.body, (0, 0), (0, 0), 100, 100, 10))
wall(space, wid, hei)
draw_options = pymunk.pygame_util.DrawOptions(window)
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
break
draw(space, window, draw_options)
space.step(dt)
clock.tick(fps)
pygame.quit()
if __name__ == "__main__":
run(window, wid, hei)
But the following error shows up when I run it.
pygame 2.0.1 (SDL 2.0.14, Python 3.8.9)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "e:/pymunk/2D-cloth-simulation/string_d.py", line 104, in <module>
run(window, wid, hei)
File "e:/pymunk/2D-cloth-simulation/string_d.py", line 88, in run
add_spring(joina, big_ball)
File "e:/pymunk/2D-cloth-simulation/string_d.py", line 71, in add_spring
dlx = pymunk.DampedSpring(var1, var2, (0, 0), (0, 0), 5, 70, 0)
File "C:\Users\Kishlay\AppData\Local\Programs\Python\Python38\lib\site-packages\pymunk\constraints.py", line 617, in __init__
_constraint = lib.cpDampedSpringNew(
TypeError: initializer for ctype 'struct cpBody *' must be a cdata pointer, not Body
When I do the same thing without defining a function for it, it works, but in order to keep the code clean, I need it to convert it to a function so that I can do it multiple times without hassle.
You have two mistakes.
It needs .body
(like in other DampedSpring
in your code)
You can get it from var1
, var2
:
dlx = pymunk.DampedSpring(var1.body, var2.body, (0, 0), (0, 0), 5, 70, 0)
Or you can send .body
:
add_spring(joina.body, big_ball.body)
You have to send also space
to this function (to run space.add()
Get it in function:
def add_spring(space, var1, var2):
Send it to function:
add_spring(space, joina.body, big_ball.body)
Full code:
import pygame
import pymunk
import pymunk.pygame_util
import math
# --- constants --- # PEP8: `UPPER_CASE_NAMES`
WIDTH = 800
HEIGHT = 700
FPS = 60
# --- functions --- # PEP8: all function before main code
def draw(space, window, draw_options):
window.fill("white")
space.debug_draw(draw_options)
pygame.display.update()
def wall(space, width, height):
rects = [
[(width/2, height - 10), (width, 20)],
[(width/2, 10), (width, 20)]
]
for pos, size in rects:
body = pymunk.Body(body_type=pymunk.Body.STATIC)
body.position = pos
shape = pymunk.Poly.create_box(body, size)
shape.elasticity = 0.4
shape.friction = 0.5
space.add(body, shape)
def create_ball(space, radius, mass):
body = pymunk.Body()
body.position = (500, 350)
shape = pymunk.Circle(body, radius)
shape.mass = mass
shape.color = (55, 0, 0, 100)
shape.elasticity = 0.9
shape.friction = 0.4
space.add(body, shape)
return shape
def add_ball(space):
body = pymunk.Body()
body.position = (500, 500)
shape = pymunk.Circle(body, 20)
shape.mass = 1
shape.friction = 0.7
space.add(body, shape)
return body
def create_ball_a(space, radius, mass):
body = pymunk.Body(body_type=pymunk.Body.STATIC)
body.position = (500, 300)
shape = pymunk.Circle(body, radius)
shape.mass = mass
shape.color = (55, 0, 0, 100)
shape.elasticity = 0.9
shape.friction = 0.4
space.add(body, shape)
return shape
def create_ball_b(space, radius, mass):
body = pymunk.Body(body_type=pymunk.Body.STATIC)
body.position = (550, 300)
shape = pymunk.Circle(body, radius)
shape.mass = mass
shape.color = (55, 0, 0, 100)
shape.elasticity = 0.9
shape.friction = 0.4
space.add(body, shape)
return shape
def add_spring(space, body1, body2):
dlx = pymunk.DampedSpring(body1, body2, (0, 0), (0, 0), 5, 70, 0)
space.add(dlx)
return dlx
def run(WIDTH, HEIGHT):
pygame.init()
window = pygame.display.set_mode((WIDTH, HEIGHT))
dt = 1 / FPS
clock = pygame.time.Clock()
space = pymunk.Space()
space.gravity = (0, 981)
big_ball = create_ball(space, 30, 10)
joina = create_ball_a(space, 5, 10)
joinb = create_ball_b(space, 5, 10)
j = pymunk.DampedSpring(big_ball.body, joina.body, (0, 0), (0, 0), 5, 70, 0)
space.add(j)
add_spring(space, joina.body, big_ball.body)
space.add(pymunk.DampedSpring(big_ball.body, joinb.body, (0, 0), (0, 0), 100, 100, 10))
wall(space, WIDTH, HEIGHT)
draw_options = pymunk.pygame_util.DrawOptions(window)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
break
draw(space, window, draw_options)
space.step(dt)
clock.tick(FPS)
pygame.quit()
if __name__ == "__main__":
run(WIDTH, HEIGHT)