Question

RANDOM PACMAN The task was to animate 5 objects(pac man and 4 ghosts that moved randomly,if pac man collides with a ghost he bounce's off it, the ghosts pass though one another and are unaffected when hit by pac man. When the mouse is clicked the mode changes and the ghosts bounce of pac man if they collide and pac man is unaffected, if the mouse is clicked again it reverts back to the original mode. Functions ghost_collision and mode_swich deal with this and I have a if statement at the end for the mouse click. BUG1I can't work out why when sprites collide sometimes they become immobile (in both modes). Also is I possible to replace some of the repeated if statements with a list and a for loop? If so how? I tried making a list of all the ghost_boundary variables and then using

 For sprite in sprite_list():        
    sprite.left < 0 or sprite.right > WIDTH:
    sprite_velocity[1] = -1 * sprite_velocity[1]

and that failed.

import pygame
from random import *



pygame.init()

def ghost_collision():
   # global pacman_up, pacman_right, pacman_velocity why?
    SCREAM.play()
    pacman_velocity[0] = randint(-1,1)
    pacman_velocity[1] = randint(-1,1)
   if pacman_velocity[0] < 0:
        pacman = pygame.image.load(PACMAN_LEFT).convert()
    elif pacman_velocity[0] > 0:
        pacman = pygame.image.load(PACMAN_RIGHT).convert()
    return pacman_velocity

def mode_switch():
    global mode
    blue_right, orange_right, pink_right,\
          red_right, blue, orange, pink, red
    if mode == False:
        mode = True
        blue = pygame.image.load(GHOST_SCARED).convert()
        orange = pygame.image.load(GHOST_SCARED).convert()
        pink = pygame.image.load(GHOST_SCARED).convert()
        red = pygame.image.load(GHOST_SCARED).convert()
    else:
        mode = False
        if blue_right == True:
            blue = pygame.image.load(BLUE_LEFT).convert()
            blue_right = False
    else:
        blue = pygame.image.load(BLUE_RIGHT).convert()
        blue_right = True
    if orange_right == True:
        orange = pygame.image.load(ORANGE_LEFT).convert()
        orange_right = False
    else:
        orange = pygame.image.load(ORANGE_RIGHT).convert()
        orange_right = True
    if pink_right == True:
        pink = pygame.image.load(PINK_LEFT).convert()
        pink_right = False
    else:
        pink = pygame.image.load(PINK_RIGHT).convert()
        pink_right = True
    if red_right == True:
        red = pygame.image.load(RED_LEFT).convert()
        red_right = False
    else:
        red = pygame.image.load(RED_RIGHT).convert()
        red_right = True


PACMAN_LEFT = 'pacman-left.png'#import all necessary images and sounds
PACMAN_RIGHT = 'pacman-right.png'
BLUE_LEFT = 'blue-left.png'
BLUE_RIGHT = 'blue-right.png'
ORANGE_LEFT = 'orange-left.png'
ORANGE_RIGHT = 'orange-right.png'
PINK_LEFT = 'pink-left.png'
PINK_RIGHT = 'pink-right.png'
RED_LEFT = 'red-left.png'
RED_RIGHT = 'red-right.png'
GHOST_SCARED = 'vulnerable.png'
BOUNCE_SOUND = 'Thump.wav'
SCREAM_SOUND = 'pacman_death.wav'
GHOST_WAIL = 'pacman_eatfruit.wav'
SOUND = pygame.mixer.Sound(BOUNCE_SOUND)
SCREAM = pygame.mixer.Sound(SCREAM_SOUND)
WAIL = pygame.mixer.Sound(GHOST_WAIL)
WIDTH = 800
HEIGHT = 600
BACKGROUND_COLOUR = 0, 0, 0
CAPTION = 'Random Pacman'
pacman_up = True#define image direction controlling variables
pacman_right = True
blue_right = False
orange_right = True
pink_right = False
red_right = True
mode = False

frame = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(CAPTION)
pacman = pygame.image.load(PACMAN_RIGHT).convert()#create sprites and define boundaries
pacman_boundary = pacman.get_rect(center = (300,300))
pacman_velocity = [1, 1]
blue = pygame.image.load(BLUE_LEFT).convert()
blue_boundary = pacman.get_rect(center = (300,300))
blue_velocity = [-1, -1]
orange = pygame.image.load(ORANGE_RIGHT).convert()
orange_boundary = pacman.get_rect(center = (300,300))
orange_velocity = [1, -1]
pink = pygame.image.load(PINK_LEFT).convert()
pink_boundary = pacman.get_rect(center = (300,300))
pink_velocity = [-1, 1]
red = pygame.image.load(RED_RIGHT).convert()
red_boundary = pacman.get_rect(center = (300,300))
red_velocity = [1, 1]

finished = False
while not finished:
    pygame.event.pump()
        for event in pygame.event.get():
        if event.type == pygame.QUIT:
            finished = True
        if event.type == pygame.MOUSEBUTTONUP:
            mode_switch()

    #####################################################

if pacman_boundary.left < 0 or pacman_boundary.right > WIDTH:#pacman bounce code
    SOUND.play()
    pacman_velocity[0] = -1 * pacman_velocity[0]
    if pacman_velocity[0] < 0:
        pacman = pygame.image.load(PACMAN_LEFT).convert()
    elif pacman_velocity[0] > 0:
        pacman = pygame.image.load(PACMAN_RIGHT).convert()
    pacman_velocity[1] = randint(-1,1)

if pacman_boundary.top < 0 or pacman_boundary.bottom > HEIGHT:
    SOUND.play()
    pacman_velocity[1] = -1 * pacman_velocity[1]

if mode == False:        
    if pacman_boundary.colliderect(blue_boundary)\
       or pacman_boundary.colliderect(orange_boundary)\
       or pacman_boundary.colliderect(pink_boundary)\
       or pacman_boundary.colliderect(red_boundary):
        ghost_collision()

    #####################################################

if blue_boundary.left < 0 or blue_boundary.right > WIDTH:#blue bounce code
    blue_velocity[0] = -1 * blue_velocity[0]
    if mode == False:
        if blue_right == True:
            blue = pygame.image.load(BLUE_LEFT).convert()
            blue_right = False
        else:
            blue = pygame.image.load(BLUE_RIGHT).convert()
            blue_right = True

if blue_boundary.top < 0 or blue_boundary.bottom > HEIGHT:
    SOUND.play()
    blue_velocity[1] = -1 * blue_velocity[1]

if mode == True:
    if pacman_boundary.colliderect(blue_boundary):

        blue_velocity[0] = randint(-1,1)
        blue_velocity[1] = randint(-1,1)
        WAIL.play()


#####################################################

if orange_boundary.left < 0 or orange_boundary.right > WIDTH:#orange bounce code
    orange_velocity[0] = -1 * orange_velocity[0]
    if mode == False:
        if orange_right == True:
            orange = pygame.image.load(ORANGE_LEFT).convert()
            orange_right = False
        else:
            orange = pygame.image.load(ORANGE_RIGHT).convert()
            orange_right = True

if orange_boundary.top < 0 or orange_boundary.bottom > HEIGHT:
    SOUND.play()
    orange_velocity[1] = -1 * orange_velocity[1]

if mode == True:
    if pacman_boundary.colliderect(orange_boundary):
        orange_velocity[0] = randint(-1,1)
        orange_velocity[1] = randint(-1,1)
        WAIL.play()

#####################################################

if pink_boundary.left < 0 or pink_boundary.right > WIDTH:#pink bounce code
    pink_velocity[0] = -1 * pink_velocity[0]
    if mode == False:
        if pink_right == True:
            pink = pygame.image.load(PINK_LEFT).convert()
            pink_right = False
        else:
            pink = pygame.image.load(PINK_RIGHT).convert()
            pink_right = True

if pink_boundary.top < 0 or pink_boundary.bottom > HEIGHT:
    SOUND.play()
    pink_velocity[1] = -1 * pink_velocity[1]

if mode == True:
    if pacman_boundary.colliderect(pink_boundary):
        pink_velocity[0] = randint(-1,1)
        pink_velocity[1] = randint(-1,1)
        WAIL.play()

#####################################################

if red_boundary.left < 0 or red_boundary.right > WIDTH:#red bounce code
    red_velocity[0] = -1 * red_velocity[0]
    if mode == False:
        if red_right == True:
            red = pygame.image.load(RED_LEFT).convert()
            red_right = False
        else:
            red = pygame.image.load(RED_RIGHT).convert()
            red_right = True

if red_boundary.top < 0 or red_boundary.bottom > HEIGHT:
    SOUND.play()
    red_velocity[1] = -1 * red_velocity[1]

if mode == True:
    if pacman_boundary.colliderect(red_boundary):
        red_velocity[0] = randint(-1,1)
        red_velocity[1] = randint(-1,1)
        WAIL.play()

#####################################################



pacman_boundary = pacman_boundary.move(pacman_velocity)
blue_boundary = blue_boundary.move(blue_velocity)
orange_boundary = orange_boundary.move(orange_velocity)
pink_boundary = pink_boundary.move(pink_velocity)
red_boundary = red_boundary.move(red_velocity)
frame.fill(BACKGROUND_COLOUR)
frame.blit(pacman, pacman_boundary)
frame.blit(blue, blue_boundary)
frame.blit(orange, orange_boundary)
frame.blit(pink, pink_boundary)
frame.blit(red, red_boundary)
pygame.display.flip()

pygame.quit()
Was it helpful?

Solution

The reason the sprites sometimes become immobile after colliding is because of this code here:

pacman_velocity[0] = randint(-1,1)
pacman_velocity[1] = randint(-1,1)

randint for that range means you're getting an integer value that is either -1, 0, or 1.
From the docs: (http://docs.python.org/2/library/random.html)

random.randint(a, b)
Return a random integer N such that a <= N <= b

That means that (theoretically) each time there is a collision, there is a 1/3 chance that the x component of the velocity will be 0, and a 1/3 chance that the y component of the velocity will be zero. If you only want to select either 1 or -1, try the random.choice() function:

pacman_velocity[0] = random.choice((-1, 1))
pacman_velocity[1] = random.choice((-1, 1))

If you wanted to include 0 as a possibility, but want to reduce its frequency, you could accomplish that with something like this:

pacman_velocity[0] = random.choice((-1, -1, -1, 0, 1, 1, 1))
pacman_velocity[0] = random.choice((-1, -1, -1, 0, 1, 1, 1))

The problem with this loop you tried:

For sprite in sprite_list():        
    sprite.left < 0 or sprite.right > WIDTH:
    sprite_velocity[1] = -1 * sprite_velocity[1]

is that you are checking to see if the sprite has passed the left or right boundary of the screen, but then instead of reversing the x component of the sprite's velocity, you are reversing the y component of the velocity. Also, you don't have an if at the beginning of the condition. Try this:

For sprite in sprite_list:
    if sprite.left < 0 or sprite.right > WIDTH:
       sprite_velocity[0] = -1 * sprite_velocity[0]
    if sprite.top < 0 or sprite.bottom > HEIGHT:
        sprite_velocity[1] = -1 * sprite_velocity[1]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top