Pygame入門 Sprite同士の衝突を検知して、そのSpriteを削除する

f:id:collatz:20220405170715g:plain
pygame.sprite.spritecollideでSprite同士の衝突を検知できる。
また、引数の指定によって、衝突したSpriteを削除できる。

pygame.sprite.spritecollide(sprite, group, dokill)
2番めの引数のgroupに属するSpriteのうち、
1番目の引数のspriteと衝突しているもののリストを返す。
3番めの引数のdokillをTrueにすると、衝突しているSpriteがgroupから削除される。
Spriteの衝突判定は、Spriteのrectプロパティによって行っている。

import pygame
import sys

SCREEN = pygame.Rect(0, 0, 400, 400)
FPS = 30

WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)

BALL_SIZE = 20

PADDLE_WIDTH = 60
PADDLE_HEIGHT = 20
PADDLE_POS_Y = SCREEN.bottom - PADDLE_HEIGHT * 2

class Ball(pygame.sprite.Sprite):
    def __init__(self, pos, speed):
        pygame.sprite.Sprite.__init__(self, self.containers)
        x, y = pos
        vx, vy = speed
        self.image = pygame.Surface((BALL_SIZE, BALL_SIZE))
        self.image.fill(WHITE)
        pygame.draw.circle(self.image, RED, self.image.get_rect().center, BALL_SIZE / 2)
        self.rect = pygame.Rect(x, y, BALL_SIZE, BALL_SIZE)
        self.vx = vx
        self.vy = vy

    def update(self):
        self.rect.move_ip(self.vx, self.vy)
        if self.rect.left < SCREEN.left or SCREEN.right < self.rect.right:
            self.vx = -self.vx
        if self.rect.top < SCREEN.top or SCREEN.bottom < self.rect.bottom:
            self.vy = -self.vy
        self.rect = self.rect.clamp(SCREEN)

class Paddle(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self, self.containers)
        self.image = pygame.Surface((PADDLE_WIDTH, PADDLE_HEIGHT))
        self.image.fill(GREEN)
        self.rect = pygame.Rect(0, PADDLE_POS_Y, PADDLE_WIDTH, PADDLE_HEIGHT)

    def update(self):
        self.rect.centerx = pygame.mouse.get_pos()[0] #Paddleの真ん中のX座標をマウスのX座標にする
        self.rect = self.rect.clamp(SCREEN) #SCREENから出ないようにする

#main()
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode(SCREEN.size)

sprite_group = pygame.sprite.Group() #すべてのスプライトの更新と描画を行うためのグループ
ball_group = pygame.sprite.Group() #Paddleとの衝突を調べるためのグループ

Ball.containers = sprite_group, ball_group
Paddle.containers = sprite_group

Ball((200, 200), (2, 3))
Ball((100, 200), (3, 3))
Ball((100, 300), (3, 4))
paddle = Paddle()

while True:
    #paddleと衝突したBallを削除する
    pygame.sprite.spritecollide(paddle, ball_group, True)

    screen.fill(WHITE)
    sprite_group.update()
    sprite_group.draw(screen)

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

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()