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
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.