弾幕の作り方:放射・自機狙い・雨・渦巻き・追尾の仕組みを、計算式と動く見本で解説
弾幕メーカー 開発の記録 / 2026年11月
弾幕シューティングの弾幕は、見た目は複雑でも、ひとつひとつは短い計算式でできています。この記事は、私が作っている弾幕ゲーム「弾幕メーカー」で実際に使っている式を、そのまま書き出して、動く見本で確かめられるようにしたものです。弾幕を自分で作りたい人、ゲームで弾幕を組みたい人向けです。
式は、アプリの弾の計算(DanmakuCore の Simulation.swift と AdPatterns.swift)から写しました。見本は、その式を JavaScript に移したもので、画面の自機は指やマウスを置いた所へ動きます(当たり判定はしません)。自機の上の白い小さな円が、ゲームの当たり判定の大きさです。
弾幕は「発射台」と、4 つの数でできている
弾幕メーカーでは、弾を撃つ場所を発射台と呼び、1 ステージに最大 8 個まで置けます。発射台ごとに決めるのは、ほぼ次の 4 つです。
| 記号 | 意味 | 単位 |
|---|---|---|
i | 発射の間隔 | 秒(0.05〜2) |
c | 1 回に出す弾の数 | 個(1〜36) |
v | 弾の速さ | ×60 px/秒(1〜5) |
r | 角度(パターンによって、回転・広がり・振れ幅の意味になる) | 度 |
画面は 360×540 の大きさで計算し、1/120 秒ずつ進めます。k 回目の発射で、j 番目の弾(0 から c−1)を、角度 θ の向きに、速さ v × 60 で出す。弾は、出たあとはまっすぐ進むだけです(追尾など、一部を除く)。弾幕の形は、ほとんど「出す瞬間の角度の決め方」で決まります。
放射:円の上に、等しい間隔で並べる
いちばん基本の弾幕です。c 発を、円を等分した向きに出します。
θ = 2π × j ÷ c + k × r°
r = 0 なら、毎回同じ向きに出るので、輪が同心円で広がります。下の見本は 16 発・1 秒おきです。
輪と輪の間をくぐるのが、避け方の基本です。弾の数を増やすほど、すき間は狭くなります。
回る放射と、本当の渦巻きは、別物
放射の r を 0 以外にすると、発射のたびに全体が r 度ずつ回ります。間隔を短く(0.12 秒)、弾を少なく(3 発)すると、弾の列が渦の腕のように見えます。
ただし、ひとつひとつの弾は、まっすぐ飛んでいます。渦に見えるのは、出す向きが少しずつずれているからです。弾幕メーカーも、はじめはこれを「渦巻き」と呼んでいました。
あとから、弾そのものが曲がる、本当の渦巻きを足しました。出たあと 8 秒のあいだ、毎秒 30° ずつ、同じ向きに向きを変えます。
見比べると、回る放射は外へ行くほど腕がまっすぐに開き、本当の渦巻きは外へ行っても腕が巻き続けます。避け方も違います。回る放射は「腕と腕の間」に入ればよく、本当の渦巻きは、腕が自分のほうへ回り込んできます。
古い「渦巻き」は、計算を変えると、すでに投稿されたステージの動きが変わってしまいます。そのため、計算はそのまま残して、エディタの選択肢からだけ外し、新しい渦巻きを別のパターンとして足しました。
自機狙い:奇数弾と偶数弾で、避け方が真逆になる
撃つ瞬間の自機の位置を向き、その左右に r 度の扇を広げます。
b = atan2(自機y − 発射台y, 自機x − 発射台x)θ = b + (j ÷ (c−1) − 0.5) × r°
ここで、弾の数が奇数か偶数かで、性質が真逆になります。
- 奇数(5 発など):真ん中の弾(
j = (c−1)÷2)の角度がちょうどbになり、自機の今いる場所へまっすぐ飛んできます。止まっていると当たります。少しずつ横へ動き続けるのが基本です。 - 偶数(6 発など):真ん中に弾がなく、自機の今いる場所が、ちょうどすき間になります。止まっていれば避けられ、慌てて動くと当たります。
見本で、自機を止めてみると違いが分かります。弾幕を作るときは、奇数と偶数を混ぜると、「動く」と「止まる」の判断を迫れます。
雨:画面の上から、ばらばらに降らせる
発射台の位置は使わず、画面の上端の、ランダムな横位置から、ほぼ真下に出します。向きは真下から ±0.15 ラジアン(約 ±8.6°)だけ、ばらつかせています。
x = 乱数 × 360、y = −8、θ = 90° + (乱数 − 0.5) × 0.3
ばらばらに見えますが、乱数はステージごとに決まった種から作る(mulberry32)ので、同じステージなら、誰が遊んでも同じ雨が降ります。そうしないと、ランキングで運の良し悪しが勝負を分けてしまいます。
首ふり扇:真下を中心に、ゆっくり首を振る
真下(90°)を中心に、発射のたびに、正弦波で左右へ振ります。扇の広がりは 0.5 ラジアン(約 29°)で固定です。
中心 = 90° + sin(0.25 × k) × r°
0.25 × k の 0.25 を大きくすると首を振るのが速くなり、r を大きくすると振れ幅が広がります。弾の帯が波打つので、帯の「戻ってくる側」を読んで避けます。
追尾:曲がれるのは、最初の 2.5 秒だけ
追尾弾は、毎フレーム、自機の方向へ向きを近づけます。ただし、1 秒に曲がれる角度に上限(max(25°, 2 × |r|°))があり、さらに追うのは出てから 2.5 秒だけです。そのあとは、まっすぐ飛びます。
時間で切らずに追い続けさせると、弾は自機のまわりを回り続け、いつかは必ず当たります。避けようのない弾は、難しいのではなく、ただ理不尽です。「追ってくるけれど、引きつけて横へかわせば外れる」くらいが、遊びとして成り立つ線でした。
当たり判定は、見た目より小さい
弾幕メーカーの当たり判定は、弾の中心と自機の中心の距離が 5.5 px 未満のときです(計算では、距離の 2 乗が 30.25 未満)。弾の色の部分は半径 6 px で描いているので、見た目では「かすった」くらいでは当たりません。弾幕ゲームでは、当たり判定を見た目より小さくするのが一般的で、これがあるから、すき間を抜けるのが楽しくなります。
もう一つ、画面に出せる弾は 1,600 発までにしています。それを超える分は出しません。スマートフォンでも描くのが追いつき、それでも画面がほぼ埋まる数です。
まとめ:弾幕を作るときのコツ
- 形は、出す瞬間の角度で決まる。放射・自機狙い・首ふりは、どれも 1 行の式です。
- 回る放射と、曲がる弾は別物。同じ「渦」に見えても、避け方が違います。
- 自機狙いは、奇数と偶数を使い分ける。奇数は「動け」、偶数は「止まれ」。
- ばらつきは、決まった種の乱数で。同じステージなら同じ弾幕に。
- 追尾には、時間の上限を。避けられない弾は、作らない。
自分で作ってみる
ここに書いた放射・自機狙い・雨の 3 つは、弾幕メーカーのブラウザ版(無料・登録なし)で、そのまま自分の弾幕として組めます。作ったステージは、自分でクリアするとリンクで友達に送れます。渦巻き・首ふり扇・追尾のほか、花・星・レーザー・地雷など、ずっと多くのパターンは、iPhone・iPad 版で使えます。
ほかの記録
- すし積むの番付に載らなくなった:ゲームの数字を変えて、サーバーの検算を直し忘れていた(しかも二つ) — 番付に、普通に遊んでも載らなくなった。ゲームの数字を変えて、サーバーの検算を直し忘れていた。金の桶の褒美(8,000→25,000)と、降るネタ(3種→5種)の二つ。注意書きでは守れず、同じ種で出題を比べる検査を足した。
- ポケカ・トレカ抽選アプリを比較:トレカダッシュ・トレゲト・NowPokeca・Pokeka Tracker・トレカの地図のメリットとデメリット — ポケカをはじめトレカの抽選・予約・再販を追うアプリ・サイトを、ジャンル数・通知・地図・料金で比較。作者(トレカダッシュの開発者)による比較で、トレカダッシュの弱いところも書いた。
- 同じ報告が 3 回目:SwiftUI のボタンが「文字の上でしか」反応しなかった。過去 2 回の「修正」は効いていなかった — 「当選」「落選」ボタンが文字の上しか反応しない報告は 3 回目。過去 2 回は修飾子の順序を直しても効かず、ButtonStyle の中で見た目を組み立てて、6 か所を差し替えた。同じ日の「郵送なのに位置情報」も同じ根っこだった。
コメント
感想や、記事の間違いの指摘は、ここへ。書くには、GitHub のアカウントが要ります。
押すと、giscus(giscus.app)と GitHub に接続します。押さなければ、接続しません。詳しくはプライバシーポリシーに書いています。