I'm trying to write something of a pacman clone in python using pygame, though I'm still learning both.
I have trouble with collision detection of ghosts. Currently there is only one ghost - it sees the map as matrix of numbers where 0 means wall. It's supposed to choose direction randomly every time collision occurs (it's starting direction is UP) but for now it just goes up ignoring all the walls.
This is the main game loop:
while True:
for event in pygame.event.get():
if event.type == QUIT:
exit()
pacman.change_direction(tiles)
ghost.move(layout)
for tile in tiles:
pacman.collision(tile)
screen.blit(background, (0,0))
for tile in tiles:
tile.draw(screen)
ghost.draw(screen)
pacman.draw(screen)
pygame.display.update()
this is the ghost class (please ignore the comment which is in Polish):
class Ghost():
def __init__(self, dimensions, coordinates=[0,0]): #mamy Blinky, Pinky, Inky, Clyde
self.dimensions = dimensions
self.coordinates = [13*16, 15*16]
self.colour = (255,0,0)
self.direction = 'UP'
def draw(self, screen):
pygame.draw.rect(screen, self.colour, (self.coordinates, self.dimensions))
def choose_driection(self):
a = random.randrange(1, 5)
if (a==1):
return 'UP'
elif (a==2):
return 'DOWN'
elif (a==3):
return 'RIGHT'
elif (a==4):
return 'LEFT'
def collision(self, x, y, layout):
if (layout[(x/16)-1][(y/16)-1]!=0):
if (self.direction is 'LEFT'):
self.coordinates[0] -= 1
elif (self.direction is 'RIGHT'):
self.coordinates[0] += 1
elif (self.direction is 'UP'):
self.coordinates[1] -= 1
elif (self.direction is 'DOWN'):
self.coordinates[1] += 1
else:
xcollide = collide(self.coordinates[0], self.dimensions[0], x, 16)
ycollide = collide(self.coordinates[1], self.dimensions[1], y, 16)
if not (xcollide and ycollide):
if (self.direction is 'LEFT'):
self.coordinates[0] -= 1
elif (self.direction is 'RIGHT'):
self.coordinates[0] += 1
elif (self.direction is 'UP'):
self.coordinates[1] -= 1
elif (self.direction is 'DOWN'):
self.coordinates[1] += 1
while xcollide and ycollide:
if (self.direction is 'LEFT'):
self.coordinates[0] += 1
elif (self.direction is 'RIGHT'):
self.coordinates[0] -= 1
elif (self.direction is 'UP'):
self.coordinates[1] += 1
elif (self.direction is 'DOWN'):
self.coordinates[1] -= 1
self.direction = self.choose_direction()
if (self.direction is 'LEFT'):
self.coordinates[0] -= 1
xcollide = collide(self.coordinates[0], self.dimensions[0], math.floor(self.coordinates[0]/16)*16-16, 16)
elif (self.direction is 'RIGHT'):
self.coordinates[0] += 1
xcollide = collide(self.coordinates[0], self.dimensions[0], math.floor(self.coordinates[0]/16)*16+16, 16)
elif (self.direction is 'UP'):
self.coordinates[1] -= 1
ycollide = collide(self.coordinates[1], self.dimensions[1], math.floor(self.coordinates[1]/16)*16-16, 16)
elif (self.direction is 'DOWN'):
self.coordinates[1] += 1
ycollide = collide(self.coordinates[1], self.dimensions[1], math.floor(self.coordinates[1]/16)*16+16, 16)
def move(self, layout):
if (self.direction is 'LEFT'):
self.collision(math.floor(self.coordinates[0]/16)*16-16, math.floor(self.coordinates[1]/16)*16, layout) #podloga, bo wspolrzedne ghost moga nie byc co 16 kiedy sie porusza, a plytek sa
elif (self.direction is 'RIGHT'):
self.collision(math.floor(self.coordinates[0]/16)*16+16, math.floor(self.coordinates[1]/16)*16, layout)
elif (self.direction is 'UP'):
self.collision(math.floor(self.coordinates[0]/16)*16, math.floor(self.coordinates[1]/16)*16-16, layout)
elif (self.direction is 'DOWN'):
self.collision(math.floor(self.coordinates[0]/16)*16, math.floor(self.coordinates[1]/16)*16+16, layout)
and this is the collide function it uses:
def collide(p1, length1, p2, length2): #coordinate, length, coordinate, length
collided = False
if p1 < p2:
if p2+length2-p1 < length1+length2:
collided = True
elif p1 > p2:
if p1+length1-p2 < length1+length2:
collided = True
elif p1 == p2:
collided = True
return collided
Now, I know it's not the best method to do this, I considered making the whole map a graph, but I still need it in this form for petals which are not implemented yet. There are some other issues with the code, probably, but for now I would just want to know why collision detection doesn't work...