1

我对编程很陌生,因为它只是作为一门学科引入我的学校,我需要一些帮助。我的任务是制作三个球(矩形图像)在屏幕周围弹跳并相互弹开的动画。我的三个球和墙壁的反弹都很好,但我不知道如何让它们相互反弹。任何帮助将不胜感激,我当前的代码如下:

import pygame
import random
import sys

if __name__ =='__main__':

    ball_image1 = 'beachball1.jpg'
    ball_image2 = 'beachball2.jpg'
    ball_image3 = 'beachball3.jpg'
    bounce_sound = 'thump.wav'
    width = 800
    top = 600
    x = 0
    y = 0
    background_colour = 0,0,0
    caption= 'Bouncing Ball animation'
    velocity1 = [-1,-1]
    velocity2 = [-1,1]
    velocity3 = [1,-1]
    pygame.init ()
    frame = pygame.display.set_mode ((width, top))
    pygame.display.set_caption (caption)
    ball1= pygame.image.load (ball_image1). convert()
    ball2= pygame.image.load (ball_image2). convert()
    ball3= pygame.image.load (ball_image3). convert()
    ball_boundary_1 = ball2.get_rect (center=(random.randint(50, 750),random.randint(50, 550)))
    ball_boundary_2 = ball2.get_rect (center=(random.randint(50, 750),random.randint(50, 550)))
    ball_boundary_3 = ball2.get_rect (center=(random.randint(50, 750),random.randint(50, 550)))
    sound = pygame.mixer.Sound (bounce_sound)
    while True:
        for event in pygame.event.get():
            print event 
            if event.type == pygame.QUIT: sys.exit(0)
        if ball_boundary_1.left < 0 or ball_boundary_1.right > width:
            sound.play()
            velocity1[0] = -velocity1[0]
        if ball_boundary_1.top < 0 or ball_boundary_1.bottom > top:
            sound.play()
            velocity1[1] = -velocity1[1]
        if ball_boundary_2.left < 0 or ball_boundary_2.right > width:
            sound.play()
            velocity2[0] = -velocity2[0]
        if ball_boundary_2.top < 0 or ball_boundary_2.bottom > top:
            sound.play()
            velocity2[1] = -velocity2[1]
        if ball_boundary_3.left < 0 or ball_boundary_3.right > width:
            sound.play()
            velocity3[0] = -velocity3[0]
        if ball_boundary_3.top < 0 or ball_boundary_3.bottom > top:
            sound.play()
            velocity3[1] = -velocity3[1]

        ball_boundary_1 = ball_boundary_1.move (velocity1)
        ball_boundary_2 = ball_boundary_2.move (velocity2)
        ball_boundary_3 = ball_boundary_3.move (velocity3)
        frame.fill (background_colour)
        frame.blit (ball1, ball_boundary_1)
        frame.blit (ball2, ball_boundary_2)
        frame.blit (ball3, ball_boundary_3)
        pygame.display.flip() 
4

3 回答 3

3

当两个物体“碰撞”时,它们基本上存在于同一个物理空间中,因此您必须检查这一点。在 2d 中,这很好也很容易,尤其是对于矩形。基本上编写一个名为“overlap”的函数,如果两个球发生碰撞,它会返回一个真值。例如:

for (i = 0; i < numberOfBalls; i++) {
    for (j = i+1; j < numberOfBalls; j++) {
        if (overlap (ball_rect[i], ball_rect[j])) {
            // you will need to write this reverse velocity code differently
            // to comply with the code above but I recommend that the balls 
            // go in an array with three elements so that you can index 
            // them. (Useful in for loops as seen above)
            ball_xvelocity[i] *= -1;
            ball_xvelocity[j] *= -1;
            ball_yvelocity[i] *= -1;
            ball_yvelocity[j] *= -1;
        }
    }
}

我将把重叠功能留给你,但你应该谷歌“矩形碰撞检测”,你会发现如何。你会发现它真的没有那么可怕,并且会让你相信你可以研究和学习编程概念。

NB 具体没有给出python代码。因为这是家庭作业,所以你的工作就是写答案。对不起,只是一个 SO 政策。希望这可以帮助。:)

于 2009-04-25T14:02:19.750 回答
1

正如我的讲师在我对此的特别评估中添加的那样,

一旦第二个球在框架周围弹跳,添加一些代码来改变球碰撞时的方向。PyGame 提供了一个函数,允许您检测两个 Rect 对象之间是否发生了碰撞。该函数名为colliderect,调用方式如下。如果两个 Rect 对象被命名为 ball_boundary_1 和 ball_boundary_2,您可以检查是否有碰撞:

if ball_boundary_1.colliderect(ball_boundary_2):

    # alter the direction of the balls with the usual method

因此,这将用于检查“是否”发生碰撞,返回 True,并运行一些代码来反转速度。祝你好运,:我自己还没有真正做到这一点,我正要尝试一下

于 2010-04-07T09:22:54.687 回答
1

好吧,您实际上在提供的代码中有一些线索。检测球是否在墙上反弹的方法是检查球的顶部边界是否小于 0,这意味着它已经触及顶部边界并且需要反弹,因此您需要改变方向。

所以代码:

if ball_boundary_1.top < 0 or ball_boundary_1.bottom > top:
        sound.play()
        velocity1[1] = -velocity1[1]

如果球在地板或天花板上反弹,基本上会改变球的垂直运动。

因此,要修改它,您需要问自己,如果两个球相互弹跳意味着什么……这意味着它们的边界以多种方式重叠。因此,例如,您可以检查球 1 的左侧或右侧是否在球 2 的水平尺寸内,并且球 1 的顶部或底部是否在球 2 的垂直尺寸内,然后两个球接触,因此改变两者的速度球。

于 2009-04-25T14:06:40.097 回答