C言語 入門 STGの作り方

七日目 敵ショットを表示

初心者向けSTG作成入門

HOME/STGの作り方 目次/七日目 敵ショットを表示/

広告

↓2016年02月29日発売↓

12歳からはじめる ゼロからのC言語 ゲームプログラミング教室

新品価格
¥2,462から
(2016/5/10 22:16時点)

もっと!C、C++言語本

目次へ戻る

敵ショットを表示

今回は敵ショットを表示させてみます。

敵ショットの構造体から見てみましょう。

struct ENEMY_SHOT{
	double first_x;
	double first_y;
	double x[10];
	double y[10];
	double draw_x[10];
	double draw_y[10];
	double angle[10];
	int init_flag;
	int move_flag;
	int move_type;
	int max_bullet;
	int gamecount_point[5];
	double range;
	int enemy_no;
};

struct ENEMY_SHOT enemy_shot[DISP_ENEMY_MAX * 2];

今までやってきた敵の構造体などとほとんど一緒ですね!

わかりやすいトコロから見てみましょう。

double first_x;
double first_y;
double x[10];
double y[10];
double draw_x[10];
double draw_y[10];

計算座標「x,y」と表示する時の座標「draw_x,draw_y」そして初期位置の座標「first_x,first_y」ですね。

連射する弾などもあるので座標は「10」個ぐらい用意しておきます。

double angle[10];

好きな方向に飛ばしたい時に指定する角度です。

int init_flag;
int move_flag;
int move_type;

初期化用のフラグ、「敵ショットの入れ物」が使用中かどうかのフラグ、ショットの動き方。

int max_bullet;

こちらはプレイヤーの時にもありましたね、一度に飛ばすショットの最大弾数になります。

int gamecount_point[5];
double range;

あとは基準の「gamecount」の記録用と当たり判定の範囲ですね。

int enemy_no;

こちらは連射ショットを打っている敵がいた時、その敵はどの敵なのかを判別する為の変数なのですが、今の時点ではわかりづらいので連射ショットを実際作る時まではあまり気にしないでください。

struct ENEMY_SHOT enemy_shot[DISP_ENEMY_MAX * 2];

そして敵ショットは敵の消滅するタイミングなどと少しずれたりするので少し多めに敵の数の2倍ぐらい用意しておきます。

敵の時と同じように、これが「敵ショットの入れ物」となりこの構造体の数が「同時に画面に表示できる敵ショットの最大数」になります。

初期化

初期化します。

void my_init_enemy_shot(){
	for (int i = 0; i < DISP_ENEMY_MAX * 2; i++){
		enemy_shot[i].first_x = 0;
		enemy_shot[i].first_y = 0;
		enemy_shot[i].init_flag = 0;
		enemy_shot[i].move_flag = 0;
		enemy_shot[i].move_type = 0;
		enemy_shot[i].max_bullet = 0;
		enemy_shot[i].range = 10;
		enemy_shot[i].enemy_no = 0;
		for(int j = 0;j < 10;j++){
			enemy_shot[i].x[j] = 0;
			enemy_shot[i].y[j] = 0;
			enemy_shot[i].draw_x[j] = 0;
			enemy_shot[i].draw_y[j] = 0;
			enemy_shot[i].angle[j] = 0;
		}
		for(int j = 0;j < 5;j++){
			enemy_shot[i].gamecount_point[j] = 0;
		}
	}
}

当たり判定範囲の「range」は全て「10」残りは全て「0」で初期化しております。

敵ショットを表示する流れ

プレイヤーショットの時は発射ボタンを押す事によって「move_flag」を起動しました。

敵の時は登場するポイントである「appear_point」に差し掛かった時に「move_flag」を起動しました。

では敵ショットはどのように「move_flag」を起動するのかと言いますと「敵自身が移動する動き」の中で敵ショットを起動します。

それを踏まえて敵ショットを表示するまでの流れを見てみましょう。

1・「敵の動き」の中で敵ショットを発射する

2・敵ショットが発射された時に現在未使用の「敵ショットの入れ物」を調べて使用中に

3・その時の「敵ショットの動き方」などを「敵ショットの入れ物」に登録

4・その「敵ショットの動き方」に応じて出現・計算・表示

5・終わったら再び「敵ショットの入れ物」を未使用に

最初の部分が違うだけでやはりほとんど変わらない流れですね。

ではまずは「敵の動き」に敵ショット発射を加えてみましょう。

敵ショット起動!

前回作った単純な「敵の動き」に敵ショット起動を加えてみます。

if (gamecount < enemy[i].gamecount_point + 500){
 if (gamecount < enemy[i].gamecount_point + 220){
  enemy[i].y--;
 }
 if (gamecount == enemy[i].gamecount_point + 240){
  my_set_enemy_shot(enemy[i].x,enemy[i].y,enemy[i].shot_type,i);
 }
 if (gamecount > enemy[i].gamecount_point + 260){
  enemy[i].y++;
 }
}

