C++で自機狙い弾を作りたい。
でも、「どうやって実装すればいいのか分からない」そんな風に感じていませんか。
実は、C++で自機狙い弾を作るには、追尾・角度計算の基本を理解することが重要です。
DirectXやDxLibを使えば、初心者でも自機狙い弾システムを作ることができるでしょう。
この記事では、C++で自機狙い弾を作る方法を、追尾・角度計算の基本とともに詳しく解説します。
✨ この記事でわかること
- C++で自機狙い弾を作る基本(所要30分)
- 追尾処理の実装方法と角度計算の詳細(所要1時間)
- DirectX・DxLibを使った実装コード(所要1時間)
- C++自機狙い弾でよくある失敗5選と解決方法
- 実用的な自機狙い弾システム完成までの4ステップ(合計4時間)

自機狙い弾は、敵と自機の位置から角度を計算して、その方向に弾を発射するのがコツです。atan2関数を使うと簡単に実装できます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
C++で自機狙い弾を作る基本とは?基礎知識から理解する

C++で自機狙い弾を作る基本とは、敵が発射する弾が自機を狙って飛ぶ仕組みのことです。
適切な実装により、面白い敵の攻撃を実現できます。
C++で自機狙い弾を作る基本には、角度計算と弾の移動が重要になります。
角度計算で自機の方向を求め、その方向に弾を発射します。
弾の移動処理で、計算した方向に弾を動かします。
自機狙い弾は、シューティングゲームの難易度を調整する重要な要素です。
適切に実装することで、プレイヤーが避けやすい弾や、避けにくい弾を作れます。
自機狙い弾の仕組み
自機狙い弾の仕組みは、敵の位置と自機の位置から角度を計算し、その方向に弾を発射することです。
発射時の角度を固定することで、発射後は直進する弾になります。
一方、発射後も角度を更新し続けることで、曲がる弾を実現できます。
一般的には、発射時の角度で固定する方が実装が簡単で、多くのシューティングゲームで採用されています。
自機狙い弾に必要な要素
✅ 自機狙い弾に必要な要素
- 角度計算:自機への角度を計算(atan2関数を使用、所要時間:実装1時間)
- 弾の生成:計算した角度で弾を生成(速度ベクトルを設定、所要時間:実装30分)
- 弾の移動:計算した方向に弾を移動(毎フレーム更新、所要時間:実装1時間)
- 弾の管理:複数の弾を管理(配列やリストで管理、所要時間:実装1時間)
角度計算は、atan2関数を使うことで実現できます。
atan2関数は、Y座標の差とX座標の差から角度を計算します。
計算した角度から、速度ベクトルを計算して弾を移動させます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
追尾処理の実装方法

追尾処理の実装方法を解説します。
適切な実装により、正確な自機狙い攻撃を実現できます。
角度計算の実装
角度計算は、atan2関数を使って実装します。
atan2関数は、math.hをインクルードすることで使用できます。
敵の位置と自機の位置の差から、角度を計算します。
atan2関数は、-πからπまでの角度をラジアン単位で返します。
第1引数はY座標の差、第2引数はX座標の差です。
順序を間違えると、角度が正しく計算されないので注意が必要です。
角度を計算する際は、敵の位置を基準に自機の位置への方向を計算します。
dx = playerX – enemyX、dy = playerY – enemyYとして、atan2(dy, dx)を計算します。
この角度は、敵から自機への方向を示します。
速度ベクトルの計算
速度ベクトルは、角度と速度から計算します。
cos関数とsin関数を使って、速度ベクトルを計算します。
計算した速度ベクトルを使って、弾を移動させます。
速度ベクトルのX成分は、速度×cos(角度)で計算します。
速度ベクトルのY成分は、速度×sin(角度)で計算します。
速度の値は、ゲームのバランスに応じて調整します。一般的には、3.0〜8.0の範囲が適切です。
速度ベクトルを計算する際は、角度がラジアン単位であることを確認します。
度単位の角度を使う場合は、ラジアンに変換する必要があります。
変換式は、ラジアン = 度 × π / 180です。
実装のポイント
実装のポイントは、角度計算のタイミングです。
発射時に角度を計算して固定する場合と、毎フレーム角度を更新する場合があります。
発射時に固定する方が実装が簡単で、多くのシューティングゲームで採用されています。
毎フレーム更新する場合は、弾が曲がって飛ぶため、難易度が上がります。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
角度計算の基本

