>> シューティングゲーム作成入門トップに戻る

操作キャラから弾を発射してみよう

今回は操作キャラから弾を発射してみましょう。

まず弾を発射させるために、弾用の構造体を定義します。
define.hでは以下のように定義しています。

struct SHOT{
	bool flag;//弾が発射中かどうか
	double x;//x座標
	double y;//y座標
	int gh;//グラフィックハンドル
	int width,height;//画像の幅と高さ
};


弾が発射中かどうかを示すフラグと、座標、グラフィックハンドル、画像のサイズ用の変数を持たせています。
フラグを持たせたのは、現在発射中の弾だけ描画するためです。
画面からはみ出した弾はもう描画する必要はありませんよね?
それに当たり判定等でも使う必要がないので、それを区別するために持たせてます。

操作キャラから発射する弾はとりあえず1列だけにします。
アイテムなどを取ったら弾が拡散して攻撃できたりするゲームがほとんどですが、
まずは初期段階なので一列だけにします。大分後の講座でその辺の要素は付け加えていきます。

発射する弾の数ですが、一画面中に何弾発射してればよいかという視点から考えます。
画面中に20発以上の弾が溢れることはないので、20発定義しておけば弾切れもないと思うので、
20発定義することにします。
player.hではこの弾構造体を20個配列として定義しています。

class PLAYER{
private:
	//x座標,y座標
	double x,y;

	//画像幅
	int width,height;

	//グラフィックハンドル格納用配列
	int gh[12];


	//移動係数
	float move;

	//横方向と縦方向のカウント数。
	int xcount,ycount;
	//添字用変数
	int ix,iy,result;

	//生きてるかどうかのフラグ
	bool life;

	//弾
	SHOT shot[PSHOT_NUM];

	//カウント
	int count;

private:
	void Move();
	void Draw();
	void Shot();

public:
	PLAYER();
	void All();

};


PSHOT_NUMという定数はdefine.hで20と定義しています。
こういう弾の最大数などの値は定数として定義しておくと後から変更があった場合に都合が良いです。

次に、コンストラクタで画像の読み込み等の処理を行います。

PLAYER::PLAYER()
{
	//画像読み込み
	
	if(-1==LoadDivGraph("charall.png",12,3,4,29,40,gh)){
		MSG("エラー発生");
	}

	width=29;
	height=40;
		

	//移動係数
	move=1.0f;

	//横方向と縦方向のカウント数。
	xcount=0,ycount=0;
	//添字用変数
	ix=0,iy=0,result=0;

	//初期位置
	x=180;
	y=400;

	//生きてるかどうか
	life=true;

	//弾初期化
	memset(shot,0,sizeof(shot));


	//弾画像読み込み
	int temp=LoadGraph("shot.png");
	int w,h;
	GetGraphSize(temp,&w,&h);

	//フラグを全部falseにしとく
	//グラフィックハンドルと画像のサイズを代入しとく
	for(int i=0;i<PSHOT_NUM;++i){
		shot[i].flag=false;
		shot[i].gh=temp;
		shot[i].width=w;
		shot[i].height=h;
	}

	count=0;


}


下の方に書いてある「弾初期化」と「弾画像読み込み」と書いてある部分が該当のコードです。
弾画像は、

を使います。
まず画像のグラフィックハンドルとサイズを取得しています。
次にforループ文で、弾数分だけループさせて、それぞれの要素の値を設定しています。
弾はまだ発射してないので、flagはfalse,
グラフィックハンドルはどの弾も一緒なので、先程読み込んだtempの値を指定してます。
width,とheightも先程取得しといた画像のサイズを代入しています。

これで下準備はできました。
次に、実際に弾を発射させる部分のコードと弾を移動させる部分のコードの説明をします。
新たに、Shot関数を作りました。

