I am attempting to make a game in Python where a maze is generated and a sprite has to be navigated through the maze, the maze generation is working but once the sprite is drawn I can't figure out how to make it collide. I have attempted to make it print "true" when it does collide just as a test but I'm unable to make the masks to work or collide.
This is the code that I'm using so far:
import random
import pygame
import sys
import os
WHITE = (255,255,255)
GREY = (20,20,20)
BLACK = (0,0,0)
PURPLE = (100,0,100)
RED = (255,0,0)
BLUE=(0,0,255)
size = (350,350)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Maze Generator")
done = False
global walls_collide
clock = pygame.time.Clock()
width = 25
cols = int(size[0] / width)
rows = int(size[1] / width)
stack = []
class Cell():
def __init__(self,x,y):
global width
self.x = x * width
self.y = y * width
self.visited = False
self.current = False
self.walls = [True,True,True,True] # top , right , bottom , left
# neighbors
self.neighbors = []
self.top = 0
self.right = 0
self.bottom = 0
self.left = 0
self.next_cell = 0
def draw(self):
if self.current:
pygame.draw.rect(screen,RED,(self.x,self.y,width,width))
elif self.visited:
pygame.draw.rect(screen,WHITE,(self.x,self.y,width,width))
if self.walls[0]:
pygame.draw.line(screen,BLACK,(self.x,self.y),((self.x + width),self.y),1) # top
if self.walls[1]:
pygame.draw.line(screen,BLACK,((self.x + width),self.y),((self.x + width),(self.y + width)),1) # right
if self.walls[2]:
pygame.draw.line(screen,BLACK,((self.x + width),(self.y + width)),(self.x,(self.y + width)),1) # bottom
if self.walls[3]:
pygame.draw.line(screen,BLACK,(self.x,(self.y + width)),(self.x,self.y),1) # left
def checkNeighbors(self):
#print("Top; y: " + str(int(self.y / width)) + ", y - 1: " + str(int(self.y / width) - 1))
if int(self.y / width) - 1 >= 0:
self.top = grid[int(self.y / width) - 1][int(self.x / width)]
# print("Right; x: " + str(int(self.x / width)) + ", x + 1: " + str(int(self.x / width) + 1))
if int(self.x / width) + 1 <= cols - 1:
self.right = grid[int(self.y / width)][int(self.x / width) + 1]
#print("Bottom; y: " + str(int(self.y / width)) + ", y + 1: " + str(int(self.y / width) + 1))
if int(self.y / width) + 1 <= rows - 1:
self.bottom = grid[int(self.y / width) + 1][int(self.x / width)]
# print("Left; x: " + str(int(self.x / width)) + ", x - 1: " + str(int(self.x / width) - 1))
if int(self.x / width) - 1 >= 0:
self.left = grid[int(self.y / width)][int(self.x / width) - 1]
#print("--------------------")
if self.top != 0:
if self.top.visited == False:
self.neighbors.append(self.top)
if self.right != 0:
if self.right.visited == False:
self.neighbors.append(self.right)
if self.bottom != 0:
if self.bottom.visited == False:
self.neighbors.append(self.bottom)
if self.left != 0:
if self.left.visited == False:
self.neighbors.append(self.left)
if len(self.neighbors) > 0:
self.next_cell = self.neighbors[random.randrange(0,len(self.neighbors))]
return self.next_cell
else:
return False
def removeWalls(current_cell,next_cell):
x = int(current_cell.x / width) - int(next_cell.x / width)
y = int(current_cell.y / width) - int(next_cell.y / width)
if x == -1: # right of current
current_cell.walls[1] = False
next_cell.walls[3] = False
elif x == 1: # left of current
current_cell.walls[3] = False
next_cell.walls[1] = False
elif y == -1: # bottom of current
current_cell.walls[2] = False
next_cell.walls[0] = False
elif y == 1: # top of current
current_cell.walls[0] = False
next_cell.walls[2] = False
grid = []
for y in range(rows):
grid.append([])
for x in range(cols):
grid[y].append(Cell(x,y))
current_cell = grid[0][0]
next_cell = 0
# -------- Main Program Loop -----------
while done==False:
screen.fill(GREY)
current_cell.visited = True
current_cell.current = True
for y in range(rows):
for x in range(cols):
grid[y][x].draw()
next_cell = current_cell.checkNeighbors()
if next_cell != False:
current_cell.neighbors = []
stack.append(current_cell)
removeWalls(current_cell,next_cell)
current_cell.current = False
current_cell = next_cell
elif len(stack) > 0:
current_cell.current = False
current_cell = stack.pop()
elif len(stack) == 0:
grid = []
done=True
for y in range(rows):
grid.append([])
for x in range(cols):
grid[y].append(Cell(x,y))
current_cell = grid[0][0]
next_cell = 0
pygame.display.flip()
clock.tick(0)#fix of speed
class Mazerun(pygame.sprite.Sprite):
def __init__(self, width,height,pos_x,pos_y,color):
super().__init__()
self.image=pygame.Surface([width,height])
self.image.fill(color)
self.rect=self.image.get_rect()
self.rect.center=[pos_x,pos_y]
self.mask = pygame.mask.from_surface(self.image)
def update(self):
key = pygame.key.get_pressed()
dist = 1
global offset
offset=(self.rect.x,self.rect.y)
if key[pygame.K_DOWN]:
self.rect.y += dist
elif key[pygame.K_UP]:
self.rect.y -= dist
if key[pygame.K_RIGHT]:
self.rect.x += dist
elif key[pygame.K_LEFT]:
self.rect.x -= dist
mazerun=Mazerun(15,15,12.5,12.5,(0,0,255))
mazerun_group=pygame.sprite.Group()
mazerun_group.add(mazerun)
background=screen.copy()
walls_collide=pygame.mask.from_threshold(screen, BLACK)
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()
pygame.display.flip()
mazerun_group.draw(screen)
# draw everything
screen.blit(background,(0,0))
mazerun_group.update()
mazerun_group.draw(screen)
pygame.display.update()
player_mask=pygame.mask.from_threshold(screen, BLUE)
if walls_collide.overlap(player_mask, offset):
print("true")
clock.tick(180)
What can I do to make the sprite collide with the black lines, I have checked the pygame documentation and haven't found anything to fix the problem.