Надувной шар Pygame проваливается сквозь пол

#python #pygame

#python #pygame

Вопрос:

Приведенный ниже код отскакивает от мяча, но по какой-то причине мяч проходит сквозь землю после того, как он заканчивает свои прыжки. Кто-нибудь знает, почему? Идея кода заключается в том, что мяч начинается в верхнем левом углу, затем падает и подпрыгивает, а затем поднимается и опускается и так далее, пока не перестанет подпрыгивать, но когда он перестает подпрыгивать, он начинает дрожать и медленно проваливается сквозь землю. Idk почему, и я не могу понять это. Кто-нибудь знает, почему? Спасибо за помощь

 import pygame
pygame.init()

#All keyboard and mouse input will be handled by the following function
def handleEvents():
#This next line of code lets this function access the dx and dy
#variables without passing them to the function or returning them.
    global dx,dy
#Check for new events
    for event in pygame.event.get():
    #This if makes it so that clicking the X actually closes the game
    #weird that that wouldn't be default.
        if event.type == pygame.QUIT:
            pygame.quit(); exit()
    #Has any key been pressed?
        elif event.type == pygame.KEYDOWN:
        #Escape key also closes the game.
            if event.key == pygame.K_ESCAPE:
                pygame.quit(); exit()
            elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
                dx = dx   5
            elif event.key == pygame.K_LEFT or event.key == pygame.K_a:
                dx = dx - 5
            elif event.key == pygame.K_UP or event.key == pygame.K_w:
                dy = dy - 5
            elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
                dy = dy   5

width = 1000
height = 600
size = (width, height)
black = (0, 0, 0) #r g b

screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()

ball = pygame.image.load("ball.gif")
ballrect = ball.get_rect()

x = 0
y = 0
dx = 3
dy = 3

done = False
while not done:
    handleEvents()

    #Move the ball
    x = x   dx
    y = y   dy
    ballrect.topleft = (x,y)

    #PART A

    if ballrect.left < 0 or ballrect.right > width:
        dx = -dx
    if ballrect.top < 0 or ballrect.bottom > height:
        dy = -dy

'''If the ball is outside of the range delta y,
then delta y becomes the negative version of it, and the same goes
for delta x if it is outside the boundries of delta x
'''
#PART B

    dy = dy * 0.99
    dx = dx * 0.99
'''Could be useful if you want
the ball to stop moving after a certain amount of time,
or the opposite, it could make the ball slowly move a greater distance each frame'''

#PART C

    dy = dy   0.3

'''dy slowly gets .3 added to itself each frame, making the bounce
smaller each time until eventually it stops fully'''



#Draw everything
    screen.fill(black)
    screen.blit(ball, ballrect)
    pygame.display.flip()

#Delay to get 30 fps
    clock.tick(30)

pygame.quit()
  

Комментарии:

1. возможно, сделайте оператор if, чтобы проверить, находится ли положение y шара ниже уровня пола, и если это так, вы можете установить его в качестве координаты y пола

2. Возникшая проблема связана с используемой абстрактной физической моделью. Я рекомендую использовать реальный физический движок, если требуется симуляция, близкая к реальной жизни. Pygame обычно работает в паре с физическим движком Pymunk.

3. Кроме того, вот пример прыгающих шаров с Pygame Pymunk. Взято из официальных примеров Pymunk.

Ответ №1:

Поскольку скорость падения шара превышает 1 пиксель, вы должны убедиться, что мяч не падает ниже нижнего края окна.
Вам нужно ограничить нижнюю часть шара нижней частью окна:

 done = False
while not done:
    # [...]

    x = x   dx
    y = y   dy
    ballrect.topleft = (x,y)

    #PART A

    if ballrect.left < 0 or ballrect.right > width:
        dx = -dx
    if ballrect.top < 0:
        dy = -dy
    if ballrect.bottom > height:
        ballrect.bottom = height                       # <---
        y = ballrect.top                               # <---
        dy = -dy

    # [...]