Pygame小车wall collison

2024-04-28 20:13:56 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我试着用pygame做一个简单的迷宫游戏。目前,我在墙碰撞方面遇到了问题:我使用的当前碰撞系统有缺陷,不能按预期工作:

import pygame
import random

# mazes
mazes = [
    [
            "wwwwwwwwwwwwwwwwwwwwwww",
            "w                     w",
            "w                     D",
            "w                     D",
            "w                     w",
            "wwwwwwwwwwwwwwwwwwwwwww"
    ]
    ,
    [
            "wwwwwwwwwwwwwwwwwwwwwww",
            "w w                   w",
            "w w wwwwwwwwwwwwwwwww w",
            "w w wD              w w",
            "w w wwwwwwwwwwwwwww w w",
            "w w                 w w",
            "w wwwwwwwwwwwwwwwwwww w",
            "w                     w",
            "wwwwwwwwwwwwwwwwwwwwwww"
    ]
]

pygame.init()

# Asset and text properties
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
blue = (0, 0, 255)

# Display properties
FPS = 30
display_width = 800
display_height = int(display_width * 2 / 3)
clock = pygame.time.Clock()
block_size = display_width / 40
level = 0

def message_to_screen(msg, color, fontSize, x_axis, y_axis):
    font = pygame.font.SysFont(None, fontSize)
    screen_text = font.render(msg, True, color)
    gameDisplay.blit(screen_text, [x_axis, y_axis])


# Create a game display
gameDisplay = pygame.display.set_mode([display_width, display_height])
pygame.display.set_caption("Mazer - Use arrow keys to move")

def gameloop(): # main function
    global level
    wall_maze, door_maze = buildMaze(mazes[1])
    gameExit = False
    gameOver = False
    movementSpeed_x = 0
    movementSpeed_y = 0
    player_x = display_width / 10
    player_y = display_height / 1.2
    speed = block_size / 2

    while not gameExit: #running game loop

        while gameOver:
            gameDisplay.fill(white)
            message_to_screen("Press Q to quit",
                              red, 40, display_width / 7, display_height / 3 )
            message_to_screen("Press N for next level", red, 40,
                              display_width / 7, display_height / 3 + 40)
            pygame.display.update()
            for event in pygame.event.get():
                if event == pygame.QUIT:
                    gameExit = True
                    gameOver = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        gameExit = True
                        gameOver = False
                    elif event.key == pygame.K_n:
                        level += 1
                        gameOver = False
                        gameloop()


        # Event handling
        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                gameExit = True

            if event.type == pygame.KEYDOWN:

        # Movement control
                if movementSpeed_y == 0:
                    if event.key == pygame.K_LEFT:
                        movementSpeed_x = -speed
                    if event.key == pygame.K_RIGHT:
                        movementSpeed_x = speed
                if movementSpeed_x == 0:
                    if event.key == pygame.K_DOWN:
                        movementSpeed_y = speed
                    if event.key == pygame.K_UP:
                        movementSpeed_y = -speed

            if event.type == pygame.KEYUP and event.type != pygame.KEYDOWN:
                if event.key == pygame.K_LEFT or event.key == pygame.K_DOWN or \
                        event.key == pygame.K_UP or event.key == pygame.K_RIGHT:
                    movementSpeed_x = 0
                    movementSpeed_y = 0

        if movementSpeed_x > 0:
            if pygame.sprite.spritecollideany(mazer, wall_maze):
                movementSpeed_x = 0
                player_x -= speed
        elif movementSpeed_x < 0:
            if pygame.sprite.spritecollideany(mazer, wall_maze):
                movementSpeed_x = 0
                player_x += speed

        if movementSpeed_y > 0:
            if pygame.sprite.spritecollideany(mazer, wall_maze):
                movementSpeed_y = 0
                player_y -= speed
        elif movementSpeed_y < 0:
            if pygame.sprite.spritecollideany(mazer, wall_maze):
                movementSpeed_y = 0
                player_y += speed

        player_x += movementSpeed_x
        player_y += movementSpeed_y
        # Movement control

        # Rendering
        gameDisplay.fill(white)
        mazer = player(block_size, player_x, player_y)
        movingSprites = pygame.sprite.Group()
        movingSprites.add(mazer)
        wall_maze.draw(gameDisplay)
        door_maze.draw(gameDisplay)
        movingSprites.draw(gameDisplay)
        pygame.display.update()

        clock.tick(FPS) # FPS tick

        if pygame.sprite.spritecollideany(mazer, door_maze):
            gameOver = True

    pygame.quit()
    quit()

class asset(pygame.sprite.Sprite):

    def __init__(self):

        pygame.sprite.Sprite.__init__(self)

class player(asset): # Class for player

    def __init__(self, size, x, y):

        # Image properties for player
        super().__init__()
        self.image = pygame.Surface([size, size])
        self.image.fill(red)
        self.rect = self.image.get_rect()

        # Player's position
        self.rect.x = x
        self.rect.y = y

class wall(asset): # Class for wall blocks

    def __init__(self, size, x , y):

        # Image properties for wall
        super().__init__()
        self.image = pygame.Surface([size, size])
        self.image.fill(black)
        self.rect = self.image.get_rect()

        # Wall's position
        self.rect.x = x
        self.rect.y = y

class door(asset):

    def __init__(self, size, x, y):

        super().__init__()
        self.image = pygame.Surface([size, size])
        self.image.fill(blue)
        self.rect = self.image.get_rect()

        self.rect.x = x
        self.rect.y = y

def buildMaze(Maze):

    wall_list = pygame.sprite.Group()
    door_list = pygame.sprite.Group()
    pos_x = display_width / 10 - block_size
    pos_y = display_height / 1.2 + block_size

    for row in Maze:
        for space in row:
            if space == "w":
                wall_maze = wall(block_size, pos_x, pos_y)
                wall_list.add(wall_maze)
            elif space == "D":
                door_maze = door(block_size, pos_x, pos_y)
                door_list.add(door_maze)
            pos_x += block_size
        pos_y -= block_size
        pos_x = display_width / 10 - block_size

    return wall_list, door_list

gameloop()

如果你试着运行代码并玩游戏,你会注意到当你朝墙移动时,玩家通常会呆在墙内,控制权是颠倒的(按左键时向右移动)。我怀疑这与我如何构造碰撞探测器有关:

    if movementSpeed_x > 0:
        if pygame.sprite.spritecollideany(mazer, wall_maze):
            movementSpeed_x = 0
            player_x -= speed
    elif movementSpeed_x < 0:
        if pygame.sprite.spritecollideany(mazer, wall_maze):
            movementSpeed_x = 0
            player_x += speed

    if movementSpeed_y > 0:
        if pygame.sprite.spritecollideany(mazer, wall_maze):
            movementSpeed_y = 0
            player_y -= speed
    elif movementSpeed_y < 0:
        if pygame.sprite.spritecollideany(mazer, wall_maze):
            movementSpeed_y = 0
            player_y += speed

还有一件事,我想如果以前有这个代码pygame.display.update更新(),它不会显示球员撞墙,因为位置应该在那之前更新,但不知何故它没有按预期工作。谢谢你看我的代码。你知道吗


Tags: rectselfeventsizeifdisplayblockpygame