Search code examples
pythonpygamephysics

Implementing basic physics into a simple 2d pygame (inertia and gravity only)


I am new to pygame and game design overall. I am making a game where a ball follows the cursor. I want the ball to have some physics like inertia and gravity, so that when I fling the ball around it doesn't just make a straight line to the cursor and stop. How do I do this ? ( How do I add inertia and gravity ) My sprite:

    class Ball(pg.sprite.Sprite):

    def __init__(self, radius=30):
        super(Ball, self).__init__()
        self.height, self.width = 60, 60
        self.surf = pg.Surface((self.width, self.height))
        self.surf.fill(black)
        self.surf.set_colorkey(black)

        self.rect = self.surf.get_rect()
        self.center = (self.width//2, self.height//2)

        pg.draw.circle(self.surf, white, self.center, radius)

        # Special varis :

        self.velocity = 0

    def update(self, mousepos):
        if mousepos[0] > self.rect.x:
            self.velocity += 1
        if mousepos[0] < self.rect.x:
            self.velocity -= 1

        self.move(self.velocity)

    def move(self, v):
        self.rect.move_ip(v, 0)

        if self.velocity > 0:
            self.velocity -= 0.1
        else:
            self.velocity += 0.1

        # collision detection for edge of screen

        if self.rect.x + self.width > width:
            self.rect.x = width - self.width
            self.velocity = 0

        elif self.rect.x < 0:
            self.rect.x = 0
            self.velocity = 0

        if self.rect.y > height:
            self.rect.y = height

        elif self.rect.y - self.height < 0:
            self.rect.y = self.height

Solution

  • Firstly, when doing any form of physics, use vectors, not scalars variables. This is because forces, like gravity are made of 2 components, Fx and Fy (the x component and the y component). This also applies to motion descriptors, like velocity and acceleration.

    According to your code, your velocity is just stored as 1 variable meaning it is a scalar and affects both the x and y components equally. This is not true... you do not see gravity affecting an object's x direction in real life, do you?; (ie, horizontal motion),

    rather the y direction only; (ie, vertical motion).

    Have your velocity as stored in two vars, a velocityX and velocityY. This will give you more control in which direction the objects move and also which direction certain forces affect your objects (like gravity only affecting the y component.), leading to more efficiency and accuracy.

    This is effectively the meaning of vectors, when something is described relative to its componential position, direction and magnitude (size).

    If you do want to know more, I believe I have already answered this here.

    As for your problem of: fling the ball around it doesn't just make a straight line to the cursor and stop:

    Look at @p.phidot 's comment above.