views:

289

answers:

3

I am very new at programming as it was only just introduced into my school as a subject and I need some help. I have been given the task to have an animation of three balls (rectangle images) bouncing around the screen and off each other. I have the three balls and the bouncing of the walls all down good, but I don't know how to have them bounce off each other. Any help would be greatly appreciated, my current code is as follows:

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()
+3  A: 

When two objects 'collide' they basically exist in the same physical space and therefore you have to check for this. In 2d this is nice and easy, especially for rectangular shapes. Basically write a function called 'overlap' that returns a true value if two of the balls collide. For example:

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;
        }
    }
}

I will leave the overlap function up to you but you should google 'rectangluar collision detection' and you will find out how. You will se that it is really not that scary and will give you faith that you can research and learn programming concepts.

N.B. Specifically did not give python code. Since it is homework it is your job to write the answer. Sorry, just an SO policy. Hope this helps. :)

Robert Massaioli
A: 

Well you actually have some clues in the code that you provide. The way you are detecting if the ball bounces on the wall is to check if the top boundary of the ball is less than 0 meaning that it has touched the top boundary and needs to bounce so you change direction.

So the code:

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

basically changes to vertical movement of the ball if it bounces on the floor or ceiling.

So to modify this you need to ask your self what it means if two balls bounce on each other...and it would mean that their boundaries overlap in any of a number of ways. So, for instance, you can check if either the left or right of ball 1 is inside ball 2's horizontal dimensions AND the top or bottom of ball 1 is inside ball 2's vertical dimensions, then the two balls are touching so change the velocity of both balls.

Vincent Ramdhanie
A: 

As my lecturer added to my particular assessment on this,

"Once a second ball is bouncing around the frame, add some code to change the directions of the balls if they collide. PyGame provides a function that allows you to detect if a collision has occurred between two Rect objects. The function is named colliderect and is called in the following manner. If two Rect objects are named ball_boundary_1 and ball_boundary_2, you could check for a collision with:

if ball_boundary_1.colliderect(ball_boundary_2):

/##alter the direction of the balls with the usual method

" end qoute

so, this would be used to check 'if' a collision occurs, return True, and run some code to reverse velocity. good luck, :D I havnt actually done this bit yet myself, im just about to try it

kyran