Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在pygame中检测碰撞?_Python_Pygame_Collision Detection_Pygame Surface_Pygame2 - Fatal编程技术网

Python 如何在pygame中检测碰撞?

Python 如何在pygame中检测碰撞?,python,pygame,collision-detection,pygame-surface,pygame2,Python,Pygame,Collision Detection,Pygame Surface,Pygame2,我使用下面的类制作了一个子弹列表和一个精灵列表。如何检测子弹是否与精灵碰撞,然后删除精灵和子弹 #Define the sprite class class Sprite: def __init__(self,x,y, name): self.x=x self.y=y self.image = pygame.image.load(name) self.rect = self.image.get_rect()

我使用下面的类制作了一个子弹列表和一个精灵列表。如何检测子弹是否与精灵碰撞,然后删除精灵和子弹

#Define the sprite class
class Sprite:

    def __init__(self,x,y, name):
        self.x=x

        self.y=y

        self.image = pygame.image.load(name)

        self.rect = self.image.get_rect()

    def render(self):
        window.blit(self.image, (self.x,self.y))


# Define the bullet class to create bullets          
class Bullet:

    def __init__(self,x,y):
        self.x = x + 23
        self.y = y
        self.bullet = pygame.image.load("user_bullet.BMP")
        self.rect = self.bullet.get_rect()

    def render(self):
        window.blit(self.bullet, (self.x, self.y))

根据我对pygame的理解,您只需要使用该方法检查两个矩形是否重叠。一种方法是在
Bullet
类中使用一个方法来检查冲突:

def is_collided_with(self, sprite):
    return self.rect.colliderect(sprite.rect)
然后你可以这样称呼它:

sprite = Sprite(10, 10, 'my_sprite')
bullet = Bullet(20, 10)
if bullet.is_collided_with(sprite):
    print('collision!')
    bullet.kill()
    sprite.kill()

有一个非常简单的方法可以帮助您使用内置的方法来完成任务

这里有一个例子

import pygame
import sys

class Sprite(pygame.sprite.Sprite):
    def __init__(self, pos):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([20, 20])
        self.image.fill((255, 0, 0))
        self.rect = self.image.get_rect()

        self.rect.center = pos

def main():
    pygame.init()
    clock = pygame.time.Clock()
    fps = 50
    bg = [255, 255, 255]
    size =[200, 200]


    screen = pygame.display.set_mode(size)

    player = Sprite([40, 50])
    player.move = [pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN]
    player.vx = 5
    player.vy = 5


    wall = Sprite([100, 60])

    wall_group = pygame.sprite.Group()
    wall_group.add(wall)

    player_group = pygame.sprite.Group()
    player_group.add(player)

    # I added loop for a better exit from the game
    loop = 1
    while loop:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                loop = 0

        key = pygame.key.get_pressed()

        for i in range(2):
            if key[player.move[i]]:
                player.rect.x += player.vx * [-1, 1][i]

        for i in range(2):
            if key[player.move[2:4][i]]:
                player.rect.y += player.vy * [-1, 1][i]

        screen.fill(bg)

        # first parameter takes a single sprite
        # second parameter takes sprite groups
        # third parameter is a do kill command if true
        # all group objects colliding with the first parameter object will be
        # destroyed. The first parameter could be bullets and the second one
        # targets although the bullet is not destroyed but can be done with
        # simple trick bellow
        hit = pygame.sprite.spritecollide(player, wall_group, True)

        if hit:
            # if collision is detected call a function in your case destroy
            # bullet
            player.image.fill((255, 255, 255))

        player_group.draw(screen)
        wall_group.draw(screen)

        pygame.display.update()
        clock.tick(fps)

    pygame.quit()
    # sys.exit


if __name__ == '__main__':
    main()

为项目符号创建一个组,然后将项目符号添加到该组中

我要做的是: 在玩家的课堂上:

def collideWithBullet(self):
    if pygame.sprite.spritecollideany(self, 'groupName'):
        print("CollideWithBullet!!")
        return True
在主回路的某个地方:

def run(self):
    if self.player.collideWithBullet():
         print("Game Over")

希望这对你有用

在PyGame中,可以使用对象进行基本碰撞检测。
Rect
对象提供了检测对象之间碰撞的各种方法。请注意,在乒乓球游戏中,即使是矩形对象与圆形对象(如球拍和球)的碰撞,也可以通过两个矩形对象(球拍和球的边界矩形)之间的碰撞来大致检测

