Кто-нибудь знает, почему пакман не уважает стены? Когда я нажимаю клавиши для перемещения, пакман телепортируется между стенами

#python #pygame #pacman

Вопрос:

я пытаюсь создать игру pacman, подобную pygame, теперь я просто хочу, чтобы он прошел по лабиринту, не выходя за стены лабиринта. Однако я столкнулся с некоторыми проблемами, когда я нажимаю клавиши для перемещения пакмана, он в конечном итоге звонит между стенами, хотя и не выходит за их пределы, это приводит к ошибкам в системе координат и начинает выдавать серию ошибок во время игровых команд . Кто-нибудь знает, почему это происходит и как это решить?

 import pygame
pygame.init()
window = pygame.display.set_mode((800, 600), 0)
# Color used in the game
YELLOW = (255,255,0)
BLACK = (0,0,0)
BLUE = (13,56,143)
speed = 1
class Scenery:
    def __init__(self, size, character):
        self.character = character
        self.size = size 
        self.matrix = [
            [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
            [2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2],
            [2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2],
            [2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2],
            [2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 0, 0, 0, 0, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2],
            [2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2],
            [2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2],
            [2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
            [2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
            [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
        ]
    def paint_line(self, surface, line_index, line):
        for column_index, column in enumerate(line):
            x_box = column_index * self.size
            y_box = line_index * self.size
            half_size = self.size // 2
            color = BLACK
            if column == 2:
                color = BLUE
            pygame.draw.rect(surface, color, (x_box, y_box, self.size, self.size), 0)
            if column == 1:
                pygame.draw.circle(surface, YELLOW, (x_box   half_size, y_box   half_size), self.size//10, 0)
    def paint_scenery(self, surface):
        for line_index, line in enumerate(self.matrix):
            self.paint_line(surface, line_index, line)
    def calculate_rules(self):
        column_character = self.character.intention_column
        line_character = self.character.intention_line    
        if 0 <= column_character < 28 and 0 <= line_character < 29: 
            if self.matrix[line_character][column_character] != 2:
                self.character.aprove_movement() 
class Pacman:
    def __init__(self, size):
        self.column = 1
        self.line = 1
        self.x_center = 400
        self.y_center = 300
        self.size = size # 2x radius and size/number of the cells
        self.speed_x = 0
        self.speed_y = 0
        self.radius = self.size // 2
        self.intention_column = self.column
        self.intention_line = self.line

    def calculate_rules(self):
        # calculate the movimentantion
        self.intention_column =  self.intention_column   self.speed_x
        self.intention_line = self.intention_line   self.speed_y
        self.x_center = int( self.column * self.size   self.radius ) 
        self.y_center = int( self.line * self.size   self.radius )

    def draw_pacman(self, surface):
        # Draw pacman's character
        pacman_body = pygame.draw.circle(surface, YELLOW, (self.x_center, self.y_center), self.radius, 0)
        
        
        # Coordinates
        x_eye_position = ( self.x_center   int( self.radius/4 ) )
        y_eye_position = ( self.y_center - int( (self.radius/2) ) )
        point_a = (self.x_center, self.y_center) # Center
        point_b = ((self.x_center   self.radius), self.y_center) # Right Center
        point_c = ((self.x_center   self.radius), (self.y_center - self.radius)) # Superior Right Center
        points = [point_a, point_b, point_c]
        # Pacman 
        pacman_eye = pygame.draw.circle(surface, BLACK, (x_eye_position, y_eye_position), int(self.radius/10), 0)
        pacman_mouth = pygame.draw.polygon(surface, BLACK, points, 0)
        # Make the draws
        pacman_body 
        pacman_eye
        pacman_mouth
    
    def calculate_events(self, events):
        for e in events:
            if e.type == pygame.QUIT: # check if the user have clicked on the X box to quit
                exit()
            elif e.type == pygame.KEYDOWN:
                if e.key == pygame.K_RIGHT or e.key == pygame.K_d:
                    self.speed_x = speed
                elif e.key == pygame.K_LEFT or e.key == pygame.K_a:
                    self.speed_x = -speed
                elif e.key == pygame.K_UP or e.key == pygame.K_w:
                    self.speed_y = -speed
                elif e.key == pygame.K_DOWN or e.key == pygame.K_s:
                    self.speed_y = speed
            elif e.type == pygame.KEYUP:
                if e.key == pygame.K_RIGHT or e.key == pygame.K_d:
                    self.speed_x = 0
                elif e.key == pygame.K_LEFT or e.key == pygame.K_a:
                    self.speed_x = 0
                elif e.key == pygame.K_UP or e.key == pygame.K_w:
                    self.speed_y = 0
                elif e.key == pygame.K_DOWN or e.key == pygame.K_s:
                    self.speed_y = 0

    def aprove_movement(self):
        self.column = self.intention_column
        self.line = self.intention_line
       
    
if __name__ == '__main__':
    size = 600 // 30
    pacman = Pacman(size)
    scenary = Scenery(size, pacman)  
    

    while True:

        # Game Rules
        pacman.calculate_rules()
        scenary.calculate_rules()

        
        # Figures
        window.fill(BLACK)
        scenary.paint_scenery(window)
        pacman.draw_pacman(window)
        pygame.display.update()
        pygame.time.delay(100)

        
        events = pygame.event.get()
        pacman.calculate_events(events)
        
 
 

ИТАК, каждый раз, когда я держу клавиши для перемещения в течение нескольких секунд, pacman проходит по синим стенам проекта, кто-нибудь знает, почему и как это исправить?

Похоже, он просто телепортируется на другие стороны и затем изменяет систему координат ролей

Ответ №1:

Есть 2 проблемы:

  1. intention_column И intention_line зависит от текущего colume и line вместо предыдущего intention_column и intention_line . intention_column и intention_line увеличиваются, даже если есть стена. colume и line , однако, увеличиваются только в том случае, если движение возможно:
 class Pacman:
    # [...]

    def calculate_rules(self):
        # calculate the movimentantion
        self.intention_column =  self.column   self.speed_x
        self.intention_line = self.line   self.speed_y
 
  1. Только обновляйте x_center и y_center если column или line изменены:
 class Pacman:
    # [...]

    def aprove_movement(self):
        self.column = self.intention_column
        self.line = self.intention_line
        self.x_center = int( self.column * self.size   self.radius ) 
        self.y_center = int( self.line * self.size   self.radius )
 

Комментарии:

1. Спасибо! Я потерял свой wenesday днем, пытаясь найти эти проблемы.

2. @GustavoFigueiredo Спасибо тебе. Пожалуйста.