Pygame 精灵碰撞

1 投票
1 回答
4924 浏览
提问于 2025-04-18 06:31

我正在尝试制作一个简单的游戏,里面有两个角色(精灵)。但是我不知道怎么写代码来检测一个角色是否碰到了另一个角色。我也很难理解网上关于这个主题的很多教程。如果你能尽量简单地给我解释一下,那就太好了!

import pygame
import sys
from pygame.locals import *
pygame.init()

black = (0, 0, 0)
white = (255, 255, 255)
bg = black
square = pygame.image.load('square.png')
square1 = pygame.image.load('square1.png')
screen = pygame.display.set_mode((640, 400))

UP = 'UP'
DOWN = 'DOWN'
LEFT = 'LEFT'
RIGHT = 'RIGHT'
direction = RIGHT
movex, movey, movex1, movey1 = 100, 100, 200, 200

class player1(pygame.sprite.Sprite):
    """Player 1"""

    def __init__(self, xy):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('square.png')
        self.rect = self.image.get_rect()

class player2(pygame.sprite.Sprite):
    """Player 2"""

    def __init__(self, xy):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('square1.png')
        self.rect = self.image.get_rect()

while True:
    screen.fill(black)
    collide = pygame.sprite.collide_mask(player1, player2)
    if collide == True:
        print 'collision!'
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_w:
                movey -= 10 
            elif event.key == K_s:
                movey += 10
            elif event.key == K_a:
                movex -= 10
            elif event.key == K_d:
                movex += 10
            if event.key == K_UP:
                movey1 -= 10 
            elif event.key == K_DOWN:
                movey1 += 10
            elif event.key == K_LEFT:
                movex1 -= 10
            elif event.key == K_RIGHT:
                movex1 += 10
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    screen.blit(square, (movex, movey))
    screen.blit(square1, (movex1, movey1))
    pygame.display.update()

1 个回答

3

首先,有几个问题:

  • pygame.sprite.collide_mask 这个函数永远不会返回 True。它会返回一个点或者 None。所以你检查 collide == True 这个条件永远不会成立。
  • pygame.sprite.collide_mask 需要两个 Sprite 实例作为参数,但你传入的是类对象(比如 collide_mask(player1, player2))。
  • 只有在你想要进行像素级别的碰撞检测时,才需要使用 pygame.sprite.collide_mask
  • 在你的代码的其他部分,其实并没有使用到 player1player2 这两个类。

如果你在使用 Sprite 类,进行碰撞检测的一个简单方法是使用 Group 类。不过因为你只有两个精灵,你可以简单地通过检查它们的 Rects 是否相交来判断碰撞,使用 colliderect 函数就可以了。

我已经更新了你的代码,使用了 Sprite 类:

import pygame
import sys
from pygame.locals import *
pygame.init()

black = (0, 0, 0)
white = (255, 255, 255)

screen = pygame.display.set_mode((640, 400))

class Player(pygame.sprite.Sprite):

    def __init__(self, image, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(image)
        self.rect = self.image.get_rect(x=x, y=y)

player1, player2 = Player('square.png', 100, 100), Player('square1.png', 200, 200)
players = pygame.sprite.Group(player1, player2)

while True:
    screen.fill(black)

    if player1.rect.colliderect(player2.rect):
        print 'collision!'

    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_w:
                player1.rect.move_ip(0, -10) 
            elif event.key == K_s:
                player1.rect.move_ip(0, 10)
            elif event.key == K_a:
                player1.rect.move_ip(-10, 0)
            elif event.key == K_d:
                player1.rect.move_ip(10, 0)
            if event.key == K_UP:
                player2.rect.move_ip(0, -10)
            elif event.key == K_DOWN:
                player2.rect.move_ip(0, 10)
            elif event.key == K_LEFT:
                player2.rect.move_ip(-10, 0)
            elif event.key == K_RIGHT:
                player2.rect.move_ip(10, 0)
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    players.draw(screen)
    pygame.display.update()

碰撞检测是一个比较广泛的话题,但这些内容应该能帮助你入门。

撰写回答