角度計算の基本を解説します。
適切な計算により、正確な自機狙い攻撃を実現できます。
atan2関数の使い方
atan2関数は、2つの引数を取り、角度を返します。
第1引数はY座標の差、第2引数はX座標の差です。
返される角度は、ラジアン単位で、-πからπまでの範囲です。
atan2関数は、象限を自動的に考慮するため、atan関数よりも使いやすくなっています。
atan関数を使うと、象限の判定が必要になりますが、atan2関数を使うことで、その必要がなくなります。
atan2関数の引数の順序に注意が必要です。
第1引数がY座標の差、第2引数がX座標の差です。
順序を間違えると、角度が90度ずれてしまいます。
正しい順序は、atan2(dy, dx)です。
角度から速度ベクトルへの変換
角度から速度ベクトルへ変換するには、cos関数とsin関数を使います。
速度ベクトルのX成分は、速度×cos(角度)で計算します。
速度ベクトルのY成分は、速度×sin(角度)で計算します。
これにより、角度の方向に速度の大きさで移動するベクトルが得られます。
速度ベクトルを計算する際は、速度の値を適切に設定することが重要です。
速度が速すぎると、弾が避けにくくなりすぎます。
速度が遅すぎると、弾が避けやすくなりすぎます。
一般的には、プレイヤーの移動速度の1.5〜2倍程度が適切です。
実装例:基本的な角度計算
以下は、基本的な角度計算の実装例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include // 敵と自機の座標 float enemyX = 100.0f; float enemyY = 100.0f; float playerX = 320.0f; float playerY = 240.0f; // 角度を計算 float dx = playerX - enemyX; float dy = playerY - enemyY; float angle = atan2f(dy, dx); // 速度ベクトルを計算(速度は5.0とする) float speed = 5.0f; float vx = speed * cosf(angle); float vy = speed * sinf(angle); |
|
1 |
このコードにより、敵から自機への方向に速度5.0で移動するベクトルが得られます。
このベクトルを使って、弾を移動させることができます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
DirectXを使った自機狙い弾の実装

