有人知道为什么 pacman 不尊重墙壁吗?当我按下按键在墙壁之间移动 pacman 传送

Anyone know why pacman is not respecting the walls? When i press the keys to move pacman teleports between the walls

我正在尝试制作像 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 都会越过项目的蓝色墙壁,有人知道为什么以及如何修复它吗?

看起来他只是传送到另一边,而不是破坏角色坐标系

有 2 个问题:

  1. intention_columnintention_line依赖于当前的columeline而不是之前的intention_columnintention_line。即使有墙,intention_columnintention_line 也会递增。然而,columeline 仅在可以移动时才会递增:
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_centery_center 如果 columnline 已更改:
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 )