0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C言語の復習がてら、ゲームに応用してみる Part4

Posted at

#はじめに
この記事は、私の投稿している「C言語の復習がてら、ゲームに応用してみる」のPart4である。最初から見たいという方はこちらから

#目には目を、弾には当たり判定を
さて、今度は弾の当たり判定についてを考えよう。
弾の生成や移動に関してはpart3の知識で同じように理解できると思う。
では、当たり判定についてだ。一番簡単な考え方としては、弾が敵の中に食い込んだ時あたりという判定にする方法だ。
実際にコードを見ていこう。

//弾の数
#define PLAYER_SHOT_NUM 200

//弾の座標
int shot_x[PLAYER_SHOT_NUM],shot_y[PLAYER_SHOT_NUM];

//敵が出現しているかのフラグ
int enemy_flag[ENEMY_NUM_I][ENEMY_NUM_J]


/*省略:for文を使って弾の座標設定・敵のフラグの設定(初期値:1)*/

for (int enemy_i = 0; enemy_i < ENEMY_NUM_I; enemy_i++) {
      for (int enemy_j = 0; enemy_j < ENEMY_NUM_J; enemy_j++) {

                    /*~~~~省略:敵に関する処理~~~~*/

                    /******弾とのあたり判定*****/
                    for (int shotf_i = 0; shotf_i < PLAYER_SHOT_NUM; shotf_i++) {
                        if (player_shot_x[shotf_i] + SHOT_SIZE > enemy_x[enemy_i][enemy_j]  && player_shot_x[shotf_i] < enemy_x[enemy_i][enemy_j] +OBJECT_SIZE)
                            if (player_shot_y[shotf_i] < enemy_y[enemy_i][enemy_j] + OBJECT_SIZE){
                                enemy_flag[enemy_i][enemy_j] = 0;//敵を消す
                            }
                    }

                    //フラグが立っている敵のみ描画する。
                    if (enemy_flag[enemy_i][enemy_j] == 1)
                       DrawGraph(enemy_x[enemy_i][enemy_j], enemy_y[enemy_i][enemy_j], enemy_imgbuf, TRUE);

    }
}

以上がコードだ。弾との当たり判定は先ほど言った通りだが、これをコードに起こすには弾と敵との座標がどうなっているかを考える必要がある。
状況として、食い込んでいる=
弾の左端の座標が敵の右端の座標より小さい」または「弾の右側の座標が敵の左側の座標より大きい
という状況、かつ
弾の上側の座標が敵の下側の座標より小さい」または「弾の下側の座標が敵の上側の座標より大きい
という状況だ。」
これをif文で書いたものがコードとなる。
少しわかりづらいが2つのif文と2つずつの条件からできているのがわかる。一度わからない場合には紙に書いてみることをお勧めする。

わかりやすくまとめるべきだ。

また、これまでやってきたがある程度まとまった処理なんかは関数を別に作るべきである。

//プレイヤーのキー操作+はみ出し防止
void Player_KeyOperation() {

    int movex = 0;
    
    switch (CheckHitKeyAll()) {
    case KEY_INPUT_RIGHT://右
        movex = 3;
        break;
    
    case KEY_INPUT_SPACE:
        for (int shotf_i = 0; shotf_i < PLAYER_SHOT_NUM; shotf_i++)
            if(player_shot_interval == 0)
                if(player_shot_flag[shotf_i] == 0){//空いている弾を探す
                    player_shot_flag[shotf_i] = 1;
                    player_shot_x[shotf_i] = player_x + OBJECT_SIZE / 2 - 10;
                    player_shot_y[shotf_i] = player_y - OBJECT_SIZE     + 20;
                    player_shot_interval++;
                }
        break;
    }

    player_x += movex;
}

これは、プレイヤーのキー操作と画面からのはみだしをまとめたものだ。もっとも細かくすることももっと大きなくくりにすることもできる。そこは自分のコードを書いている際に判断してほしい。

最後に

説明が少し雑だった気がしてなんだか申し訳ない。もっと説明すべきこともあったのかもしれないが、今の文章力と能力ではこの程度が私の限界である。まことに申し訳ない。わからないことやコードに関してより詳しい説明が必要な場合はコメントをいただきたい。もしかしたら続くかもしれない。
ここまで読んでいただき本当にありがとう。これを機にもっとプログラムをやってみたい人ぜひ一緒に頑張ろう!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?