DirectXを使った自機狙い弾の実装方法を解説します。
DirectXを使うことで、Windows向けのゲーム開発が可能になります。
弾の構造体定義
まず、弾を管理するための構造体を定義します。
構造体には、座標、速度ベクトル、有効フラグを含めます。
|
1 2 3 4 5 6 7 8 9 |
struct Bullet { float x, y; // 弾の座標 float vx, vy; // 弾の速度ベクトル bool active; // 弾が有効かどうか }; const int MAX_BULLETS = 100; Bullet bullets[MAX_BULLETS]; |
この構造体を使って、複数の弾を管理できます。
MAX_BULLETSは、同時に存在できる最大の弾数を表します。
必要に応じて、この値を調整します。
自機狙い弾の発射処理
自機狙い弾の発射処理を実装します。
発射時に、敵の位置と自機の位置から角度を計算し、速度ベクトルを設定します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
void FireBullet(float enemyX, float enemyY, float playerX, float playerY) { // 空いている弾を探す for (int i = 0; i < MAX_BULLETS; i++) { if (!bullets[i].active) { // 角度を計算 float dx = playerX - enemyX; float dy = playerY - enemyY; float angle = atan2f(dy, dx); // 速度ベクトルを計算 float speed = 5.0f; bullets[i].vx = speed * cosf(angle); bullets[i].vy = speed * sinf(angle); // 弾の初期位置を設定 bullets[i].x = enemyX; bullets[i].y = enemyY; bullets[i].active = true; break; // 1発だけ発射 } } } |
この関数により、敵から自機に向かって弾を発射できます。
発射する際は、空いている弾のスロットを探して使用します。
全ての弾が使用中の場合は、新しい弾を発射できません。
弾の移動処理
弾の移動処理を実装します。
毎フレーム、全ての有効な弾に対して移動処理を実行します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void UpdateBullets() { for (int i = 0; i < MAX_BULLETS; i++) { if (bullets[i].active) { // 弾を移動 bullets[i].x += bullets[i].vx; bullets[i].y += bullets[i].vy; // 画面外に出たら無効化 if (bullets[i].x < 0 || bullets[i].x > 640 || bullets[i].y < 0 || bullets[i].y > 480) { bullets[i].active = false; } } } } |
この関数により、弾が移動し、画面外に出た弾が自動的に無効化されます。
画面のサイズは、ゲームに応じて調整します。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
DxLibを使った自機狙い弾の実装

DxLibを使った自機狙い弾の実装方法を解説します。
DxLibは、DirectXを簡単に使えるライブラリです。
DxLibでの実装例
DxLibを使うと、描画処理が簡単になります。
以下のコードで、自機狙い弾のシステムを実装できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
#include "DxLib.h" #include struct Bullet { float x, y; float vx, vy; bool active; }; const int MAX_BULLETS = 100; Bullet bullets[MAX_BULLETS]; float enemyX = 100.0f; float enemyY = 100.0f; float playerX = 320.0f; float playerY = 240.0f; void InitBullets() { for (int i = 0; i < MAX_BULLETS; i++) { bullets[i].active = false; } } void FireBullet() { for (int i = 0; i < MAX_BULLETS; i++) { if (!bullets[i].active) { float dx = playerX - enemyX; float dy = playerY - enemyY; float angle = atan2f(dy, dx); float speed = 5.0f; bullets[i].x = enemyX; bullets[i].y = enemyY; bullets[i].vx = speed * cosf(angle); bullets[i].vy = speed * sinf(angle); bullets[i].active = true; break; } } } void UpdateBullets() { for (int i = 0; i < MAX_BULLETS; i++) { if (bullets[i].active) { bullets[i].x += bullets[i].vx; bullets[i].y += bullets[i].vy; if (bullets[i].x < 0 || bullets[i].x > 640 || bullets[i].y < 0 || bullets[i].y > 480) { bullets[i].active = false; } } } } void DrawBullets() { for (int i = 0; i < MAX_BULLETS; i++) { if (bullets[i].active) { DrawCircle(bullets[i].x, bullets[i].y, 5, GetColor(255, 255, 0), TRUE); } } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { if (DxLib_Init() == -1) return -1; InitBullets(); int fireTimer = 0; const int FIRE_INTERVAL = 60; // 1秒ごとに発射 while (ProcessMessage() == 0) { ClearDrawScreen(); // プレイヤーの位置をマウスで制御(テスト用) GetMousePoint(&playerX, &playerY); // 定期的に弾を発射 fireTimer++; if (fireTimer >= FIRE_INTERVAL) { FireBullet(); fireTimer = 0; } UpdateBullets(); DrawBullets(); // 敵とプレイヤーも描画 DrawCircle(enemyX, enemyY, 15, GetColor(255, 0, 0), TRUE); DrawCircle(playerX, playerY, 10, GetColor(0, 255, 0), TRUE); ScreenFlip(); } DxLib_End(); return 0; } |
|
1 |
このコードにより、敵が自機に向かって弾を発射するシステムが完成します。
マウスを動かすと、プレイヤーの位置が変わり、弾がその方向に発射されます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
C++自機狙い弾でよくある失敗5選と解決方法

C++自機狙い弾で、初心者が陥りやすい失敗があります。
ここでは、5つのよくある失敗と解決方法を紹介します。
失敗1:atan関数を使っている
❌ よくある失敗
- atan関数を使っている
- 角度が正しく計算されない
- 象限が考慮されていない
- 角度が90度ずれる
atan関数を使うと、象限の判定が必要になります。
また、X座標の差が0の場合にエラーが発生する可能性があります。
atan2関数を使うことで、これらの問題を回避できます。
✅ 正しいアプローチ
- atan2関数を使う
- Y座標差とX座標差を正しい順で渡す
- 象限を自動的に考慮する
- X座標の差が0でも正しく動作する
失敗2:角度の単位が間違っている
角度の単位を間違えると、速度ベクトルが正しく計算されません。
atan2関数はラジアン単位で角度を返しますが、度単位で計算している場合があります。
また、cos関数とsin関数もラジアン単位の角度を想定しています。
解決方法:
- ラジアン単位で計算する
- 度単位が必要な場合は、ラジアンに変換する(ラジアン = 度 × π / 180)
- 単位を統一する
- atan2関数の戻り値は既にラジアン単位なので、そのまま使用する
失敗3:速度ベクトルの計算が間違っている
速度ベクトルの計算で、cos関数とsin関数の引数の順序を間違えることがあります。
また、角度から速度ベクトルを計算する際に、速度の値を掛け忘れることもあります。
⚠️ よくあるエラー
- 弾が動かない → 速度ベクトルの計算を確認(速度の値を掛けているか)
- 弾が間違った方向に飛ぶ → cos関数とsin関数の引数を確認
- 弾の速度が一定でない → 速度の値を固定する
失敗4:画面外の弾を削除しない
画面外に出た弾を削除しないと、メモリを無駄に消費します。
また、画面外の弾も処理し続けるため、パフォーマンスが低下します。
解決方法:
- 画面外に出た弾を無効化する
- 画面の範囲をチェックして、範囲外の弾を削除する
- 定期的に無効な弾をクリーンアップする
失敗5:ゼロ除算エラーが発生する
敵の位置と自機の位置が同じ場合、dxとdyが0になり、角度の計算で問題が発生する可能性があります。
また、距離を計算する際にゼロ除算が発生する可能性があります。
⚠️ 解決方法
- 敵と自機の距離が0でないことを確認する
- 距離が小さい場合は、デフォルトの角度を使用する
- ゼロ除算チェックを追加する
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
実用的な自機狙い弾システム完成までの4ステップ

- STEP1角度計算の実装(所要1時間)
敵と自機の位置から角度を計算する処理を実装する。
atan2関数を使って、自機への角度を計算する。
学べること:atan2関数、角度計算
成果物:角度を計算できるシステム
- STEP2速度ベクトルの計算(所要30分)
角度から速度ベクトルを計算する処理を実装する。
cos関数とsin関数を使って、速度ベクトルを計算する。
学べること:ベクトル計算、三角関数
成果物:速度ベクトルを計算できるシステム
- STEP3弾の生成と移動(所要1時間)
角度と速度ベクトルを使って、弾を生成して移動させる処理を実装する。
学べること:オブジェクト管理、移動処理
成果物:弾が移動するシステム
- STEP4最適化と調整(所要1時間30分)
画面外の弾を削除し、ゲームバランスを調整する。
学べること:メモリ管理、ゲームバランス調整
成果物:実用的な自機狙い弾システム
合計4時間で、実用的な自機狙い弾システムが完成します。
実装時のチェックリスト
✅ 実装時のチェックリスト
- atan2関数を使っているか(atan関数ではない)
- 角度の単位がラジアンであることを確認しているか
- 速度ベクトルの計算が正しいか(cos関数とsin関数の引数)
- 画面外の弾を削除しているか
- ゼロ除算エラーのチェックを追加しているか
- 弾の速度が適切か(プレイヤーの移動速度の1.5〜2倍程度)
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
まとめ

C++で自機狙い弾を作るには、追尾・角度計算の基本を理解することが重要です。
適切な実装により、面白い敵の攻撃を実現できるでしょう。
✅ 記事の要点まとめ
- 自機狙い弾の基本:角度計算、弾の移動、atan2関数の使用
- 追尾処理:角度計算、速度ベクトルの計算、実装のポイント
- 角度計算:atan2関数の使い方、角度から速度ベクトルへの変換
- DirectX・DxLib実装:構造体定義、発射処理、移動処理
- よくある失敗5選:atan関数の使用、単位の間違い、速度ベクトルの計算ミスなど
- 実用的なシステム:4ステップで完成(合計4時間)
今日から始める3ステップ:
- STEP1:角度計算を実装する(所要1時間)
- STEP2:弾の生成処理を実装する(所要30分)
- STEP3:弾の移動処理を実装する(所要1時間)
あなたのペースで、少しずつ進めていけば大丈夫です。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる



コメント