2022-05-22

Recreating PacMan using Pygame [closed]

Here's my code:

import pygame

pygame.init()
pygame.display.set_caption("Pac-Man")

# Sets the size of the screen via (WIDTH, HEIGHT)
SCREEN_WIDTH = 475
SCREEN_HEIGHT = 608
# Speed of Characters
SPEED = 1
# Frames per second, how fast the game runs
FPS = 50
# Colors (RED,GREEN,BLUE)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (0, 0, 255)

HIGH_SCORE = 0

# Sets the WIDTH and HEIGHT of the window
WINDOW = (SCREEN_WIDTH, SCREEN_HEIGHT)
# Displays the screen
SCREEN = pygame.display.set_mode(WINDOW)
CLOCK = pygame.time.Clock()

PacManStartSurface = pygame.transform.scale(pygame.image.load 
                                           ("PacManStart.png").convert(), 
                                           (25, 25))
PacManStartRect = PacManStartSurface.get_rect(topleft = 
                                             (((SCREEN_WIDTH - 22) // 2),
                                             (SCREEN_HEIGHT + 225) // 2))

PacManSurface = pygame.transform.scale(pygame.image.load 
                                      ("PacManRight.png").convert(), (25, 25))
PacManRect = PacManStartSurface.get_rect(topleft = 
                                        (((SCREEN_WIDTH - 22) // 2),
                                        (SCREEN_HEIGHT + 225) // 2))

CurrentSurface = PacManStartSurface
CurrentRect = PacManStartRect

BackgroundSurface = pygame.transform.scale(pygame.image.load
                                          ("Background.png").convert(), 
                                          (SCREEN_WIDTH - 2, 
                                           SCREEN_HEIGHT - 82))
BackgroundRect = BackgroundSurface.get_rect(topleft = (0, 41))

class PacMan():
    def __init__(self):
        self.LIVES = 3
        
class PowerUp(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(pygame.image.load("PowerUp.png")
                                            .convert(), (23, 23))
        self.mask = pygame.mask.from_surface(self.image)
        
class YellowGhost(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(pygame.image.load("YellowGhost.png")
                                           .convert(), (23, 23))
        self.rect = self.image.get_rect(topleft = (235, 347))
        self.mask = pygame.mask.from_surface(self.image)
        
class RedGhost(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(pygame.image.load("RedGhost.png")
                                           .convert(), (23, 23))
        self.rect = self.image.get_rect(topleft = (235, 347))
        self.mask = pygame.mask.from_surface(self.image)
        
class BlueGhost(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(pygame.image.load("BlueGhost.png")
                                           .convert(), (23, 23))
        self.rect = self.image.get_rect(topleft = (235, 347))
        self.mask = pygame.mask.from_surface(self.image)
        
class PinkGhost(pygame.sprite.Sprite):
    def __init__(self):        
        self.image = pygame.transform.scale(pygame.image.load("PinkGhost.png")
                                           .convert(), (23, 23))
        self.rect = self.image.get_rect(topleft = (235, 347))
        self.mask = pygame.mask.from_surface(self.image)
        
class Maze():
    def __init__(self):
        self.DOTS = []
        self.WALLS = []
        self.BLOCK_WIDTH = 22
        self.BLOCK_HEIGHT = 22
        self.ROWS = 21
        self.COLUMNS = 20
        self.MARGIN = 3
        # 0 - Dots
        # 1 - Walls
        # 2 - Power Up
        # 3 - Empty Space
        # 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,2,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,2,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,3,1,3,1,1,1,0,1,1,1,1], \
                      [3,3,3,1,0,1,3,3,3,3,3,3,3,1,0,1,3,3,3], \
                      [1,1,1,1,0,1,3,1,1,1,1,1,3,1,0,1,1,1,1], \
                      [0,0,0,0,0,3,3,1,4,4,4,1,3,3,0,0,0,0,0], \
                      [1,1,1,1,0,1,3,1,1,1,1,1,3,1,0,1,1,1,1], \
                      [3,3,3,1,0,1,3,3,3,3,3,3,3,1,0,1,3,3,3], \
                      [1,1,1,1,0,1,3,1,1,1,1,1,3,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,2,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,2,1], \
                      [1,0,0,1,0,0,0,0,0,3,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]
        
    def DrawGrid(self):
        for ROW in range(self.ROWS):
            for COLUMN in range(self.COLUMNS - 1):
                if self.MATRIX[ROW][COLUMN] == 0:
                    self.DOTS.append(pygame.draw.circle(SCREEN, YELLOW, 
                                    [((self.MARGIN + self.BLOCK_WIDTH)
                                    * COLUMN + self.MARGIN) + 10,
                                    ((self.MARGIN + self.BLOCK_HEIGHT) 
                                    * ROW + self.MARGIN) + 50], 2))
                if self.MATRIX[ROW][COLUMN] == 1:
                    self.WALLS.append(pygame.draw.rect(SCREEN, WHITE,
                                     [((self.MARGIN + self.BLOCK_WIDTH)
                                     * COLUMN + self.MARGIN) - 2,
                                     ((self.MARGIN + self.BLOCK_HEIGHT) 
                                     * ROW + self.MARGIN) + 40, 
                                     self.BLOCK_WIDTH, self.BLOCK_HEIGHT]))

class Main(Maze):
    def __init__(self):
        # Inherits Maze class
        Maze.__init__(self)
        self.DIRECTION = ""
        self.SCORE = 0
        
    def Movement(self):
        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT] and not key[pygame.K_UP] \
                              and not key[pygame.K_DOWN]:
            CurrentRect.x -= SPEED
            self.DIRECTION = "LEFT"
        if key[pygame.K_RIGHT] and not key[pygame.K_UP] \
                               and not key[pygame.K_DOWN]:
            CurrentRect.x += SPEED
            self.DIRECTION = "RIGHT"
        if key[pygame.K_UP] and not key[pygame.K_LEFT] \
                            and not key[pygame.K_RIGHT]:
            CurrentRect.y -= SPEED
            self.DIRECTION = "UP"
        if key[pygame.K_DOWN] and not key[pygame.K_LEFT] \
                              and not key[pygame.K_RIGHT]:
            CurrentRect.y += SPEED
            self.DIRECTION = "DOWN"
            
    def ContinueMovement(self):
        if self.DIRECTION == "LEFT":
            CurrentRect.x -= SPEED
            Main.WallDetection(self, -1, 0, CurrentRect)
        if self.DIRECTION == "RIGHT":
            CurrentRect.x += SPEED
            Main.WallDetection(self, 1, 0, CurrentRect)
        if self.DIRECTION == "UP":
            CurrentRect.y -= SPEED
            Main.WallDetection(self, 0, -1, CurrentRect)
        if self.DIRECTION == "DOWN":
            CurrentRect.y += SPEED
            Main.WallDetection(self, 0, 1, CurrentRect)

    def ChangeImage(self):
        global CurrentSurface
        if self.DIRECTION == "LEFT":
            CurrentSurface = pygame.transform.rotate(PacManSurface, 180)
        if self.DIRECTION == "RIGHT":
            CurrentSurface = PacManSurface
        if self.DIRECTION == "UP":
            CurrentSurface = pygame.transform.rotate(PacManSurface, 90)
        if self.DIRECTION == "DOWN":
            CurrentSurface = pygame.transform.rotate(PacManSurface, 270)
        
    def Teleport(self):
        if CurrentRect.right < 0:
            CurrentRect.right = SCREEN_WIDTH + 20
        if CurrentRect.left > SCREEN_WIDTH:
            CurrentRect.right = 0
    
    def WallDetection(self, x, y, CurrentRect):
        CurrentRect.right += x
        for wall in self.WALLS:
            collide = CurrentRect.colliderect(wall)
            if collide:
                if x < 0: 
                    CurrentRect.left = wall.right
                elif x > 0:
                    CurrentRect.right = wall.left
                break
        
        CurrentRect.top += y
        for wall in self.WALLS:
            collide = CurrentRect.colliderect(wall)
            if collide:
                if y < 0:
                    CurrentRect.top = wall.bottom
                if y > 0:
                    CurrentRect.bottom = wall.top
                break
            
    def EatDots(self, font):
        for ROW in range(self.ROWS):
            for COLUMN in range(self.COLUMNS - 1):
                for DOT in self.DOTS:
                    chomp = CurrentRect.colliderect(DOT)
                    if chomp:
                        self.MATRIX[ROW][COLUMN] = 3
                        self.SCORE += str(10)
                    return font.render(self.SCORE, True, WHITE)
                        
    def EatGhosts(self):
        pass
    
    def EatPowerUp(self):
        pass
                
    def ShowText(self):
        font = pygame.font.Font("emulogic.ttf", 15)
        OneUpText = font.render("1UP", True, WHITE)
        OneUpTextRect = OneUpText.get_rect(center = (70, 10))
        OneUpScoreText = font.render("00", True, WHITE)
        Main.EatDots(self, font)
        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))
        HighScoreNumber = font.render("00", True, WHITE)
        HighScoreNumberRect = HighScoreNumber.get_rect(center = 
                                                      ((SCREEN_WIDTH + 90) 
                                                       // 2, 26))

        SCREEN.blit(HighScoreText, HighScoreTextRect)
        SCREEN.blit(HighScoreNumber, HighScoreNumberRect)
        SCREEN.blit(OneUpText, OneUpTextRect)
        SCREEN.blit(OneUpScoreText, OneUpScoreRect)
        
    def PacManBite(self):
        SCREEN.blit(PacManStartSurface, PacManStartRect)
        pygame.display.update()

Player = Main()
Player.DrawGrid()
    
'''
pregame = True
while pregame:
    if key button pressed:
        pregame = False
    run = True
'''

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            Player.Movement()
            Player.ChangeImage()
            Player.Teleport()   
            
    Player.ContinueMovement()
    Player.EatDots(0)

    Player.PacManBite()
    #SCREEN.blit(BackgroundSurface, BackgroundRect)
    SCREEN.blit(CurrentSurface, CurrentRect)  
    Player.ShowText()
    pygame.display.update()
    CLOCK.tick(FPS)
            
pygame.quit()

So I'm trying to recreate a PacMan game using pygame. So far my code works smoothly, but I wanted to know if I can format a background image based on the grid I draw like scale it to match the maze made of rectangles. I also have an issue where the character speeds up when I hold down the arrow key, is there any way to make him move in constant speed even when I hold down the arrow key? Thanks



No comments:

Post a Comment