void PLAYER::Shot()
{
	//キーが押されててかつ、6ループに一回発射
	if(key[KEY_INPUT_Z]==1 && count%6==0){
		for(int i=0;i<PSHOT_NUM;++i){
			if(shot[i].flag==false){
				shot[i].flag=true;
				shot[i].x=x;
				shot[i].y=y;
				break;
			}
		}
	}

	//弾を移動させる処理
	for(int i=0;i<PSHOT_NUM;++i){
		//発射してる弾だけ
		if(shot[i].flag){
			shot[i].y-=PSHOT_SPEED;

			//画面の外にはみ出したらフラグを戻す
			if(shot[i].y<-10){
				shot[i].flag=false;
			}
		}
	}


}


弾はZキーで発射するようにします。
最初のif文でZキーが押されていて、かつcountを6で割って余りが0ならば、処理をする、
という条件になっています。
countという変数は、毎ループごとに1ずつ増えていくカウント用変数です。
All関数でインクリメントさせています。
つまり、このcountを6で割って余りが0の時というのは、
6ループに一回やってくることになります。
毎ループごとに弾を発射してしまうと、弾と弾の間隔が近すぎてしまいますからね。

その次に弾をセットするためにforループに入っています。
ここでflagがfalse、つまり発射されてない弾を見つけたら、
フラグをtrueにして初期座標を設定しています。
初期座標は操作キャラの中心から発射するので、操作キャラの座標をそのまま代入しています。

ここまでで弾のセット部分のコードは出来ました。
次に弾の移動部分のコードです。

その下のコードで、弾の数だけまたforループでループさせています。
ここでフラグがtrue、つまり弾が発射中のやつだけ、
y座標からPSHOT_SPEEDの値だけ引いています。
PSHOT_SPEEDはdefine.hで14と定義しています。
つまり毎回14ずつ上に移動するということです。

これで弾の移動までは出来ましたが、
次に弾が画面の外にはみ出たらフラグを戻してやる必要があります。
それが、その下のif文です。
画面の外にはみ出るということは、弾は上に飛んでいくので、
y座標が画面の上端よりも越えたらはみ出たということが分かります。
上端のy座標は余白分の10ですが、弾画像の高さもありますので、
余裕をもって-10よりも下回ったら、フラグを戻すようにしています。
こうすることで、弾が完全に画面から消えてから、フラグが戻されることになります。

ここまでで弾の移動制御に関する処理は全てかけました。
後は描画するだけです。
描画部分とAll関数は以下のようになっています。

void PLAYER::Draw()
{

	//弾描画
	for(int i=0;i<PSHOT_NUM;++i){
		if(shot[i].flag){
			DrawGraph(shot[i].x-shot[i].width/2,shot[i].y-shot[i].height/2,shot[i].gh,TRUE);
		}
	}

	//生きてれば描画
	if(life){
		//描画
		DrawGraph(x-width/2,y-height/2,gh[result],TRUE);
	}
}

void PLAYER::All()
{
	Move();
	Shot();
	Draw();

	++count;
}


キャラの描画よりも先に弾の描画を行っています。
弾を後から描画すると、キャラの上に被ってしまい違和感があるからです。
弾の描画は、forループで弾数分だけループさせ、
発射中の弾、つまりflagがtrueのやつだけ描画するようにしています。
指定している座標も配列の各要素の座標を指定しています。

All関数もShot関数を加えただけで特に変更はありません。
先程説明したカウント用のcount変数を加えて、インクリメントさせてるだけです。

こうすることで以下の動画のように操作キャラから弾を発射することが出来るようになります。

今回の説明は以上です。
次回は敵を表示させてみます。

