人工知能に関する断創録スマートフォン用の表示で見るスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。ロボティクス、生物学などに興味を持っています。このブログでは人工知能のさまざまな分野について調査したことをまとめています。Learning、Kerasに関する記事が多いです。2008-08-11ブロックを壊すPygameブロックを配置してボールが当たると壊れるようにします。ブロックをブロックグループに追加し、ボールスプライトとブロックグループの衝突判定を行います。Spriteの衝突判定機能を使うと簡単にできます。ここまでくるとゲームっぽくなってきます。breakout03.zipブロックの実装と配置まずブロックを表すBrickクラスから作ります(Brickはつづりミスではなくレンガや積み木という意味です。別にBlockでもいいです)。ブロッククラスもパドルやボールと同じく、Spriteを継承するのでスプライトになります。非常に単純でコンストラクタしかありません。self.rect.heightコンストラクタで指定した引数の位置にブロックを配置します。ピクセル単位の座標ではなく、ブロックのサイズを1マスとしたときのマス単位の座標です。フィールド上にブロックをぎっしりはめこんだとき一番左上が(0,0)になります。その右となりのブロックは(1,0)です。ピクセル単位よりマス単位で座標を指定できた方がブロックの配置が簡単になります。実際にブロックをフィールド上に配置するのはmain()です。y)for文で10列5行のブロックを作成しています。ここでBrick(x,y)とオブジェクトを作っただけでどこにも格納していません。実は、後で見るようにブロックにもデフォルトスプライトグループ(self.containers)を指定しています。そのため、ブロックを作成したと同時にスプライトグループに追加されます。ブロックの描画や更新はスプライトグループが行うので作成したブロックはちゃんと画面に描画されます。次にボールがブロックに当たったときにブロックが消える処理を実装します。スプライトとグループが衝突したかを調べるための方法がpygameには用意されています。そのために新しいスプライトグループを追加します。bricksパドルやボールは今までallというRenderUpdatesグループに追加していました。RenderUpdatesは、描画や更新を行うスプライトグループです。ブロックも描画や更新はしなくてはいけないのでBrick.containersにallを追加しています。新しく追加されたのはbricksというpygame.sprite.Groupです。こちらは主に衝突判定に使うスプライトグループです。今回は、ボールとブロックグループがぶつかったか判定したいのでブロックを追加するbricksグループを作成しています。bricksには先ほど作成したように10x5=50個のBrickが追加されます。brickのようにカンマで区切って並べます。ボールとブロックの衝突は、ボールスプライトとブロックスプライトグループの衝突があるか調べます。pygameでは、スプライトとスプライトグループの衝突を調べるpygame.sprite.spritecollide()という関数があります。dokill)という形式の関数でspriteとgroup内のいずれかのスプライトが衝突したか調べ、group内の衝突したスプライトをリストで返します。dokillをTrueにしておくとspriteと衝突したgroup内のスプライトをすべてgroupから消します。groupから消えたスプライトはdraw()されなくなるので画面からも消えます。実際にボールとブロックが衝突したときの処理を見てみます。Ballのmove()です。True)となっています。selfはボールスプライト、self.bricksはブロックスプライトグループです。ボールスプライトとブロックスプライトグループが衝突しているか調べ、衝突したブロックのリストをbricks_collidedに格納します。dokillをTrueとしているので衝突したブロックはbricksグループから取り除かれ消えます。次に衝突ブロックがある場合、どの方向からボールがブロックに当たったかを調べてボールの反射方向を計算しています。ここで、oldrectはボールの矩形を表します。if文内でself.rectを更新しているので元のボールの矩形を保持しておく必要があります。ボールがどの方角からブロックに当たったかを求める条件式は下の図を見てください。ボールの矩形とブロックの矩形の位置関係から判断できます。brick.rect.leftのような式はボールが上図のようにブロックに食い込んだとき食い込まないように位置を戻してやる式です。elifを使わなかったのはボールがちょうどブロックの角にぶつかる場合もあるからです。ブロックの左下に当たった場合、ボールが左から衝突とボールが下から衝突の2つの条件を満たします。今回はスプライトとグループの衝突判定を調べましたが、pygameには他にもいろいろ衝突判定関数が用意されています。スプライトとグループの衝突判定(pygame.sprite.spritecollide())グループとグループの衝突判定(pygame.sprite.groupcollide())今回使ったのは1番目のスプライトとグループの衝突判定を行う関数です。2番目のグループとグループの衝突判定はたとえばボールがたくさんある場合にボールグループとブロックグループで衝突判定を行うときに使います。スプライトとスプライトの衝突判定はどうすればいいでしょう?これは、ボールの反射でパドルとボールの衝突判定を調べたようにRect.colliderect()を使えばいいですね。pygame1.8.0からpygame.sprite.collide_rect()というスプライトとスプライトの衝突判定関数が追加されています。取るようになっていて意味がよくわかりません。中身を調べてみないと。»プロフィールid:aidiary人工知能とその関連分野に興味があります。Blog|ブログを報告する。