Pygame弹跳球穿过地板

3
下面的代码反弹了一个球,但由于某种原因,在球完成弹跳后球穿过了地面。 有人知道为什么吗? 代码的想法是球从左上角开始下落并弹跳,然后上升、再次下降,如此往复,直到停止弹跳,但当它停止弹跳时,开始抖动并缓慢沉入地面。 我不知道为什么,也无法解决。 有人知道为什么吗? 感谢帮助。
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()

也许可以编写一个 if 语句来检查球的纵向位置是否在地板以下,如果是,您可以将其设置为地板的纵坐标。 - BWallDev
遇到的问题是由于使用了抽象物理模型。如果需要接近真实仿真,我建议使用真实的物理引擎。Pygame通常与Pymunk物理引擎配对使用。 - Attila Viniczai
此外,这里有一个使用Pygame + Pymunk的弹跳球示例。取自于官方Pymunk示例中的弹跳球示例页面(http://www.pymunk.org/en/latest/examples.html#bouncing-balls-py)。示例代码可在此链接中找到:https://github.com/viblo/pymunk/blob/master/examples/bouncing_balls.py。 - Attila Viniczai
1个回答

2

由于球的下落速度大于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

    # [...]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接