>> 【敵を表示させてみよう】に進む
>> シューティングゲーム作成入門トップに戻る
●更新履歴
2016/08/16 Java入門ページにページを幾つか追加
2016/04/08 Java入門ページ作成
2016/03/09 メニューレイアウト変更。ブラウザキャッシュのクリアをお願い致します。
2016/03/09 PDOトランザクション、自動コミットモードをオフ追加
2016/03/09 PDO 例外処理 try catch追加
2016/03/09 PDO update文実行追加
2016/03/09 PDO delete文実行追加
2016/03/09 PDO insert文実行追加
2016/03/09 PDO selectでデータを取得、fetchAll、queryメソッド追加
2016/03/09 PDO bindValueとbindParamの違い追加
2016/03/09 PDO prepare プリペアドステートメントの使い方追加
2016/03/04 ソースコードをクリップボードにコピーする機能を追加
2016/03/04 C言語、C++のページのソースコードを一部修正
2014/01/31 C言語関数一覧ページに11ページほど追加
2014/01/31 C言語関数一覧ページに30ページほど追加
2014/01/30 C言語関数一覧ページ作成中
2013/07/01 レイアウト変更に伴いブラウザキャッシュのクリアをお願いします。
2013/07/01 MySQL入門ページ作成
2013/07/01 PHP入門ページにSQLite学習項目追加
2013/06/25 ドメイン変更、レイアウトを一部変更
2013/03/14 レイアウトを一部変更
2012/08/13 C言語よくある課題・宿題ページ開設!
2012/08/13 シューティングゲーム作成第33章追加!
2012/08/11 ドメイン変更&サーバ移設完了
2012/04/21 シューティングゲームプログラミング第2,3章の内容を修正
2012/04/19 シューティングゲームプログラミング第2章の内容を修正
2012/04/03 Googleカスタム検索を設置!
2012/04/03 シューティングゲームプログラミング第32章追加!
2012/04/03 シューティングゲームプログラミング第31章追加!
2012/03/31 サイトをリニューアルしました!
2012/03/25 シューティングゲームプログラミング第30章追加!
2012/03/19 シューティングゲームプログラミング第29章追加!
2012/03/16 シューティングゲームプログラミング第28章追加!
2012/02/27 シューティングゲームプログラミング第27章追加!
2012/02/03 シューティングゲームプログラミング第26章追加!
2012/01/31 シューティングゲームプログラミング第25章追加!
2012/01/20 シューティングゲームプログラミング第23,24章追加!
2012/01/11 シューティングゲームプログラミング第22章追加!
2012/01/05 トップページ、ゲームプログラミング関連のトップページのデザインを変更
2012/01/04 シューティングゲームプログラミング第21章追加!
2012/01/01 シューティングゲームプログラミング第20章追加!
2011/12/25 シューティングゲームプログラミング第19章追加!
2011/12/22 シューティングゲームプログラミング第18章追加!
2011/12/18 シューティングゲームプログラミング第17章追加!
2011/12/17 シューティングゲームプログラミングページOPEN!
2011/11/21 ゲームプログラミングページOPEN!
2011/11/21 サイトデザインを大幅に変更
2011/11/17 TOPページのデザインを変更。相互リンクページに、複数サイト追加。
2011/11/06 WINAPI学習ページ(33~36章)追加
2011/11/05 WINAPI学習ページ(20~32章)追加
2011/10/27 WINAPI学習ページ(14~19章)追加
2011/10/21 WINAPI学習ページ(13章)追加
2011/10/21 サイトマップ、連絡ページ追加
2011/10/17 WINAPI学習ページ(6~11章)追加
2011/10/16 WINAPI学習ページ(1~5章)追加
2011/10/13 全体のレイアウト変更
2011/10/07 PHP学習ページ(8~11章)追加
2011/10/06 PHP学習ページ(1~7章)作成
2011/10/06 JavaScriptリファレンスページ作成
2011/10/05 C言語学習ページ発展編(10~14章)追加
2011/10/04 C言語学習ページ発展編(1~9章)追加。
2011/10/03 HTML/CSSリファレンスのページ追加。(個々の詳細ページは作成中)
2011/09/30 HTML学習ページ(8章)追加
2011/09/29 JavaScript学習ページ(12~17章)追加
2011/09/28 JavaScript学習ページ(1~11章)追加
2011/09/27 HTML学習ページ(4~7章)追加
2011/09/26 C言語学習ページ(27章)追加、C++学習ページ(17章)、HTML学習ページ(1~3章)追加
2011/09/25 C言語学習ページ(23~26章)を追加
2011/09/24 C++学習ページ(9~16章)追加
2011/09/23 C++学習ページ(3~8章)追加
2011/09/22 C言語の学習ページ(22章)とC++学習ページ(1~2章)追加
2011/09/21 C言語の学習ページ(15章~21章)を追加
2011/09/20 C言語の学習ページ(10章~14章)を追加
2011/09/19 サイト作成(随時更新予定)