精灵的Pygame碰撞检测



我有两个精灵,它们可以通过WASD和箭头键独立移动。我想尝试做碰撞检测,如果一个触摸另一个,它不会穿过对方。我在while循环中尝试过,但它会无限期地执行,精灵会相互卡住,游戏崩溃。我试过只使用if,但没有多大作用。为格式错误道歉

我的代码:

displayWidth = 500
displayHeight = 500
display = pygame.display.set_mode((displayWidth,displayHeight))
clock = pygame.time.Clock()

class Player(pygame.sprite.Sprite):
def __init__(self,image,x,y):
super().__init__()
self.image = image
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def move(self, keyPress,kup,kdown,kleft,kright):
if keyPress[kup]:
self.rect.move_ip(0,-5)
if keyPress[kdown]:
self.rect.move_ip(0,5)
if keyPress[kleft]:
self.rect.move_ip(-5,0)
if keyPress[kright]:
self.rect.move_ip(5,0)
if self.rect.left < 0:
self.rect.left = 0
if self.rect.right > displayWidth:
self.rect.right = displayWidth
if self.rect.top < 0:
self.rect.top = 0
if self.rect.bottom > displayHeight:
self.rect.bottom = displayHeight
pygame.display.update()
pygame.init()
pygame.display.set_caption("Collision Detection")
sprite1 = Player(pygame.image.load("Images/down.png"),0,0)
enemy1 = Player(pygame.image.load("Images/up.png"),100,100)
player_list = pygame.sprite.Group()
enemy_list = pygame.sprite.Group()
player_list.add(sprite1)
enemy_list.add(enemy1)

gameRunning = True
while gameRunning == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameRunning = False
display.fill([0,0,0])
keyPress = pygame.key.get_pressed()
playerPositionX = sprite1.rect.x
playerPositionY = sprite1.rect.y
enemyPositionX = enemy1.rect.x
enemyPositionY = enemy1.rect.y
while pygame.sprite.collide_rect(sprite1,enemy1):
sprite1.rect.x = playerPositionX
sprite1.rect.y = playerPositionY
enemy1.rect.x = enemyPositionX
enemy1.rect.y = enemyPositionY
player_list.draw(display)
enemy_list.draw(display)
sprite1.move(keyPress,K_UP,K_DOWN,K_LEFT,K_RIGHT)
enemy1.move(keyPress,K_w,K_s,K_a,K_d)
pygame.display.flip()
clock.tick(60)
pygame.quit()

您可以尝试使用IF语句将播放器和精灵的位置设置为0。检查玩家的位置是否大于敌人的位置,反之亦然。如果是,请将玩家x设置为0(请确保在更新循环中这样做,因为它无法正常工作!(

E.g用于阻止玩家:

if player.x > enemy.x:
player.x = 0

顺序很重要。你必须在移动树枝后做碰撞测试。copy子画面移动前的矩形,并在检测到碰撞时恢复矩形:

gameRunning = True
while gameRunning == True:
# [...]

player_rect = sprite1.rect.copy()
enemy_rect = enemy1.rect.copy()
keyPress = pygame.key.get_pressed()
sprite1.move(keyPress,K_UP, K_DOWN, K_LEFT, K_RIGHT)
enemy1.move(keyPress, K_w, K_s, K_a, K_d)
if pygame.sprite.collide_rect(sprite1, enemy1):
sprite1.rect = player_rect
enemy1.rect = enemy_rect
# [...]

我建议简化代码。特别是Player类:

mport pygame
from pygame.locals import *
pygame.init()
displayWidth = 500
displayHeight = 500
display = pygame.display.set_mode((displayWidth,displayHeight))
pygame.display.set_caption("Collision Detection")
clock = pygame.time.Clock()
class Player(pygame.sprite.Sprite):
def __init__(self,image,x,y):
super().__init__()
self.image = image
self.rect = self.image.get_rect(topleft = (x, y))
def move(self, keyPress, kup, kdown, kleft, kright):
self.rect.x += (keyPress[kright] - keyPress[kleft]) * 5
self.rect.y += (keyPress[kdown] - keyPress[kup]) * 5
self.rect.clamp_ip(display.get_rect())
sprite1 = Player(pygame.image.load("Images/down.png"), 0, 0)
enemy1 = Player(pygame.image.load("Images/up.png"), 100, 100)
player_list = pygame.sprite.Group([sprite1])
enemy_list = pygame.sprite.Group([enemy1])
gameRunning = True
while gameRunning == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameRunning = False

player_rect = sprite1.rect.copy()
enemy_rect = enemy1.rect.copy()
keyPress = pygame.key.get_pressed()
sprite1.move(keyPress,K_UP, K_DOWN, K_LEFT, K_RIGHT)
enemy1.move(keyPress, K_w, K_s, K_a, K_d)
if pygame.sprite.collide_rect(sprite1, enemy1):
sprite1.rect = player_rect
enemy1.rect = enemy_rect
display.fill((0, 0, 0))
player_list.draw(display)
enemy_list.draw(display)
pygame.display.flip()
clock.tick(60)
pygame.quit()

最新更新