Pygame入門 ブロック崩しゲームを作る(途中) ボールと衝突したブロックを消す しかし、ボールはブロックに当たっても跳ね返らない
マウスの左クリックで開始します
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) BLUE = (0, 0, 255) BALL_SIZE = 20 PADDLE_WIDTH = 60 PADDLE_HEIGHT = 5 PADDLE_POS_Y = SCREEN.bottom - 30 BLOCK_ROW = 5 BLOCK_COLUMN = 6 BLOCK_MARGIN = 10 BLOCK_WIDTH = ((SCREEN.width - BLOCK_MARGIN) / BLOCK_COLUMN) - BLOCK_MARGIN BLOCK_HEIGHT = 20 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 self.update = self.start #これにより、updateメソッドが呼び出されるとstartメソッドが実行される def start(self): #Ballの初期X座標をPaddleのX座標にする self.rect.centerx = paddle.rect.centerx #マウスの左クリックによりBallを動かし始める if pygame.mouse.get_pressed()[0]: self.update = self.move #これにより、updateメソッドが呼び出されるとmoveメソッドが実行される def move(self): #Ballを移動させる self.rect.move_ip(self.vx, self.vy) #Paddleに当たったら跳ね返る if self.rect.colliderect(paddle.rect): self.vy = -self.vy self.rect.bottom = paddle.rect.top #画面の左端か右端に当たったら跳ね返る if self.rect.left < SCREEN.left or SCREEN.right < self.rect.right: self.vx = -self.vx #画面の上端に当たったら跳ね返る if self.rect.top < SCREEN.top: self.vy = -self.vy #画面の下端に当たったら止まる if SCREEN.bottom < self.rect.bottom: self.vx = 0 self.vy = 0 self.rect = self.rect.clamp(SCREEN) #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から出ないようにする class Block(pygame.sprite.Sprite): def __init__(self, pos): pygame.sprite.Sprite.__init__(self, self.containers) x, y = pos self.image = pygame.Surface((BLOCK_WIDTH, BLOCK_HEIGHT)) self.image.fill(BLUE) self.rect = pygame.Rect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT) #main pygame.init() clock = pygame.time.Clock() screen = pygame.display.set_mode(SCREEN.size) sprite_group = pygame.sprite.Group() #すべてのスプライトの更新と描画を行うためのグループ block_group = pygame.sprite.Group() #BallとBlockの衝突判定とBlockの削除を行うためのグループ Ball.containers = sprite_group #これにより、Ballインスタンスが自動でsprite_groupに追加される Paddle.containers = sprite_group #これにより、Paddleインスタンスが自動でsprite_groupに追加される Block.containers = sprite_group, block_group #これにより、Blockインスタンスが自動でsprite_groupとblock_groupに追加される ball = Ball((200, 150), (6, 6)) paddle = Paddle() #Blockの作成 for r in range(BLOCK_ROW): for c in range(BLOCK_COLUMN): block_x = BLOCK_MARGIN + (BLOCK_WIDTH + BLOCK_MARGIN) * c block_y = BLOCK_MARGIN + (BLOCK_HEIGHT + BLOCK_MARGIN) * r Block((block_x, block_y)) while True: #Ballと衝突したBlockを削除する #ballスプライトとblock_groupに属している各Blockスプライトの衝突を判定してくれる #3つ目の引数をTrueにするとballと衝突したBlockがblock_groupから削除される #それによりballと衝突したBlockは画面から消える。(画面描画はsprite_group.draw(screen)により行われているため。) pygame.sprite.spritecollide(ball, block_group, True) sprite_group.update() screen.fill(WHITE) 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()