pygame中的碰撞检测不工作

2024-09-27 23:20:54 发布

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

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

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()

Tags: keyselfeventifdefchangescreenpygame
1条回答
网友
1楼 · 发布于 2024-09-27 23:20:54

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()

如果要更改全局命名空间中的变量,则需要使用^{} 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)

相关问题 更多 >

    热门问题