C言語ゲームプログラミング  ブロック崩し編 第1回




2014年10月より個人の方を対象に、Study C無料提供を開始しました。
C言語を勉強中の方は、学習・教育に最適なC言語インタープリタのStudy Cを使ってみてください(個人の方は無料です)。
大学・高専・高校などの教育機関での採用実績も多数あるロングセラー商品Study Cが、個人向けに無料提供を始めました。
インタープリタの手軽さに加え、ゲームや3Dタートルグラフィックで楽しく勉強したりと、C言語の学習を協力にサポートします。
ブロック崩しゲーム 3Dツリー クリスマスツリー
また、このようなボタンの用意されているページでは、掲載しているプログラムをStudy Cに直接ロードし実行したりすることができます。
Study Cにロードする Study Cにロードし編集する Study Cにロードし実行する
Study C無料利用についての詳細は、このページを参照してください。



ブロック崩しゲームを作るために必要な基本機能は、第1回第15回の基本講座で説明しました。 ここからは、ブロック崩しゲームを例にして実際のゲームを作っていきたいと思います。


1.矩形の移動


まずは、課題1に相当するプログラムを作成していこうと思います。 ボールが壁にぶつかって反射するプログラムは、第6回講座で完成しているのでラケットを動かす部分から作っていきます。

第8回講座の最初のプログラムを見てください。 このプログラムは、キー入力に応じてボール(ビットマップとして表示)を上下左右に移動させています。 ボールの表示をラケット(ここではただの長方形描画)に変えて上下移動を行わないようにするだけです。

まず、ボールの上下移動に関する部分「if(gl_getkeystate(VK_UP) < 0){」と「if(gl_getkeystate(VK_DOWN) < 0){」のif文を削除します。 ESCキーの処理も削除します。 次にボールのビットマップ読み込みの「hbmp_ball」変数に関する部分を除去します。 最後にgl_drawbitmap() 関数を長方形描画の gl_fillrect() 関数に置き換えます(色は白とします)。

以上の修正を行ったプログラムは次のようになります。

#include <graph.h>

main()
{
	int	b_xx, b_yy, bold_xx, bold_yy;
	unsigned long
		tick;

	gl_openwin(-1, -1, 640, 480, 0);

	bold_xx = bold_yy = -1;
	b_xx = 320;
	b_yy = 240;
	tick = GetTickCount();

	for(;;){
		if(GetTickCount() >= tick && GetTickCount() < tick + 50)
			continue;
		tick = GetTickCount();

		//ESCキーを押したらプログラムが終了する処理も追加
		if(gl_getkeystate(VK_ESCAPE) < 0)
			break;

		if(gl_getkeystate(VK_LEFT) < 0){
			b_xx -= 10;
			if(b_xx < 0)
				b_xx = 0;
		}
		if(gl_getkeystate(VK_RIGHT) < 0){
			b_xx += 10;
			if(b_xx > 640 - 16)
				b_xx = 640 - 16;
		}

		if(bold_xx != b_xx || bold_yy != b_yy){
			if(bold_xx != -1 && bold_yy != -1){
				gl_fillrect(bold_xx, bold_yy,
					bold_xx + 16, bold_yy + 16, RGB(0, 0, 0));
			}
			bold_xx = b_xx;
			bold_yy = b_yy;
			gl_fillrect(b_xx, b_yy, b_xx + 16, b_yy + 16, RGB(255, 255, 255));
		}
		gl_refresh();
	}
}
白い正方形がラケットのつもり

このプログラムを実行すると、640×480のサイズのウィンドウが作成され白い正方形がカーソルキーの操作で左右に動くようになります。

2.左右に移動するラケット完成


ラケットのサイズ、位置、変数名、コメントを修正したものが次のプログラムになります(本質的な部分は、前のプログラムと変わっていません)。

#include <graph.h>

main()
{
	//ラケット用の変数
	int	r_xx = 320, rold_xx = -1;
	unsigned long
		tick;

	gl_openwin(-1, -1, 640, 480, 0);


	tick = GetTickCount();
	for( ; ; ){
		if(GetTickCount() >= tick && GetTickCount() < tick + 50)
			continue;
		tick = GetTickCount();

		//ESCキーを押したらプログラムが終了する処理も追加
		if(gl_getkeystate(VK_ESCAPE) < 0)
			break;

		//カーソル左右キーでラケットの位置(r_xx)を変化させます
		//カーソル左キーが押されているときの処理
		if(gl_getkeystate(VK_LEFT) < 0){
			r_xx = r_xx - 20;
			if(r_xx < 0){
				r_xx = 0;
			}
		}
		//カーソル右キーが押されているときの処理
		if(gl_getkeystate(VK_RIGHT) < 0){
			r_xx = r_xx + 20;
			if(r_xx > 640 - 80){
				r_xx = 640 - 80;
			}
		}

		//ラケットの消去・描画処理
		if(rold_xx != r_xx){
			//前に描画したラケットを消去
			if(rold_xx != -1){
				gl_fillrect(rold_xx, 440, rold_xx + 80, 440 + 10, RGB(0, 0, 0));
			}
			//ラケットの旧位置(rold_xx)を更新
			rold_xx = r_xx;
			//新しい位置にラケットを描画
			gl_fillrect(r_xx, 440, r_xx + 80, 440 + 10, RGB(255, 255, 255));
		}

		gl_refresh();
	}
}
移動するラケット完成

次回は壁に反射するボールのプログラムと、上記のプログラムをつなげていきます。