Question

I am creating a piece of code that involves a maze and doors that open when a button is hit. The problem is that when I put in the doors the player collision detects the doors but no longer detects the maze. I have put all my code down on here in hopes that if people can see any other problems they can help Thanks :)

import pygame, sys, random, time


#Setting up the colours
black = (0,0,0)
white = (255,255,255)
blue = (0,0,255)
green = (0,255,0)
red = (255,0,0)
orange = (248,100,1)
slateG = (112,128,144)
pink = (255,20,147)
dTurq = (0,206,209)
honeyD = (240,255,240)
maroon = (128,0,0)
goldenrod = (218,165,32)
sGreen = (0,255,127)
Fus = (255,0,255)


class player(pygame.sprite.Sprite):
    change_x=0
    change_y=0

    #initialise the class
    def __init__(self,x,y):

        pygame.sprite.Sprite.__init__(self)
        #the player will be 13x13
        self.image = pygame.Surface([13,13])
        self.image.fill(maroon)

        self.rect = self.image.get_rect()
        self.rect.top = y
        self.rect.left = x

    def changespeed(self,x,y): #this function changes the speed of the player
        self.change_x+=x
        self.change_y+=y

    def updateWall(self,walls): #This is a collision detection function
        old_x=self.rect.left
        new_x = old_x+self.change_x
        self.rect.left = new_x

        collide = pygame.sprite.spritecollide(self,walls,False)
        if collide:
            self.rect.left = old_x

        old_y = self.rect.top
        new_y = old_y+self.change_y
        self.rect.top = new_y

        collide = pygame.sprite.spritecollide(self,walls,False)
        if collide:
            self.rect.top = old_y

    def updateBarrier1(self,barriers):
        gx=self.rect.left
        nx = gx+self.change_x
        self.rect.left = nx

        collide = pygame.sprite.spritecollide(self,barriers,False)
        if collide:
            self.rect.left = gx

        gy = self.rect.top
        ny = gy+self.change_y
        self.rect.top = ny

        collide = pygame.sprite.spritecollide(self,barriers,False)
        if collide:
            self.rect.top = gy






class Wall(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height,color): #this sets up for the x/y coordinates, the width and the height and the colour of the wall

        pygame.sprite.Sprite.__init__(self)
        #how big will the wall be
        self.image = pygame.Surface([width,height])
        #what colour will the wall be
        self.image.fill(color)

        #initialising the x/y coordinates
        self.rect = self.image.get_rect()
        self.rect.top = y
        self.rect.left = x

class Bar(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height,color):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface([width,height])

        self.image.fill(color)


        self.rect = self.image.get_rect()
        self.rect.top = y
        self.rect.left = x


class Button(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height,color):

        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([width,height]) #the buttons dimensions
        self.image.fill(color) #colour of the button

        #x/y coordinates
        self.rect = self.image.get_rect()
        self.rect.top=y
        self.rect.left=x

#Setting up the walls for the maze
def maze1():
    wall_list = pygame.sprite.RenderPlain()
    #Walls of maze
    walls = [[0,0,20,390,goldenrod],[0,410,20,390,goldenrod],[0,0,1000,20,goldenrod],
             [980,0,20,800,goldenrod],[0,780,980,20,goldenrod],[20,40,940,10,dTurq],
             [950,40,10,350,dTurq],[950,410,10,350,dTurq],[40,750,370,10,dTurq],
             [430,570,10,210,dTurq],[430,570,240,10,dTurq],[660,570,10,210,dTurq],
             [690,550,10,210,dTurq],[690,750,260,10,dTurq],[400,550,10,210,dTurq],
             [40,410,10,350,dTurq],[20,100,30,10,dTurq], [40,100,10,290,dTurq],
             [50,410,460,10,green],[50,380,350,10,green],[430,380,100,10,green],
             [530,380,10,100,green],[500,410,10,100,green],[500,510,60,10,green],
             [550,510,10,30,green],[580,510,10,30,green],[400,540,160,10,dTurq],
             [580,540,120,10,dTurq],[530,480,150,10,green],[680,430,10,60,green],
             [580,510,130,10,green],[710,460,10,60,green],[680,430,250,10,green],
             [710,460,190,10,green],[920,430,10,300,green],[890,460,10,230,green],
             [820,720,100,10,green],[820,690,80,10,green],[810,690,10,40,green],
             [550,410,400,10,sGreen],[550,210,10,200,sGreen],[250,210,300,10,sGreen],
             [250,210,10,120,sGreen],[250,330,180,10,sGreen],[430,330,10,50,sGreen],
             [580,380,370,10,sGreen],[580,180,10,200,sGreen],[220,180,360,10,sGreen],
             [220,180,10,180,sGreen],[220,360,180,10,sGreen],[390,360,10,20,sGreen]]

    for item in walls:
        wall = Wall(item[0],item[1],item[2],item[3],item[4])
        wall_list.add(wall)
    return wall_list


