Appearance
第05回 弾を撃つ
前回: 第04回 構造体と矩形 / 次回: 第06回 敵と衝突判定
今回の授業内容
- 弾を表す構造体を追加する
- 固定配列で複数の弾を管理する
- 有効フラグで使用中と空きを区別する
- ショットキーで弾を発射する
- 画面外へ出た弾を無効化して再利用する
今回の開始状態
第04回終了時点では、プレイヤーが移動し、当たり判定の矩形を確認できます。
今回の終了時点では、ZまたはSpaceで弾を撃てるようにします。
まだBulletクラスは作りません。
第05回では、Game内に弾用の構造体と配列を置いて、まず固定配列管理の流れを理解します。
変更するファイル
| ファイル | 変更内容 |
|---|---|
Game.h | Bullet構造体、弾配列、連射間隔を追加する |
Game.cpp | 発射、更新、描画、無効化を追加する |
弾のデータを用意する
Game.hに、弾を表す構造体を追加します。
cpp
struct Bullet
{
Vec2 position;
float speed;
bool active;
};続けて、Gameクラスに弾の配列を追加します。
cpp
static constexpr int maxBullets = 48;
Bullet bullets[maxBullets] = {};
int shotCooldown = 0;配列の要素は最初から48個あります。
画面上で使っている弾だけをactive == trueとして扱います。
弾を発射する
Update()の中で、ショットキーが押されていて、連射待ちが終わっているかを確認します。
cpp
if ((input.IsDown(KEY_INPUT_Z) || input.IsDown(KEY_INPUT_SPACE)) && shotCooldown <= 0)
{
SpawnBullet();
shotCooldown = 8;
}
if (shotCooldown > 0)
--shotCooldown;SpawnBullet()では、空いている弾を探して初期値を入れます。
cpp
void Game::SpawnBullet()
{
for (Bullet& bullet : bullets)
{
if (!bullet.active)
{
bullet.position = { playerPosition.x, playerPosition.y - 22.0f };
bullet.speed = 8.0f;
bullet.active = true;
return;
}
}
}空きがない場合は何も発射しません。
これは不具合ではなく、同時に出せる弾の上限に達したという仕様です。
弾を更新して描画する
更新では、使っていない弾を飛ばし、使っている弾だけ上へ動かします。
cpp
for (Bullet& bullet : bullets)
{
if (!bullet.active)
continue;
bullet.position.y -= bullet.speed;
if (bullet.position.y < -16.0f)
bullet.active = false;
}描画も同じように、activeな弾だけを描きます。
cpp
for (const Bullet& bullet : bullets)
{
if (!bullet.active)
continue;
DrawBox(
static_cast<int>(bullet.position.x - 3),
static_cast<int>(bullet.position.y - 10),
static_cast<int>(bullet.position.x + 3),
static_cast<int>(bullet.position.y + 10),
yellow,
TRUE
);
}動作確認
- ZまたはSpaceで弾が出ることを確認する
- 弾が上方向へ移動することを確認する
- 画面外へ出た弾が消えることを確認する
maxBulletsを3へ変更し、画面内に3発残っている間は新しい弾が出ないことを確認する- 確認後、
maxBulletsを48へ戻す
よくある問題
- 弾が1発しか出ない場合は、空き弾を探すループと
activeの切り替えを確認する - 弾が消えない場合は、画面外で
active = falseに戻しているか確認する - 連射が速すぎる場合は、
shotCooldownの値を確認する
今回の完成条件
- 固定配列で複数の弾を管理できる
- 有効フラグの役割を説明できる
- ショットキーで弾を発射できる
- 画面外へ出た弾を無効化できる
まとめ
今回は、固定配列と有効フラグで複数の弾を扱いました。
次回は敵を追加し、弾との衝突でスコアを増やします。