My circle in `pygame` is going out of boundaries and then coming back (clipping through the boundary)

Viewed 80

I'm building a simple 2D physics engine using pygame and made a circle, which has velocity and acceleration, and if you press the arrow keys the acceleration of the sphere changes. I'm going to implement elastic and inelastic collisions, friction, air resistance etc. But the problem I'm having is that I set boundaries to the window so the circle can't go out of the window but it's going out of the boundary and coming back again in a fraction of a second, it's doesn't act like a wall more like a repulsive force. This is my code.

import pygame as pyg
pyg.init()
win = pyg.display.set_mode((800, 800))
pyg.display.set_caption('physics engine')
crash = False
jump = False
x = 400
y = 400
vel_x = 1
vel_y = 1
acc_x = 5
acc_y = 5
g = 0

while not crash:
    pyg.time.delay(50)
    for event in pyg.event.get():
        if event.type == pyg.QUIT:
            crash = True
    keys = pyg.key.get_pressed()

    if keys[pyg.K_LEFT]:
        vel_x -= acc_x

    if keys[pyg.K_RIGHT]:
        vel_x += acc_x

    if keys[pyg.K_UP]:
        vel_y -= acc_y

    if keys[pyg.K_DOWN]:
        vel_y += acc_y

    if keys[pyg.K_SPACE]:
        jump = True
        vel_y -= 20

    vel_y += g
    win.fill((0, 0, 0))
    print((x, y))
    if vel_x <= 0:
        if x <= 50:
            vel_x = 0
            x = 50
        x += vel_x
    elif vel_x >= 0:
        if x >= 750:
            vel_x = 0
            x = 750
        x += vel_x

    if vel_y <= 0:
        if y <= 50:
            vel_y = 0
            y = 50
        y += vel_y
    elif vel_y >= 0:
        if y >= 750:
            vel_y = 0
            y = 750
        y += vel_y

    game_char = pyg.draw.circle(win, (50, 50, 255), (x, y), 50)
    pyg.display.update()

pyg.quit()

it's an 800*800 square window and the circle's radius is 50 so that's why there's 50 and 750 as boundaries but the circle is like bouncing and then stopping its sort of like a clipping effect where the circle clips through the boundary and stops. I tried to figure out how I solve this but I really couldn't get the circle from clipping through the boundary. Help needed please, thanks in advance!

2 Answers

You have to move the circle, before you restrict the position of the ball to the bounds:

while not crash:
    # [...]

    if vel_x <= 0:
        x += vel_x
        if x <= 50:
            vel_x = 0
            x = 50
    elif vel_x >= 0:
        x += vel_x
        if x >= 750:
            vel_x = 0
            x = 750
    if vel_y <= 0:
        y += vel_y
        if y <= 50:
            vel_y = 0
            y = 50
    elif vel_y >= 0:
        y += vel_y
        if y >= 750:
            vel_y = 0
            y = 750

Anyway I suggest to simplify the code:

while not crash:
    # [...]

    x += vel_x
    y += vel_y
    if x < 50 or x > 750:
        x = max(50, min(750, x))
        vel_x = 0
    if y < 50 or y > 750:
        y = max(50, min(750, y))
        vel_y = 0

You should check the next position of the ball and not the current position. If the next position of the ball (current position + speed) is outside of the boundary then speed must be set equal to zero. Here is the code:

if vel_x <= 0:
    if x+vel_x < 50:
        vel_x = 0
        x = 50
    x += vel_x
elif x >= 0:
    if x+vel_x > 750:
        vel_x = 0
        x = 750
    x += vel_x

if vel_y <= 0:
    if y+vel_y < 50:
        vel_y = 0
        y = 50
    y += vel_y
elif vel_y >= 0:
    if y+vel_y > 750:
        vel_y = 0
        y = 750
    y += vel_y
Related