I am recreating PacMan game, right now my code just gets the key arrow pressed whether LRUD and moves in that direction, what I want is for the PacMan to move smoothly between the maze just like my Ghost is. Is there any way to make it move strictly left meaning if there is a wall on top and bottom, I don't want it to move slighty up or slightly down, just in that direction or turn around and go right. So it starts off at (225, 176) position on the screen, what I tried is to get the values for which % 25 == 0, then stop it from moving, but I'm not sure that's always the case. Is there a better way to make it move in one direction always?
class Maze():
def __init__(self):
self.Pellets = []
self.Walls = []
self.Energizer = []
self.Ghosts = []
self.BlockWidth = 25
self.BlockHeight = 25
self.MazeOffsetX = 0
self.MazeOffsetY = 50
# 0 - Pellets
# 1 - Walls
# 2 - Empty Spaces
# 3 - Energizers
# 4 - Ghosts
self.Matrix = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], \
[1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1], \
[1,3,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,3,1], \
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], \
[1,0,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,0,1], \
[1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1], \
[1,1,1,1,0,1,1,1,2,1,2,1,1,1,0,1,1,1,1], \
[2,2,2,1,0,1,2,2,2,4,2,2,2,1,0,1,2,2,2], \
[1,1,1,1,0,1,2,1,1,1,1,1,2,1,0,1,1,1,1], \
[2,2,2,2,0,2,2,1,4,4,4,1,2,2,0,2,2,2,2], \
[1,1,1,1,0,1,2,1,1,1,1,1,2,1,0,1,1,1,1], \
[2,2,2,1,0,1,2,2,2,2,2,2,2,1,0,1,2,2,2], \
[1,1,1,1,0,1,2,1,1,1,1,1,2,1,0,1,1,1,1], \
[1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1], \
[1,3,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,3,1], \
[1,0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,1], \
[1,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1], \
[1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1], \
[1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1], \
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], \
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
# BackgroundImage(X, Y, WIDTH, HEIGHT)
self.MazeX = self.BlockWidth * (len(self.Matrix[0])
+ self.MazeOffsetX)
self.MazeY = self.BlockHeight * (len(self.Matrix)
+ self.MazeOffsetY)
self.MazeWidth = self.BlockWidth * len(self.Matrix[0])
self.MazeHeight = self.BlockHeight * len(self.Matrix)
def DrawMaze(self, MazeSurface):
for Row in range(len(self.Matrix)):
for Column in range(len(self.Matrix[0])):
# Saves the position of each pellet
if self.Matrix[Row][Column] == 0:
self.Pellets.append([self.BlockWidth * Column,
self.BlockHeight * Row, 4, 4])
if self.Matrix[Row][Column - 1] != 1 and \
self.Matrix[Row][Column - 1] != 2:
self.Pellets.append([((self.BlockWidth * Column) - 13),
self.BlockHeight * Row , 4, 4])
if Column + 1 == None and Row - 1 == None:
if self.Matrix[Row][Column + 1] != 1 and \
self.Matrix[Row][Column + 1] != 2:
self.Pellets.append([((self.BlockWidth * Column) + 13),
self.BlockHeight * Row, 4, 4])
if self.Matrix[Row - 1][Column] != 1 and \
self.Matrix[Row - 1][Column] != 2:
self.Pellets.append([self.BlockWidth * Column,
((self.BlockHeight * Row) - 13),
4, 4])
if self.Matrix[Row + 1][Column] != 1 and \
self.Matrix[Row + 1][Column] != 2:
self.Pellets.append([self.BlockWidth * Column,
((self.BlockHeight * Row) + 13),
4, 4])
# Saves the position of each wall
if self.Matrix[Row][Column] == 1:
self.Walls.append(pygame.draw.rect(MazeSurface, WHITE,
[((self.BlockWidth) * Column),
((self.BlockHeight) * Row),
self.BlockWidth, self.BlockHeight]))
# Saves the position of each Energizer
if self.Matrix[Row][Column] == 3:
self.Energizer.append([(self.BlockWidth * Column),
(self.BlockHeight * Row), 14, 14])
# Saves the position of each Ghost
if self.Matrix[Row][Column] == 4:
self.Ghosts.append([(self.BlockWidth * Column),
(self.BlockHeight * Row), 23, 23])
class PacMan(Maze):
def __init__(self):
Maze.__init__(self)
self.PacManStartSurface = pygame.transform.scale(
pygame.image.load(
os.path.join("Pac Man", "PacManStart.png"))
.convert_alpha(), (23, 23))
self.PacManStartRect = pygame.Rect((225, 376, 23, 23))
self.PacManSurface = pygame.transform.scale(
pygame.image.load(
os.path.join("Pac Man", "PacManRight.png"))
.convert_alpha(), (23, 23))
self.PacManRect = pygame.Rect((225, 376, 23, 23))
self.CurrentSurface = self.PacManSurface
self.CurrentRect = self.PacManRect
self.MouthOpen = False
self.LastBiteTime = time.time()
self.PacManDirection = ""
self.TimeBetweenBites = 0.1
self.Lives = 3
def PacManMovement(self):
key = pygame.key.get_pressed()
if key[pygame.K_LEFT]:
self.PacManDirection = "LEFT"
elif key[pygame.K_RIGHT]:
self.PacManDirection = "RIGHT"
elif key[pygame.K_UP]:
self.PacManDirection = "UP"
elif key[pygame.K_DOWN]:
self.PacManDirection = "DOWN"
def ContinuePacManMovement(self):
if self.PacManDirection == "LEFT":
self.CurrentRect.move(-SPEED, 0)
self.PacManWallDetection(-1, 0)
if self.PacManDirection == "RIGHT":
self.CurrentRect.move(SPEED, 0)
self.PacManWallDetection(1, 0)
if self.PacManDirection == "UP":
self.CurrentRect.move(0, -SPEED)
self.PacManWallDetection(0, -1)
if self.PacManDirection == "DOWN":
self.CurrentRect.move(0, SPEED)
self.PacManWallDetection(0, 1)
def PacManTeleport(self):
if self.CurrentRect.x < 0:
self.CurrentRect.right = SCREEN_WIDTH + 20
if self.CurrentRect.x > SCREEN_WIDTH:
self.CurrentRect.x = 0
def PacManWallDetection(self, x, y):
self.CurrentRect.right += x
for Wall in self.Walls:
Collide = self.CurrentRect.colliderect(Wall)
if Collide:
if x < 0:
self.CurrentRect.left = Wall.right
if x > 0:
self.CurrentRect.right = Wall.left
break
self.CurrentRect.top += y
for Wall in self.Walls:
Collide = self.CurrentRect.colliderect(Wall)
if Collide:
if y < 0:
self.CurrentRect.top = Wall.bottom
if y > 0:
self.CurrentRect.bottom = Wall.top
break
def EatPellets(self):
for Row in range(len(self.Matrix)):
for Column in range(len(self.Matrix[0])):
for Pellet in self.Pellets:
if Pellet[0] < self.CurrentRect.x + Pellet[2] and \
Pellet[0] + self.CurrentRect.width > self.CurrentRect.x and \
Pellet[1] < self.CurrentRect.y + Pellet[3] and \
self.CurrentRect.height + Pellet[1] > self.CurrentRect.y:
Chomp = self.CurrentRect.colliderect(Pellet)
if Chomp:
Main.PlaySound(0)
self.Pellets.remove(Pellet)
self.Matrix[Row][Column] = 2
self.Score += 10
if self.Score > self.HighScore:
self.HighScore = self.Score
return str(self.Score), str(self.HighScore)
def EatEnergizer(self):
for Row in range(len(self.Matrix)):
for Column in range(len(self.Matrix[0])):
for PowerUp in self.Energizer:
Chomp = self.CurrentRect.colliderect(PowerUp)
if Chomp:
self.Energizer.remove(PowerUp)
#self.Matrix[Row][Column] = 3
self.Score += 50
Main.PlaySound(1)
if self.Score > self.HighScore:
self.HighScore = self.Score
return str(self.Score), str(self.HighScore)
def EatGhosts(self):
pass
def PacManAnimation(self):
if time.time() - self.LastBiteTime >= self.TimeBetweenBites:
self.LastBiteTime = time.time()
if self.MouthOpen:
self.CurrentSurface = self.PacManStartSurface
else:
self.CurrentSurface = self.PacManSurface
self.MouthOpen = not self.MouthOpen
if self.PacManDirection == "LEFT":
self.CurrentSurface = pygame.transform.rotate(
self.CurrentSurface, 180)
if self.PacManDirection == "RIGHT":
self.CurrentSurface = self.CurrentSurface
if self.PacManDirection == "UP":
self.CurrentSurface = pygame.transform.rotate(
self.CurrentSurface, 90)
if self.PacManDirection == "DOWN":
self.CurrentSurface = pygame.transform.rotate(
self.CurrentSurface, 270)
def DrawPacMan(self):
MazeSurface.blit(self.CurrentSurface, self.CurrentRect)
class Main():
def __init__(self):
# Inherits Maze class
Maze.__init__(self)
PacMan.__init__(self)
PinkGhost.__init__(self)
YellowGhost.__init__(self)
BlueGhost.__init__(self)
RedGhost.__init__(self)
self.Score = 0
self.HighScore = 0
def DrawLives(self):
PacManSurface = self.PacManSurface
PacManSurface = pygame.transform.rotate(PacManSurface, 180)
PacManLife1 = PacManSurface.get_rect(center =
((SCREEN_WIDTH - 370) // 2,
SCREEN_HEIGHT - 17))
PacManLife2 = PacManSurface.get_rect(center =
((SCREEN_WIDTH - 310) // 2,
SCREEN_HEIGHT - 17))
PacManLife3 = PacManSurface.get_rect(center =
((SCREEN_WIDTH - 250) // 2,
SCREEN_HEIGHT - 17))
SCREEN.blit(PacManSurface, PacManLife1)
SCREEN.blit(PacManSurface, PacManLife2)
SCREEN.blit(PacManSurface, PacManLife3)
def DrawPellets(self):
for Position in self.Pellets:
X = Position[0] + 13
Y = Position[1] + 13
Width = Position[2] // 2
Height = Position[3] // 2
pygame.draw.circle(MazeSurface, PEACH, (X, Y), Width, Height)
def DrawEnergizers(self):
for Position in self.Energizer:
X = Position[0] + 13
Y = Position[1] + 20
Width = Position[2] // 2
Height = Position[3] // 2
pygame.draw.circle(MazeSurface, PEACH, (X, Y), Width, Height)
def DrawBackground(self):
MazeSurface.blit(BackgroundSurface, BackgroundRect)
def PlaySound(self, Track):
if Track == 0:
Eat = pygame.mixer.Sound(
os.path.join("Sound Effects", "pacman_chomp.wav"))
Eat.play()
pygame.mixer.fadeout(400)
if Track == 1:
EatPellet = pygame.mixer.Sound(
os.path.join("Sound Effects", "pacman_eatghost.wav"))
EatPellet.play()
pygame.mixer.music.play(7)
pygame.mixer.fadeout(400)
def GameOver(self):
if self.Lives == 0:
print("Game Over")
def ShowScore(self):
global Font
OneUpText = Font.render("1UP", True, WHITE)
OneUpTextRect = OneUpText.get_rect(center = (70, 10))
# Displays current score
OneUpScoreText = Font.render(str(self.Score), True, WHITE)
OneUpScoreRect = OneUpScoreText.get_rect(center =
((SCREEN_WIDTH - 290)
// 2, 26))
HighScoreText = Font.render("High Score", True, WHITE)
HighScoreTextRect = HighScoreText.get_rect(center =
(SCREEN_WIDTH // 2, 10))
# Displays High Score
HighScoreNumber = Font.render(str(self.HighScore), True, WHITE)
HighScoreNumberRect = HighScoreNumber.get_rect(center =
((SCREEN_WIDTH + 90)
// 2, 26))
SCREEN.blit(OneUpText, OneUpTextRect)
SCREEN.blit(OneUpScoreText, OneUpScoreRect)
SCREEN.blit(HighScoreText, HighScoreTextRect)
SCREEN.blit(HighScoreNumber, HighScoreNumberRect)
def Update(self):
# Update PacMan
Main.PacManTeleport()
Main.ContinuePacManMovement()
Main.PacManAnimation()
# Update PinkGhost
Main.PinkGhostTeleport()
Main.ContinuePinkGhostMovement()
Main.PinkGhostAnimation()
Main.FrightenedMode()
Main.KillPacMan()
# Update Main
Main.DrawBackground()
Main.DrawPellets()
Main.DrawEnergizers()
Main.DrawPinkGhost()
Main.DrawPacMan()
Main.DrawLives()
Main.GameOver()
Main.EatPellets()
Main.EatEnergizer()
SCREEN.blit(MazeSurface, MazeRect)
Main.ShowScore()
Main = Main()
BackgroundSurface = pygame.transform.scale(BackgroundSurface,
(Main.MazeWidth,
Main.MazeHeight))
BackgroundRect = BackgroundSurface.get_rect()
MazeSurface = pygame.Surface((Main.MazeWidth, Main.MazeHeight))
MazeRect = MazeSurface.get_rect(topleft = (Main.MazeOffsetX,
Main.MazeOffsetY))
Main.DrawMaze(MazeSurface)
#Main.PinkGhostStartPosition()
'''
Before the game starts ...
pregame = True
while pregame:
if key button pressed:
pregame = False
run = True
'''
run = True
while run:
SCREEN.fill(BLACK)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
Main.PacManMovement()
Main.Update()
pygame.display.update()
CLOCK.tick(FPS)
pygame.quit()