def BarrierWhite():
    barriers = pygame.sprite.RenderPlain()
    barrier = [[500,540,10,40,white],[400,180,10,40,white]]

    for item in barrier:
        barrie = Bar(item[0],item[1],item[2],item[3],item[4])
        barriers.add(barrie)
    return barriers



def BarrierPink():
    wall_list = pygame.sprite.RenderPlain()
    walls = [[550,520,40,10,pink],[20,600,30,10,pink],[300,380,10,40,pink]]

    for item in walls:
        wall = Wall(item[0],item[1],item[2],item[3],item[4])
        wall_list.add(wall)

    return wall_list


def Buttons(): #Creating buttons
    buttons = pygame.sprite.RenderPlain()
    button1 = [[965,765,10,10,white]]
    for item in button1:
        button = Button(item[0],item[1],item[2],item[3],item[4])
        buttons.add(button)

    return buttons

def pinkButton():
    pinkB = pygame.sprite.RenderPlain()
    b = [[835,705,10,10,pink]]
    for item in b:
        button = Button(item[0],item[1],item[2],item[3],item[4])
        pinkB.add(button)
    return pinkB

#main line
pygame.init()

window = pygame.display.set_mode([1000,800])

background = pygame.Surface(window.get_size())
background = background.convert()
background.fill(black)

player = player(25,25)
movingsprt = pygame.sprite.RenderPlain()
movingsprt.add(player)

clock = pygame.time.Clock()

wall_list = maze1()
barriers = BarrierWhite()

buttons = Buttons()
B1 = pinkButton()

done = False


while done == False:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

            #This makes the player move
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                player.changespeed(-6,0)
            if event.key == pygame.K_RIGHT:
                player.changespeed(6,0)
            if event.key == pygame.K_UP:
                player.changespeed(0,-6)
            if event.key == pygame.K_DOWN:
                player.changespeed(0,6)

        #This stops the player from moving
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                player.changespeed(6,0)
            if event.key == pygame.K_RIGHT:
                player.changespeed(-6,0)
            if event.key == pygame.K_UP:
                player.changespeed(0,6)
            if event.key == pygame.K_DOWN:
                player.changespeed(0,-6)

    player.updateWall(wall_list)
    player.updateBarrier1(barriers)



    window.fill(black)

    movingsprt.draw(window)
    barriers.draw(window)
    wall_list.draw(window)
    buttons.draw(window)
    B1.draw(window)


    pygame.display.flip()

    clock.tick(40)

pygame.quit()            

Also if someone could tell me how to put a countdown timer that will disable the player and display a game over sign that would be awesome too :D

Was it helpful?

Solution

Adding doors (or barriers as you call them in your code) makes the wall collision ineffective because of a design problem in your game.

Here's what you do in your main loop:

player.updateWall(wall_list)
player.updateBarrier1(barriers)

You first check with collisions for a wall, then check again for collisions with barriers. The problem is that you incorporated the part that makes your character move in those updateWall and updateBarrier1 methods.

So for instance, if your character collides with a wall, but not with a door, the character will still move because the updateBarrier1 method will not detect a collision with a barrier (door) and will make him move.

Instead, you should do some methods called collides_wall and collides_barrier that return True or False and then replace the two previously quoted lines by:

if not player.collides_wall(wall_list) and not player.collides_barriers(barriers):
    player.move()

With move a method that would move your player as you currently do in the updateSomething methods.

Note: Someone pointed out in the comments that you also don't need two separate methods for walls and barriers collision, because ultimately they are both sprites and you do exactly the same operations on both of them. So just add a collides method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top