簡體   English   中英

當玩家與牆壁發生碰撞時,拒絕 pygame 中的移動

[英]Deny movement in pygame when player would collide with a wall

我在 pygame 中遇到了碰撞問題。 具體來說,我有一個玩家和一個牆列表,如果它們發生碰撞,我應該阻止該方向的任何移動。

我已經嘗試了很多指南,但我似乎無法讓這個自己工作。

import pygame
pygame.init()

win = pygame.display.set_mode((800,600))
pygame.display.set_caption("Game")

playerX = 380 #Player X coordinate
playerY = 380 #Player Y coordinate
playerXVel = 10 #Horizontal Velocity
playerYVel = 10 #Vertical Velocity
overworld = (248, 192, 117)

run = True

while run: #The game starts running
    win.fill(overworld)
    pygame.time.delay(30)

    for event in pygame.event.get(): #You can stop the game now too
        if event.type == pygame.QUIT:
            run = False

    class Player: #This is you
        def __init__(self):
            self.rect = pygame.Rect(playerX,playerY,50,50)
    player = Player()

    class Wall: #The walls
        def __init__(self, pos):
            walls.append(self)
            self.rect = pygame.Rect(pos[0], pos[1], 50, 50)
    walls = []
    
    keys = pygame.key.get_pressed()  #To retain the feel of retro video games, I have made it impossible to walk diagonally
    if keys[pygame.K_w] and not keys[pygame.K_a] and not keys[pygame.K_d]:
        playerY -= playerYVel
    if keys[pygame.K_a] and not keys[pygame.K_w] and not keys[pygame.K_s]:
        playerX -= playerXVel
    if keys[pygame.K_s] and not keys[pygame.K_a] and not keys[pygame.K_d]:
        playerY += playerYVel
    if keys[pygame.K_d] and not keys[pygame.K_s] and not keys[pygame.K_w]:
        playerX += playerXVel

    #I copied this section of code
    #Credit: https://www.pygame.org/project-Rect+Collision+Response-1061-.html
    level = [
        "WWWWWWWWWWWWWWWW",
        "W              W",
        "W              W",
        "W              W",
        "W              W",
        "W              W",
        "W              W",
        "W              W",
        "W              W",
        "W              W",
        "W              W",
        "WWWWWWWWWWWWWWWW",
    ]
    x = y = 0
    for row in level:
        for col in row:
            if col == "W":
                Wall((x, y)) 
            x += 50
        y += 50
        x = 0

    #Drawing every rectangle in :3
    pygame.draw.rect(win, (0, 255, 0), player.rect)
    for wall in walls:
        pygame.draw.rect(win, (143, 41, 3), wall.rect)

    pygame.display.update()
pygame.quit()

到目前為止,一切都很好。 我有牆,我有一個玩家,那個玩家可以移動。 但是,玩家可以穿過牆壁。

我想在其中添加一段代碼,以防止在玩家與牆壁碰撞時添加或刪除速度。 這是我嘗試向上行走的方法,但它只是讓我無法完全向上行走

        for allwalls in walls:
            if not player.rect.colliderect(allwalls):
                playerY -= playerYVel

誰能告訴我我做錯了什么/我應該輸入什么代碼來阻止玩家穿過牆壁?

在應用程序循環之前創建一次對象。 您根本不需要變量playerXplayerY 請改用player.rect.xplayer.rect.y

移動播放器前請存放播放器的 position。 如果檢測到碰撞,恢復播放器 position:

oldPlyerX, oldPlyerY = player.rect.topleft          # store player position

keys = pygame.key.get_pressed()
if keys[pygame.K_w] and not keys[pygame.K_a] and not keys[pygame.K_d]:
    player.rect.y -= playerYVel
if keys[pygame.K_a] and not keys[pygame.K_w] and not keys[pygame.K_s]:
    player.rect.x -= playerXVel
if keys[pygame.K_s] and not keys[pygame.K_a] and not keys[pygame.K_d]:
    player.rect.y += playerYVel
if keys[pygame.K_d] and not keys[pygame.K_s] and not keys[pygame.K_w]:
    player.rect.x += playerXVel

for allwalls in walls:
    if player.rect.colliderect(allwalls):
        player.rect.topleft = oldPlyerX, oldPlyerY # restore player position

完整示例:

import pygame
pygame.init()

win = pygame.display.set_mode((800,600))
pygame.display.set_caption("Game")

playerXVel = 10 #Horizontal Velocity
playerYVel = 10 #Vertical Velocity
overworld = (248, 192, 117)

class Player: #This is you
    def __init__(self):
        self.rect = pygame.Rect(380,380,50,50)
player = Player()

class Wall: #The walls
    def __init__(self, pos):
        walls.append(self)
        self.rect = pygame.Rect(pos[0], pos[1], 50, 50)
walls = []

#I copied this section of code
#Credit: https://www.pygame.org/project-Rect+Collision+Response-1061-.html
level = [
    "WWWWWWWWWWWWWWWW",
    "W              W",
    "W              W",
    "W              W",
    "W              W",
    "W              W",
    "W              W",
    "W              W",
    "W              W",
    "W              W",
    "W              W",
    "WWWWWWWWWWWWWWWW",
]
x = y = 0
for row in level:
    for col in row:
        if col == "W":
            Wall((x, y)) 
        x += 50
    y += 50
    x = 0

run = True

while run: #The game starts running
    win.fill(overworld)
    pygame.time.delay(30)

    for event in pygame.event.get(): #You can stop the game now too
        if event.type == pygame.QUIT:
            run = False

    oldPlyerX, oldPlyerY = player.rect.topleft
    keys = pygame.key.get_pressed()  #To retain the feel of retro video games, I have made it impossible to walk diagonally
    if keys[pygame.K_w] and not keys[pygame.K_a] and not keys[pygame.K_d]:
        player.rect.y -= playerYVel
    if keys[pygame.K_a] and not keys[pygame.K_w] and not keys[pygame.K_s]:
        player.rect.x -= playerXVel
    if keys[pygame.K_s] and not keys[pygame.K_a] and not keys[pygame.K_d]:
        player.rect.y += playerYVel
    if keys[pygame.K_d] and not keys[pygame.K_s] and not keys[pygame.K_w]:
        player.rect.x += playerXVel

    for allwalls in walls:
        if player.rect.colliderect(allwalls):
            player.rect.topleft = oldPlyerX, oldPlyerY

    #Drawing every rectangle in :3
    pygame.draw.rect(win, (0, 255, 0), player.rect)
    for wall in walls:
        pygame.draw.rect(win, (143, 41, 3), wall.rect)

    pygame.display.update()
pygame.quit()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM