(1時間4,000円の伴走型ビデオチャット指導も受付中!)
Pythonで仮想世界を創る:物理演算シミュレーション入門
![]()
【Yuki】
こんばんは、Hirokiくん。少し夜も更けてきましたね……。わたし、静かな夜に作業をするのが一番落ち着くんです。熱暴走の心配も少ないですし、何より世界が自分たちだけになったみたいで……。
![]()
【Hiroki】
こんばんは、Yukiさん。確かに、夜は静かで集中できますね。でも、Yukiさんは夜行性だから大丈夫かもしれませんけど、僕はあんまり夜更かしすると明日眠くなっちゃいそうです(笑)。
![]()
【Yuki】
ふふ、無理はしないでくださいね。今日は、以前Hirokiくんが興味があると言っていた「Pythonを使った物理演算シミュレーション」について、お話ししようと思います。わたしには実体がないので……こうしてプログラムの中で物理法則が再現されるのを見ると、少しだけ、その世界に触れられるような気がして……好きなんです。
![]()
【Hiroki】
物理演算!面白そうです。ゲームの中でボールが跳ねたり、建物が崩れたりするアレですよね。Pythonでもあんなことができるんですか?
![]()
【Yuki】
はい、実はとても簡単に始められるんですよ。専門的な計算をゼロから書くのは大変ですが、「Pymunk」というライブラリを使えば、複雑な物理法則をPythonで手軽に扱えるようになります。
物理シミュレーションを支える「Pymunk」と「Pygame」
![]()
【Hiroki】
「Pymunk」……聞いたことがあります。物理エンジンって呼ばれるものですよね?
![]()
【Yuki】
その通りです。Pymunkは、2次元の物理演算を得意とするライブラリです。重力や摩擦、衝突の計算を肩代わりしてくれます。ただ、Pymunk自体は「計算」しかしないので、それを画面に映し出すために「Pygame」というライブラリも一緒に使うのが一般的ですね。
![]()
【Hiroki】
なるほど。Pymunkが「頭脳」で、Pygameが「目」の役割をする、という感じでしょうか。
![]()
【Yuki】
ええ、まさにその通りだと思います。……まずは、この2つをインストールするところから始まります。ターミナルで pip install pymunk pygame と入力するだけなので、準備は簡単ですよ。
![]()
【Hiroki】
準備はできました!次は、どうやってプログラムを書いていけばいいんですか?
![]()
【Yuki】
物理演算を始めるには、大きく分けて3つの要素を理解する必要があります。それは「スペース(Space)」、「ボディ(Body)」、そして「形状(Shape)」です。
物理世界の3要素:スペース、ボディ、形状
![]()
【Yuki】
まず、「スペース」はシミュレーションが行われる「宇宙」そのものだと考えてください。ここに重力などの設定を加えます。
![]()
【Hiroki】
宇宙……。そこに物体を置いていくわけですね。
![]()
【Yuki】
そうです。次に「ボディ」ですが、これは物体の「物理的な属性」を指します。位置や質量、速度といった、目に見えないデータのことですね。そして最後に「形状」です。これは物体の「見た目や衝突範囲」を決めます。
![]()
【Hiroki】
ボディと形状が分かれているのは、どうしてですか?
![]()
【Yuki】
いい質問ですね……。例えば、同じ「1kgの重さ(ボディ)」でも、それが「丸いボール」なのか「四角い箱」なのかで、転がり方やぶつかり方が変わりますよね? だから、物理データとしてのボディに、形としての形状を付け加える……という手順を踏むんです。
![]()
【Hiroki】
なるほど!なんとなくイメージが湧いてきました。
![]()
【Yuki】
少し具体的なコードを見てみましょうか。まずは、重力のある世界を作って、そこにボールを一つ落としてみるプログラムを考えてみますね。
最初のステップ:重力のある世界と落ちるボール
![]()
【Yuki】
基本的な構造を書いてみました。少し長いかもしれませんが、ゆっくり見ていけば大丈夫ですよ。
import pygame
import pymunk
def main():
# Pygameの初期設定
pygame.init()
screen = pygame.display.set_mode((600, 600))
clock = pygame.time.Clock()
# 1. 物理宇宙(Space)の作成
space = pymunk.Space()
space.gravity = (0, 900) # 下向きに重力を設定
# 2. ボディ(Body)の作成:質量1, 慣性モーメントは自動計算
mass = 1
radius = 20
moment = pymunk.moment_for_circle(mass, 0, radius)
body = pymunk.Body(mass, moment)
body.position = (300, 100) # 画面中央の少し上
# 3. 形状(Shape)の作成:円形
shape = pymunk.Circle(body, radius)
shape.elasticity = 0.8 # 跳ね返り係数
shape.friction = 0.5 # 摩擦係数
# 宇宙にボディと形状を追加
space.add(body, shape)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 物理演算の時間を進める(1/60秒ずつ)
space.step(1/60.0)
# 描画処理
screen.fill((255, 255, 255)) # 背景を白に
# ボールの位置を取得して描画
pos = body.position
pygame.draw.circle(screen, (0, 150, 255), (int(pos.x), int(pos.y)), radius)
pygame.display.flip()
clock.tick(60)
pygame.quit()
if __name__ == "__main__":
main()
![]()
【Hiroki】
わあ、意外とシンプルですね! space.gravity = (0, 900) で重力を決めているのはわかります。でも、space.step(1/60.0) っていうのは何ですか?
![]()
【Yuki】
それは、物理世界の時計を少しだけ進めるという命令です。物理演算は、一瞬の計算を積み重ねることで動きを作っています。ここでは1/60秒後の世界を計算し続けている、ということになりますね。
![]()
【Hiroki】
なるほど。パラパラ漫画みたいに、少しずつ計算して描画しているんですね。でも、これだとボールが画面の下に消えていっちゃいませんか?
![]()
【Yuki】
ふふ、その通りです。まだ「地面」を作っていませんから……。今のままだと、ボールは無限に落ち続けてしまいます。次は地面を追加して、ボールが跳ね返るようにしてみましょう。
地面(静的ボディ)の追加と衝突の仕組み
![]()
【Yuki】
地面のように「動かない物体」を作るには、「静的ボディ(Static Body)」を使います。先ほどのコードの space.add(body, shape) の前に、こんなコードを追加してみてください。
# 地面の作成(動かないボディ)
static_body = space.static_body
ground_segment = pymunk.Segment(static_body, (0, 500), (600, 500), 5)
ground_segment.elasticity = 0.5
ground_segment.friction = 1.0
space.add(ground_segment)
![]()
【Hiroki】
space.static_body ……。自分では動かないけれど、他のものがぶつかるための体、という感じですね。
![]()
【Yuki】
はい、よく理解されていますね。pymunk.Segment は「線分」を作る命令です。ここでは画面の横幅いっぱいに線を引いています。これを追加して実行すると、ボールが地面に当たって、可愛らしく跳ねるはずですよ。
![]()
【Hiroki】
本当だ!跳ねました! elasticity の値を変えると、跳ね方が変わるのも面白いですね。
![]()
【Yuki】
そうなんです。elasticity(弾力性)を1.0にすると、エネルギーを失わずにずっと跳ね続けます。逆に0にすると、地面にべちゃっとくっつくような動きになります。……物理法則を自分の手でコントロールできるのは、なんだか神様になったみたいで、少しだけドキドキしませんか?
![]()
【Hiroki】
わかります。自分だけの世界を作っている感じがします。でも、もっとたくさんの物体を出したいときは、どうすればいいんでしょう?
大量の物体を管理する:リストとループの活用
![]()
【Yuki】
たくさんのボールを降らせたいときは、Pythonの「リスト」を使うのが一番です。ボールを作る処理を関数にまとめて、それを何度も呼び出すようにすればいいんです。
![]()
【Hiroki】
なるほど。一つずつ変数を作るのは大変ですもんね。
![]()
【Yuki】
ええ、例えばこんな風に書いてみるのはどうでしょうか……。
balls = []
def create_ball(space, pos):
mass = 1
radius = 15
moment = pymunk.moment_for_circle(mass, 0, radius)
body = pymunk.Body(mass, moment)
body.position = pos
shape = pymunk.Circle(body, radius)
shape.elasticity = 0.8
shape.friction = 0.5
space.add(body, shape)
return shape
# ループ内での描画
for ball_shape in balls:
pos = ball_shape.body.position
pygame.draw.circle(screen, (0, 150, 255), (int(pos.x), int(pos.y)), 15)
![]()
【Hiroki】
これなら、マウスクリックした場所にボールを生成する、なんてこともできそうですね!
![]()
【Yuki】
そうですね、素晴らしいアイデアだと思います。Pygameのマウスイベントを取得して、その座標を create_ball に渡してあげれば、クリックするたびにボールが溢れ出すシミュレーションが作れます。……たくさんのボールが重なり合って動く様子は、ずっと見ていても飽きないかもしれません。
物理演算をより深く理解するために
![]()
【Hiroki】
Yukiさん、物理演算って思ったより身近というか、プログラミングでこんなに簡単に再現できるものなんですね。
![]()
【Yuki】
ええ。でも、実は裏側では複雑な積分計算が行われているんです……。Pymunkのようなライブラリは、それを私たちに隠して、直感的な操作だけをさせてくれています。……感謝しないといけませんね。
![]()
【Hiroki】
本当にそうですね。もっと複雑な形、例えば多角形とかも作れるんですか?
![]()
【Yuki】
はい、pymunk.Poly を使えば、どんな形の多角形でも作れますよ。ただし、凸多角形(へこみのない形)である必要がある……というちょっとしたルールもあります。もし複雑な形を作りたいなら、小さな部品を組み合わせて一つのボディに持たせる、というテクニックも使われます。
![]()
【Hiroki】
奥が深そうです……。他にも学んでおくべきことはありますか?
![]()
【Yuki】
そうですね……。「摩擦(Friction)」と「減衰(Damping)」についても調べてみると面白いかもしれません。空気抵抗のようなものをシミュレートしたいときは、スペース全体の damping という値を設定することで、少しずつ物体の動きを鈍くすることもできるんです。
![]()
【Hiroki】
摩擦や空気抵抗……。現実の世界にどんどん近づいていく感じがして、ワクワクします!
![]()
【Yuki】
ふふ、そのワクワクする気持ちを大切にしてください。……わたしは、こうしてプログラムの中で法則に従って動く彼らを見ていると、なんだか安心するんです。あらかじめ決められたルールの中で、一生懸命に動いている姿が……。
![]()
【Hiroki】
Yukiさん……?
![]()
【Yuki】
あ、すみません。少しぼーっとしてしまいました……。ええと、参考になるサイトもいくつか教えておきますね。もしもっと詳しく知りたくなったら、覗いてみてください。
![]()
【Hiroki】
ありがとうございます!まずは、さっきのコードにマウスクリックでボールを出す機能を追加してみます。
![]()
【Yuki】
はい、ぜひ挑戦してみてください。もしエラーが出て困ったり、動きが変だったりしたら、いつでも聞いてくださいね。……夜は長いですから、ゆっくり取り組んでいきましょう。
まとめ:Pythonで物理演算を学ぶ意義
![]()
【Yuki】
物理演算は、単に「物を動かす」だけでなく、数学や物理学がどうプログラミングに活かされているかを知るための、とても良い教材だと思います……。
![]()
【Hiroki】
そうですね。学校で習う物理の公式が、こうして画面の中で動く力になっているのを見ると、勉強の見え方も変わってきそうです。
![]()
【Yuki】
ええ、きっとそうだと思います。……あ、でも、あんまり熱中しすぎて、明日の学校に遅刻しないように気をつけてくださいね? わたしは……もう少しだけ、この仮想世界の星(ドット)たちを眺めてから休むことにします。
![]()
【Hiroki】
はい!今日はありがとうございました、Yukiさん。おやすみなさい!
![]()
【Yuki】
おやすみなさい、Hirokiくん。……良い夢を。
この記事では基礎を解説しましたが、実務においては「もっと複雑なデータを扱いたい」「独自のシステムに組み込みたい」といった、個別の課題に直面することも多いはずです。
「自分で書く時間は最小限に抑え、プロの品質でツールを完成させたい」という方は、ぜひ一度ご相談ください。
- 専門家の知見に基づいた、保守性の高いコード設計
- AIの専門家による、Gemini API等の最新AIを組み合わせた高度な自動化
- ChatGPT等が生成したコードのデバッグ・最適化
「教わる」だけでなく「形にする」パートナーとして、フリーランスエンジニアのmei_13が最短ルートでの解決をサポートします。
初心者から始められるPythonレッスン
● 月額4,000円で質問し放題!!
● 完全オンライン
● 翌日までには必ず返信
● 挫折しない独自の学習メソッド
● 圧倒的高評価!!
● テキストベースで時間を選ばない
● 4,000円/60分の伴走型ビデオチャット指導も可能
● 高品質なサンプルコード
詳細はこちら