中間部分、下降していったん止まった時に敵ショットを起動しております。

my_set_enemy_shot(enemy[i].x,enemy[i].y,enemy[i].shot_type,i);

こちらですね。

引数にはその時の敵の座標「enemy[i].x,enemy[i].y」、その敵が持つショットの種類「enemy[i].shot_type」そしてさきほどの「enemy_no」にあたるその敵自身がどの「敵の入れ物」を使っているのかを示す情報を渡します。

では「my_set_enemy_shot」の中身を見てみましょう。

void my_set_enemy_shot(double x,double y,int shot_type,int enemy_no){
	for(int i = 0;i < DISP_ENEMY_MAX * 2;i++){
		if(enemy_shot[i].move_flag == 0){
			enemy_shot[i].move_flag = 1;
			enemy_shot[i].first_x = x;
			enemy_shot[i].first_y = y;
			enemy_shot[i].move_type = shot_type;
			enemy_shot[i].enemy_no = enemy_no;
			break;
		}
	}
}

未使用の「敵ショットの入れ物」を探して

for(int i = 0;i < DISP_ENEMY_MAX * 2;i++){
	if(enemy_shot[i].move_flag == 0){
	}
}

さきほど引数で渡した情報をそれぞれに登録するだけですね。

enemy_shot[i].move_flag = 1;
enemy_shot[i].first_x = x;
enemy_shot[i].first_y = y;
enemy_shot[i].move_type = shot_type;
enemy_shot[i].enemy_no = enemy_no;

敵ショットが起動されたトコロで実際の動きに入っていきます。

「敵ショットの動き方」に応じて出現・計算

敵ショットの動き方を計算する「my_move_enemy_shot()」です。

少し長いので分けて説明します。

まずは全ての「敵ショットの入れ物」を調べてそれが使用中かどうか調べます。

for(int i = 0;i < DISP_ENEMY_MAX * 2;i++){
	if(enemy_shot[i].move_flag == 1){
	}
}

ここで使用中「enemy_shot[i].move_flag == 1」の状態のものがあった場合、その敵ショットは動いていなきゃいけないので動かします。

「switch」文で動き方を振り分けます。

switch (enemy_shot[i].move_type){
case 0:
	break;
default:
	break;
}

今回は「case 0」まっすぐ下に飛ぶだけのショットを作ります。

初期化部分と移動部分に分かれます。

初期化部分を見てみます。

if (enemy_shot[i].init_flag == 0){
	enemy_shot[i].x[0] = enemy_shot[i].first_x;
	enemy_shot[i].y[0] = enemy_shot[i].first_y;
	enemy_shot[i].max_bullet = 1;
	enemy_shot[i].gamecount_point[0] = gamecount;
	enemy_shot[i].init_flag = 1;
}
else{
	/*移動部分*/
}

初期化用のフラグ「enemy_shot[i].init_flag == 0」の時は初期化されていないので初期化をします。

初期座標はそのショットを放った敵の座標を移した「enemy_shot[i].first_x,enemy_shot[i].first_y」ですね。

最初は一発だけしか飛ばさないので最大弾数である「enemy_shot[i].max_bullet = 1」になります。

あとは基準となる「gamecount」を記録して初期化完了です。

では移動部分を見てみましょう。

先ほどの「else」部分ですね。

if (gamecount < enemy_shot[i].gamecount_point[0] + 300){
 enemy_shot[i].y[0] -= 2;
}
else{
 enemy_shot[i].move_flag = 0;
 enemy_shot[i].init_flag = 0;
}

「gamecount_point[0]」を基準に「300」カウント下降して少し経過した時点で消滅します。

座標を中央に・表示

こちらは前回までと同じような処理なので省略させて頂きます。

画像(s-7-1)

敵ショットが表示されました!

ここまでの中間ソースになります。

中間ソース6

次回は当たり判定を作ります。

次回

八日目 当たり判定

□ページの先頭へ□

□HOME□

広告

↓2014年06月20日発売↓

14歳からはじめるC言語わくわくゲームプログラミング教室 Visual Studio 2013編

新品価格
¥2,500から
(2016/5/10 22:17時点)

↓2014年10月25日発売↓

超本格! サンプルで覚えるC言語 3Dゲームプログラミング教室

新品価格
¥3,110から
(2016/5/10 22:18時点)

↓2013年07月25日発売↓

小学生からはじめるわくわくプログラミング

新品価格
¥2,052から
(2016/5/10 22:21時点)

↓2016年05月13日発売↓

小学生からはじめるわくわくプログラミング2

新品価格
¥2,052から
(2016/5/10 22:22時点)

もっと!C、C++言語本

□ページの先頭へ□

□HOME□