pygame 中的碰撞检测不工作

Collision detection in pygame not working

所以我正在尝试在我制作的 pygame 小游戏中实现一些碰撞检测。但是,我的代码似乎无法正常工作。或者我可能只是不知道如何实施它。在这个游戏中,我必须在没有 运行 goblin 的情况下获得 playerprincess。一切正常,但我似乎无法在 playergoblin 之间实现碰撞检测。理想情况下,如果它击中 goblin,我希望 player 回到起始位置。你可以看到我确实有一个 isCollision 函数,但是当我尝试调用它时,我得到“NameError: name 'playerX' is not defined”

import pygame
import math

# Initialize the pygame
pygame.init()

# Setting up the screen and background
screen = pygame.display.set_mode((800,600))

# Title and Icon of window
pygame.display.set_caption("Get Princess")

icon = pygame.image.load('knight.png')
pygame.display.set_icon(icon)


#Princess Image
princessImg = pygame.image.load('princess.png')
princessImg = pygame.transform.scale(princessImg, (50,50))
princessX = 360
princessY = 20
princessX_change = 0
princessY_change = 0


class player():
    def __init__(self, playerX, playerY, playerX_change, playerY_change):
        self.playerX = playerX
        self.playerY = playerY
        self.playerX_change = playerX_change
        self.playerY_change = playerY
        self.playerImg = pygame.image.load('knight.png')
        self.playerImg = pygame.transform.scale(self.playerImg, (50,50))
        self.rect = pygame.Rect(32,32,16,16)
        

    def pdraw(self):
        screen.blit(self.playerImg, (self.playerX, self.playerY))
            

    def pmovement(self):
        self.playerX += self.playerX_change
        self.playerY += self.playerY_change
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                self.playerY_change = -0.4
            if event.key == pygame.K_DOWN:
                self.playerY_change = 0.4
            if event.key == pygame.K_LEFT:
                self.playerX_change = -0.4
            if event.key == pygame.K_RIGHT:
                self.playerX_change = 0.4
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                self.playerX_change = 0
            elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                self.playerY_change = 0

        if self.playerX <= 0:
            self.playerX = 0
        elif self.playerX >= 750:
            self.playerX = 750
        if self.playerY <= 0:
            self.playerY = 0
        elif self.playerY >= 550:
            self.playerY = 550


class goblin():
    def __init__(self, goblinX, goblinY, goblinX_change):
        self.goblinX = goblinX
        self.goblinY = goblinY
        self.goblinX_change = goblinX_change
        self.goblinImg = pygame.image.load('goblin.png')
        self.goblinImg = pygame.transform.scale(self.goblinImg,(50,50))
    
    def draw(self):
        screen.blit(self.goblinImg, (self.goblinX, self.goblinY))
        
    
    def movement(self):
        self.goblinX += self.goblinX_change
        if self.goblinX <= 0 or self.goblinX >= 750:
            self.goblinX_change = self.goblinX_change * -1


def princess(x,y):
    screen.blit(princessImg, (x, y))

p = player(360, 520, 0, 0)
g = goblin(360,250, 0.10)
g1 = goblin(360, 280, 0.5)
g2 = goblin(360, 200, 0.7)
g3 = goblin(360, 160, 0.4)
goblinlist = [g, g1, g2, g3]

def isCollision(playerX, playerY, goblinX, goblinY):
    dx = playerX - goblinY
    dy = playerY - goblinY
    distance = math.sqrt(math.pow(dx,2) + math.pow(dy,2))
    if distance < 27:
        p = player(360, 520, 0,0)


running = True
while running:

    screen.fill((50,0,0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
                    
    princess(princessX, princessY)
    
    g.movement()
    g.draw()
    
    g1.movement()
    g1.draw()

    g2.movement()
    g2.draw()

    g3.movement()
    g3.draw()

    p.pmovement()
    p.pdraw()

    isCollision(p.playerX, p.playerY, g1.goblinX, g1.goblinY)
    
    pygame.display.update()

isCollision 是函数,playerXplayerYgoblinXgoblinY 是函数的参数。您没有 self 参数。通常 selfMethods.
中的对象 从函数 isCollision:

中删除所有 self.
def isCollision(playerX, playerY, goblinX, goblinY):
    dx = playerX - goblinX
    dy = playerY - goblinY
    distance = math.sqrt(math.pow(dx, 2) + math.pow(dy, 2))
    return distance < 27

将玩家 (p) 和地精 (gg1g2g3) 的坐标传递给函数:

例如:

if isCollision(p.playerX, p.playerY, g.goblinX, g.goblinY):
    #  do something
    # [...]  

请注意,您可以创建地精列表并循环执行碰撞测试:

goblin_list = [g, g1, g2, g3]
for gob in goblin_list: 
    if isCollision(p.playerX, p.playerY, gob.goblinX, gob.goblinY):
        # [...] 

您甚至可以循环移动和绘制地精:

for gob in goblin_list:
    gob.movement()
    gob.draw()

如果要更改全局命名空间中的变量,需要使用 global statement

def isCollision(playerX, playerY, goblinX, goblinY):

    global p

    dx = playerX - goblinX
    dy = playerY - goblinY
    distance = math.sqrt(math.pow(dx, 2) + math.pow(dy,2))
    if distance < 27:
        p = player(360, 520, 0,0)