This is a code for Pac-Man. I already have a moving Pac-man and the collision w/ the ghosts, but I don't know how to make them randomly move on the map. I don't need them to chase the Pac-Man, just to slide randomly through the map and change direction when they hit on the wall. I also wanted to know how could I make Pac-Man die when he collides w/ a ghost.
import pygame
pygame.init()
tela = pygame.display.set_mode((1000, 560))
jogo = True
class Tabuleiro:
def __init__(self, tela, x, y):
self.x = x
self.y = y
self.tela = tela
self.maze = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 0, 1, 3, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1],
[1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
def show(self):
for col in range(20):
for lin in range(11):
if self.maze[lin][col] == 1:
self.tela.fill((255, 255, 255), rect=[self.x + col * 50, self.y + lin * 50, 50, 50])
if self.maze[lin][col] == 2:
self.tela.fill((255, 255, 0), rect=[self.x + col * 50 + 12, self.y + lin * 50 + 12, 25, 25])
if self.maze[lin][col] == 3:
self.tela.fill((255, 0, 0), rect=[self.x + col * 50 + 12, self.y + lin * 50 + 12, 25, 25])
def findFirst(self, number):
for row, rowlist in enumerate(self.maze):
for col, cell in enumerate(rowlist):
if cell == number:
return row, col
return None, None
def testIndex(self, row, col):
if row == None or col == None:
return False
if 0 <= row < len(self.maze) and 0 <= col < len(self.maze[row]):
return True
return False
def isFieldEqual(self, row, col, number):
if self.testIndex(row, col):
return self.maze[row][col] == number
return False
def swapFileds(self, row1, col1, row2, col2):
if self.testIndex(row1, col1) and self.testIndex(row2, col2):
self.maze[row1][col1], self.maze[row2][col2] = self.maze[row2][col2], self.maze[row1][col1]
maze = Tabuleiro(tela, 10, 10)
while jogo:
row, col = maze.findFirst(2)
for event in pygame.event.get():
if event.type == pygame.QUIT:
jogo = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
if maze.isFieldEqual(row, col - 1, 0):
maze.swapFileds(row, col - 1, row, col)
if event.key == pygame.K_RIGHT:
if maze.isFieldEqual(row, col + 1, 0):
maze.swapFileds(row, col + 1, row, col)
if event.key == pygame.K_UP:
if maze.isFieldEqual(row - 1, col, 0):
maze.swapFileds(row, col, row - 1, col)
if event.key == pygame.K_DOWN:
if maze.isFieldEqual(row + 1, col, 0):
maze.swapFileds(row + 1, col, row, col)
tela.fill(0)
maze.show()
pygame.display.update()
It's for a school project, so it doesn't have to be so complex. Thank you!
Add a method that can find all field with a specific number
in the grid:
class Tabuleiro:
# [...]
def findAll(self, number):
result = []
for row, rowlist in enumerate(self.maze):
for col, cell in enumerate(rowlist):
if cell == number:
result.append((row, col))
return result
Find all the neighboring positions that can be move to. Use random.choice()
to select a random position:
while jogo:
# [...]
for row, col in maze.findAll(3):
new_pos = [(row-1, col), (row+1, col), (row, col-1), (row, col+1)]
new_pos = [(r, c) for r, c in new_pos if maze.isFieldEqual(r, c, 0)]
if new_pos:
new_row, new_col = random.choice(new_pos)
maze.swapFileds(row, col, new_row, new_col)
Use pygame.time.get_ticks()
to return the number of milliseconds since pygame.init()
was called. Set the time for the first move of the enemy. When the time exceeds move the enemy and set the time for the next move:
next_move_time = 0
jogo = True
while jogo:
current_time = pygame.time.get_ticks()
# [...]
if next_move_time < current_time:
next_move_time = current_time + 500 # 500 milliseconds = 0.5 seconds
for row, col in maze.findAll(3):
# [...]
Complete example:
import pygame
import random
pygame.init()
tela = pygame.display.set_mode((1000, 560))
class Tabuleiro:
def __init__(self, tela, x, y):
self.x = x
self.y = y
self.tela = tela
self.maze = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 0, 1, 3, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1],
[1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
def show(self):
for col in range(20):
for lin in range(11):
if self.maze[lin][col] == 1:
self.tela.fill((255, 255, 255), rect=[self.x + col * 50, self.y + lin * 50, 50, 50])
if self.maze[lin][col] == 2:
self.tela.fill((255, 255, 0), rect=[self.x + col * 50 + 12, self.y + lin * 50 + 12, 25, 25])
if self.maze[lin][col] == 3:
self.tela.fill((255, 0, 0), rect=[self.x + col * 50 + 12, self.y + lin * 50 + 12, 25, 25])
def findFirst(self, number):
for row, rowlist in enumerate(self.maze):
for col, cell in enumerate(rowlist):
if cell == number:
return row, col
return None, None
def findAll(self, number):
result = []
for row, rowlist in enumerate(self.maze):
for col, cell in enumerate(rowlist):
if cell == number:
result.append((row, col))
return result
def testIndex(self, row, col):
if row == None or col == None:
return False
if 0 <= row < len(self.maze) and 0 <= col < len(self.maze[row]):
return True
return False
def isFieldEqual(self, row, col, number):
if self.testIndex(row, col):
return self.maze[row][col] == number
return False
def swapFileds(self, row1, col1, row2, col2):
if self.testIndex(row1, col1) and self.testIndex(row2, col2):
self.maze[row1][col1], self.maze[row2][col2] = self.maze[row2][col2], self.maze[row1][col1]
maze = Tabuleiro(tela, 10, 10)
next_move_time = 0
jogo = True
while jogo:
current_time = pygame.time.get_ticks()
row, col = maze.findFirst(2)
for event in pygame.event.get():
if event.type == pygame.QUIT:
jogo = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
if maze.isFieldEqual(row, col-1, 0):
maze.swapFileds(row, col-1, row, col)
if event.key == pygame.K_RIGHT:
if maze.isFieldEqual(row, col+1, 0):
maze.swapFileds(row, col+1, row, col)
if event.key == pygame.K_UP:
if maze.isFieldEqual(row-1, col, 0):
maze.swapFileds(row, col, row-1, col)
if event.key == pygame.K_DOWN:
if maze.isFieldEqual(row+1, col, 0):
maze.swapFileds(row+1, col, row, col)
if next_move_time < current_time:
next_move_time = current_time + 500 # 500 milliseconds = 0.5 seconds
for row, col in maze.findAll(3):
new_pos = [(row-1, col), (row+1, col), (row, col-1), (row, col+1)]
new_pos = [(r, c) for r, c in new_pos if maze.isFieldEqual(r, c, 0)]
if new_pos:
new_row, new_col = random.choice(new_pos)
maze.swapFileds(row, col, new_row, new_col)
tela.fill(0)
maze.show()
pygame.display.update()