pythonpygamepymunk

The particle is not moving so what is the problem?


I follow a youtube video 'https://www.youtube.com/watch?v=cCiXqK9c18g' and in the video he make a class that represent a ball and he used pymunk to make a body and added it to the space and after that he created a method inside the ball class that will use pygame to draw the ball and I did almost like him

import pygame
import pymunk

pygame.init()

fps = 60
dt = 1/fps
dsX = 800 # screen width
dsY = 500 # screen height

display = pygame.display.set_mode((dsX, dsY))
space = pymunk.Space()
clock = pygame.time.Clock()

def convert_cor(point): # convet the coordinates from pymunk to pygame coordinates
    return point[0], dsY - point[1]

class Particle: # v: velocity, pos: position[x, y], r: radius of particle(Circle)

    def __init__(self, pos = [0, 0], v = [0, 0], r = 10, color = (255, 0, 0)):

        self.pos = pos
        self.v = v
        self.r = r
        self.color = color
        self.body = pymunk.Body()
        self.body.position = self.pos
        self.body.velocity = self.v # this is the veclocity
        self.shape = pymunk.Circle(self.body, self.r)
        self.shape.dencity = 1
        self.shape.elasticity = 1
        space.add(self.body, self.shape)

    def draw(self):

        pygame.draw.circle(display, self.color, convert_cor(self.pos), self.r)

class Box: # thickness of the sides of the box and L1, L2, L3, L4 are the sides of the box

    def __init__(self, thickness, color):

        self.thickness = thickness
        self.color = color
        L1 = pymunk.Body(body_type = pymunk.Body.STATIC)
        L2 = pymunk.Body(body_type = pymunk.Body.STATIC)
        L3 = pymunk.Body(body_type = pymunk.Body.STATIC)
        L4 = pymunk.Body(body_type = pymunk.Body.STATIC)
        L1_shape = pymunk.Segment(L1, (0, 0), (dsX, 0), self.thickness)
        L2_shape = pymunk.Segment(L2, (dsX, 0), (dsX, dsY), self.thickness)
        L3_shape = pymunk.Segment(L3, (dsX, dsY), (0, dsY), self.thickness)
        L4_shape = pymunk.Segment(L4, (0, dsY), (0, 0), self.thickness)
        space.add(L1, L1_shape)
        space.add(L2, L2_shape)
        space.add(L3, L3_shape)
        space.add(L4, L4_shape)

    def draw(self):

        pygame.draw.line(display, self.color, convert_cor((0, 0)), convert_cor((dsX, 0)), self.thickness * 2)
        pygame.draw.line(display, self.color, convert_cor((dsX, 0)), convert_cor((dsX, dsY)), self.thickness * 2)
        pygame.draw.line(display, self.color, convert_cor((dsX, dsY)), convert_cor((0, dsY)), self.thickness * 2)
        pygame.draw.line(display, self.color, convert_cor((0, dsY)), convert_cor((0, 0)), self.thickness * 2)

def Sim(): # the infinite while loop as a function

    box = Box(2, (0, 255, 255))
    particle = Particle(pos =[dsX/2, dsY/2], v = [-200, 500]) # here i gave the position and the velocity

    while True:

        for event in pygame.event.get():

            if event.type == pygame.QUIT:

                return

        display.fill((255, 255, 255))
        box.draw()
        particle.draw()
        clock.tick(fps)
        space.step(dt)
        pygame.display.update()

Sim()

pygame.quit()

The thing is, I did also a class that will add a rigid sides for the display and i drew the sides from the Box class using the method 'draw' The problem is in the time 5:58 in the video he gave the ball velocity and it start moving and in my code it does not move. any idea why it doen't move? note: I called the ball particle in my code


Solution

  • You error is both a typo and using the wrong variable.

    Inside your particles draw function...

    # OLD
    def draw(self):
            pygame.draw.circle(display, self.color, convert_cor(self.pos), self.r)
    
    # New
    def draw(self):
            pygame.draw.circle(display, self.color, convert_cor(self.body.position), self.r)
    

    You have to use the body's position cause that is the position of the physics body in pymunk's space.

    Secondly...

    class Particle: # v: velocity, pos: position[x, y], r: radius of particle(Circle)
    
        def __init__(self, pos, v, r=10, color=(255, 0, 0)):
            ...
            # Old
            self.shape.dencity = 1
        
            # New
            self.shape.density = 1
    

    Since density was not set to anything Pymunk was having a divide by zero error so it wouldn't update the body's position.