在 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
谁能告诉我我在做什么wrong/what我应该输入代码而不是防止玩家穿墙?
在应用程序循环之前创建一次对象。您根本不需要变量 playerX
和 playerY
。请改用 player.rect.x
和 player.rect.y
。
在移动之前存储玩家的位置。如果检测到碰撞,恢复玩家位置:
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()
我在 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
谁能告诉我我在做什么wrong/what我应该输入代码而不是防止玩家穿墙?
在应用程序循环之前创建一次对象。您根本不需要变量 playerX
和 playerY
。请改用 player.rect.x
和 player.rect.y
。
在移动之前存储玩家的位置。如果检测到碰撞,恢复玩家位置:
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()