1

Trying the following code with python 2.7. Basically its a circle that hangs from a bar and an apple that you can hit with an impulse by pressing the spacebar. There is also a square.

import time
import pygame
import pymunk
import pymunk.pygame_util
import sys

pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()

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

ball_body = pymunk.Body(100, 100)
ball_body.position = 400.0, 300.0
ball_body.angular_velocity = 10.0
ball_shape = pymunk.Circle(ball_body, 15)
ball_shape.friction = 0.5
ball_shape.elasticity = 0.9
ball_shape.color = (0,0,0,0)
space.add(ball_body, ball_shape)


static_lines = [pymunk.Segment(space.static_body, (20,20), (780,20), 2),
                pymunk.Segment(space.static_body, (20,580), (780,580), 2),
                pymunk.Segment(space.static_body, (20,20), (20,580), 2),
                pymunk.Segment(space.static_body, (780,20), (780,580), 2)]

for static_line in static_lines:
    static_line.color = (255,255,255)
    static_line.elasticity = 0.9
    static_line.friction = 1

space.add(static_lines)


i = 0
prev_body = pymunk.Body(10, 10000)
prev_body.position = (300, 580)
chain_fix_point = pymunk.Body()
chain_fix_point.position = (300, prev_body.position[1])

# Another

i = 0
prev_body = pymunk.Body(10, 10000)
prev_body.position = (600, 580)
chain_fix_point = pymunk.Body()
chain_fix_point.position = (600, prev_body.position[1])

while i < 20:
    # rotation_center_body = pymunk.Body()
    # rotation_center_body.position = (400, prev_body.position[1] - 20)

    body = pymunk.Body(1, 1)
    body.position = (600, prev_body.position[1] - 10)

    line = pymunk.Circle(body, 5)
    line.elasticity = 0
    line.friction = 1
    if i == 0:
        rotation_center_joint = pymunk.PinJoint(body, chain_fix_point)
    else:
        rotation_center_joint = pymunk.PinJoint(body, prev_body)

    space.add(line, body, rotation_center_joint)

    prev_body = body

    i += 1

blob_body = pymunk.Body(5, 1)
blob_body.position = prev_body.position[0], prev_body.position[1] - 40
blob_shape = pymunk.Circle(blob_body, 20)
rotation_center_joint = pymunk.SlideJoint(blob_body, prev_body,(0,0),(0,0),0,40)
space.add(blob_body, blob_shape, rotation_center_joint)

appleimg = pygame.image.load('apple.png')


box_body = pymunk.Body(10,10000)
box_body.position = 600, 300
box_vertices = [(570, 270),(570, 330),(630,330),(630,270)]
box_shape = pymunk.Poly(box_body, box_vertices, offset=(0, 0), radius=1).create_box(box_body, size = (60,60))
box_shape.friction = 0.5
box_shape.elasticity = 0.9
box_shape.color = (255,0,0)
space.add(box_body, box_shape)


def main():
    running = True
    angle = 0;
    while running == True:
        print "game loop"
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    ball_body.apply_impulse(j = (100000, 100000))

        screen.fill((0,0,0))
        pymunk.pygame_util.draw(screen, space)
        if ball_body.angle != 0:
            angle += ball_body.angular_velocity
        img = pygame.transform.rotate(appleimg, angle)
        screen.blit(img, (ball_body.position[0] - 20, 580 - ball_body.position[1]))
        pygame.display.flip()
        clock.tick(60)
        space.step(1/60)


    pygame.quit()
    quit()

main()

The gameloop runs but the position does not update.

This code worked pretty well for python 3.5. But when I switched to 2.7, its failing.

dnit13
  • 2,478
  • 18
  • 35
Saptarshi
  • 603
  • 2
  • 7
  • 15

1 Answers1

1

The problem is that in python 2.x you get 0 when you divide 1 by 60 when you call the step function, since / is doing integer division in 2.x.

You can fix this problem either by importing the python 3 division with from __future__ import division

Or you can divide by a float instead 1/60.0

Check this question for mor info: In Python 2, what is the difference between '/' and '//' when used for division?

Community
  • 1
  • 1
viblo
  • 4,159
  • 4
  • 20
  • 28
  • Just to follow up questions from a newbie to python 1) Is pymunk buggy? Sometimes on heavy impulses two bodies merge and body created first disappears behind the second. 2) In 3.x pymunks pyglet util seems to throw a lot of errors with ints and floats an operators? Have you faced this? Can you suggest a remedy? – Saptarshi Dec 13 '15 at 06:52
  • 1) That is a consequence from how pymunk (and Chipmunk which it builds on) works internally. It is natural. One way to decrease the effect is with a smaller step. – viblo Dec 13 '15 at 12:33
  • 2) Hrm, it you give me a example I can look more closely. The pyglet drawing code is a bit more immature than the pygame one, so Im not that surprised. – viblo Dec 13 '15 at 12:38
  • Thank again! Regarding 1 - I will keep that in my mind. 2 - This is the code -> http://codepad.org/H2IH85tP. Works perfectly well for 2.7 but throws error in 3.5. It is supposed to do the same thing as the code in pygame in the question. – Saptarshi Dec 14 '15 at 04:36
  • I considered Pyglet because you have to write less code + there's gl along with it. But then I noticed it uses more memory compared to pygame. Just exploring all this, to figure out the right combination :). – Saptarshi Dec 14 '15 at 04:40
  • I dont have time to investigate right now (cant run pyglet here), but I created an issue on the pymunk issue tracker to track the problem: https://github.com/viblo/pymunk/issues/97 – viblo Dec 16 '15 at 08:14
  • It seem like it works fine with the new pymunk 5.0 just released. At least this example code: https://gist.github.com/viblo/0b947b50323b5568af1541c5b59b87ba (had to make some adjustments for the updated api) – viblo Jul 17 '16 at 11:21