一些例子:

  • :

    测试点是否位于矩形内

    导入pygame
    pygame.init()
    window=pygame.display.set_模式((250250))
    rect=pygame.rect(*window.get_rect()。居中,0,0)。充气(100100)
    运行=真
    运行时:
    对于pygame.event.get()中的事件:
    如果event.type==pygame.QUIT:
    运行=错误
    point=pygame.mouse.get_pos()
    碰撞=矩形碰撞点(点)
    颜色=(255,0,0)如果碰撞其他(255,255,255)
    窗口填充(0)
    pygame.draw.rect(窗口、颜色、rect)
    pygame.display.flip()
    pygame.quit()
    退出()
    
  • 测试两个矩形是否重叠

    另见

    导入pygame
    pygame.init()
    window=pygame.display.set_模式((250250))
    rect1=pygame.Rect(*window.get_Rect()。居中,0,0)。充气(75,75)
    rect2=pygame.Rect(0,0,75,75)
    运行=真
    运行时:
    对于pygame.event.get()中的事件:
    如果event.type==pygame.QUIT:
    运行=错误
    rect2.center=pygame.mouse.get_pos()
    collide=rect1.collide-rect(rect2)
    颜色=(255,0,0)如果碰撞其他(255,255,255)
    窗口填充(0)
    pygame.draw.rect(窗口、颜色、rect1)
    pygame.draw.rect(窗口,(0,255,0),rect2,6,1)
    pygame.display.flip()
    pygame.quit()
    退出()
    
此外,可用于矩形和矩形列表之间的碰撞测试。可用于矩形和矩形字典之间的碰撞测试

和对象的碰撞可通过或检测。使用这些方法时,可以通过
collized
参数指定碰撞检测算法:

碰撞参数是一个回调函数,用于计算两个精灵是否碰撞

可能的
冲突
可调用项为

一些例子:

  • 导入pygame
    pygame.init()
    window=pygame.display.set_模式((250250))
    sprite1=pygame.sprite.sprite()
    sprite1.image=pygame.Surface((75,75))
    sprite1.image.fill((255,0,0))
    sprite1.rect=pygame.rect(*window.get_rect().center,0,0)。充气(75,75)
    sprite2=pygame.sprite.sprite()
    sprite2.image=pygame.Surface((75,75))
    sprite2.image.fill((0,255,0))
    sprite2.rect=pygame.rect(*window.get_rect()。中心,0,0)。充气(75,75)
    all_group=pygame.sprite.group([sprite2,sprite1])
    test_group=pygame.sprite.group(sprite2)
    运行=真
    运行时:
    对于pygame.event.get()中的事件:
    如果event.type==pygame.QUIT:
    运行=错误
    sprite1.rect.center=pygame.mouse.get_pos()
    collide=pygame.sprite.spritecollide(sprite1,测试组,False)
    窗口填充(0)
    所有组绘制(窗口)
    对于碰撞中的s:
    pygame.draw.rect(窗口,(255,255,255),s.rect,5,1)
    pygame.display.flip()
    pygame.quit()
    退出()
    
有关与遮罩的碰撞,请参见或

另见

  • /

    导入pygame
    pygame.init()
    window=pygame.display.set_模式((250250))
    sprite1=pygame.sprite.sprite()
    sprite1.image=pygame.Surface((80,80),pygame.SRCALPHA)
    pygame.draw.circle(sprite1.image,(255,0,0),(40,40),40)
    sprite1.rect=pygame.rect(*window.get_rect()。中心,0,0)。充气(40,40)
    sprite2=pygame.sprite.sprite()
    sprite2.image=pygame.Surface((80,89),pygame.SRCALPHA)
    pygame.draw.circle(sprite2.image,(0,255,0)、(40,40),40)
    sprite2.rect=pygame.rect(*window.get_rect()。中心,0,0)。充气(80,80)
    all_group=pygame.sprite.group([sprite2,sprite1])
    test_group=pygame.sprite.group(sprite2)
    运行=真
    运行时:
    对于pygame.event.get()中的事件:
    如果event.type==pygame.QUIT:
    运行=错误
    sprite1.rect.center=pygame.mouse.get_pos()
    collide=pygame.sprite.spritecollide(sprite1,test_组,False,pygame.sprite.collide_圈)
    窗口填充(0)
    所有组绘制(窗口)
    对于碰撞中的s:
    pygame.draw.circle(窗口,(255,255,255),s.rect.center,s.rect.width//2,5)
    pygame.display.flip()
    pygame.quit()
    退出()
    

这对您的代码意味着什么

返回一个具有曲面对象大小的矩形,该矩形始终从(0,0)开始,因为曲面对象没有位置。矩形的位置可以通过关键字参数指定。例如,可以使用关键字参数
center
指定矩形的中心。这些关键字参数在返回之前应用于的属性(有关关键字参数的完整列表,请参阅)。
看*

您根本不需要
Sprite
Bullet
x
y
属性。使用
rect的位置