| | | || | ● 1.ゲームを創ろう・入門編 |
|
初回は「入門編」です。 ノーマルの C++Builder5 で簡単なゲームを作ります。 C++Builder には、フリーの優れたコンポーネントも沢山あるのですが、初回は「入門編」と言うことで、C++Builder5 付属コンポーネントだけでゲームを作ります。
○ 用意するもの
○ 完成予定の作品
○ C++Builder5 起動直後画面
○ コンポーネントの貼り付け
○ 変数の宣言 int jx, jy; // 自機の位置格納変数 int sx, sy; // 自弾の位置格納変数 int ex, ey; // 敵機の位置格納変数 int sf; // 自弾が発射されてるか?フラグ int ef; // 敵機の状態フラグ int eh; // 敵機移動フラグ int score; // スコアを記録する変数 int miss; // ミスカウントを記録する変数 int K4, K6, KS; // キースキャン格納フラグ使う変数はこれだけ。 今回はポインタや構造体などは一切使いません。 このコーナーでは、C++の文法までは解説しませんので、各自でC++入門書は用意してください。 (注意)「//」と書かれている部分はリマークといって、この記号以降に書かれた文字は実行されず、コンパイラに無視されます。 つまり「//」と書かれている以降の文字は打たなくても大丈夫です。
○ プログラム開始 // とりあえずタイマーコンポーネントは止めておく(今回のゲームでは、止めておかなくても良いんだけど) Timer1->Enabled = false; // Form1 の初期化(フォームのプロパティを制御) Form1->Caption = "サンプルゲーム"; Form1->ClientWidth = 200; Form1->ClientHeight = 200; Form1->BorderStyle = bsDialog; Form1->Position = poDesktopCenter;フォームのサイズを 200*200 に設定。 ウインドウタイプをダイアログタイプにして、位置はデスクトップセンター。 // Image1 初期化(2枚のイメージキャンバスのプロパティを制御) Image1->Top = 0; Image1->Left = 0; Image1->Width = 200; Image1->Height= 200; Image1->Visible = false; // 非表示フラグ // Image2 初期化 Image2->Top = 0; Image2->Left = 0; Image2->Width = 200; Image2->Height= 200;2枚のイメージコンポーネントを 200*200 に設定。 Image1 は、作業用で画面には表示されません。 画面表示は Image2 のみです。 Image1 で作業 ― 転送 ―> Image2 で表示、とすることによって、画面のチラツキを軽減できます。 // 変数初期化(ヘッダファイルで宣言した変数に値を入れます) jx = 100; jy = 175; sf = 0; // 0 -> 自弾発射OK ・ 1 -> 自弾発射中 ef = 1; // 0 -> 敵居ない ・ 1 -> 敵居る ・ 2 -> 敵爆発中 ex = 100; ey = 15; eh = 0; // 0 -> 左移動 ・ 1 -> 右移動 score = 0; // 最初はスコア値を「0」にしておく miss = 0; // ミスも「0」に // とりあえず背景を黒く塗っておく Image1->Canvas->Brush->Color = clBlack; Image1->Canvas->FillRect( Rect( 0, 0, 200,200) ); // Timer1(タイマーコンポーネントを制御) Timer1->Interval = 45; Timer1->Enabled = true; // タイマー・ONFormCreate の記述はここまで。 OnCreate と同じ要領で、OnKeyDown と OnKeyUp を作ります。 OnKeyDown には、
switch ( Key )
{
case VK_SPACE: KS = 1;
break;
case VK_LEFT : K4 = 1;
break;
case VK_RIGHT: K6 = 1;
}
を入力します。 OnKeyUP には、
switch ( Key )
{
case VK_SPACE: KS = 0;
break;
case VK_LEFT : K4 = 0;
break;
case VK_RIGHT: K6 = 0;
}
を打ち込みます。 これで、「カーソルキー右」が押されたら変数 K6 に1が入り、「カーソルキー右」が押されていなければ K6 の値は0が入るようになりました。 同様に「カーソルキー左」の状態は K4、スペースバーの状態は KS に入ります。次は、いよいよタイマーコンポーネントです。 タイマーコンポーネントの OnTimer をダブルクリックし、Timer1Timer を起こします。 起こしたら、次のプログラムを入力しましょう。 // 作業画面(Image1)クリア Image1->Canvas->FillRect( Rect( 0, 0, 200, 200 ) ); // スコア表示 Image1->Canvas->Font->Size = 11; Image1->Canvas->Font->Color = clSilver; Image1->Canvas->TextOut( 20, 1, "Score" ); Image1->Canvas->TextOut( 132, 1, "Miss" ); Image1->Canvas->Font->Color = clFuchsia; Image1->Canvas->TextOut( 66, 1, IntToStr( score ) ); Image1->Canvas->TextOut( 175, 1, IntToStr( miss ) ); Image1->Canvas->Font->Size = 16;スコアの表示などをします。 Image1->Canvas->TextOut の記述は、Image1->Canvas->TextOut( X座標位置, Y座標位置, 表示する文字 ); です。
// ミスカウント
if ( miss > 2 ) {
Image1->Canvas->Font->Color = clYellow;
Image1->Canvas->TextOut( 50, 100, "Game Over" );
Timer1->Enabled = false;
}
変数 miss は、自弾の弾が画面外に出るたびに1づつ加算されるフラグです。 3になれば(プログラム的には、2以上になれば)、「Game Over」と画面に表示されて、タイマーコンポーネントが false になります。 つまりゲーム終了です。
// 自機移動
if ( K4 == 1 ) {
if ( jx > 10 ) jx -= 5;
}
if ( K6 == 1 ) {
if ( jx < 190 ) jx += 5;
}
キースキャンフラグの K4 に1が入っているということは、カーソルキー左が押されているということなので、自機は左に移動します。 K6 も同様。
// 自機表示 Image1->Canvas->Font->Color = clAqua; Image1->Canvas->TextOut( jx-9, jy, "Ω" );Image1->Canvas->TextOut は、Image1 に文字を表示するプログラムで、変数 jx, jy は自機の位置を覚えている変数。 つまり自機の座標X,Yに”Ω”を表示する。
// 自弾発射
if ( sf == 0 && KS == 1 ) {
sf = 1;
sx = jx;
sy = jy-5;
}
変数 sf は、自弾の状態フラグ。 0ならば、画面内に自弾が発射されていないと言う事なので、自弾を発射出来ます。 変数 sf が0で、しかもスペースバーのキースキャン状態が格納されている変数 KS が1(つまりスペースバーが押されている)の場合、自弾発射。
// 自弾移動
if ( sf == 1 ) {
sy -= 6;
Image1->Canvas->Font->Color = clYellow;
Image1->Canvas->TextOut( sx-9, sy, "‖" );
// 自弾当たり判定
if ( (ex-sx) > -26 && (ex-sx) < 23 ) {
if ( (ey-sy) > -13 && (ey-sy) < 13 ) {
ef = 2;
sf = 0;
score += 10;
}
}
// 自弾、画面外へ(ミス加算)
if ( sy < -10 ) {
++miss;
sf = 0;
}
}
自弾の移動と当たり判定。 自弾と敵機が当たれば、敵の状態フラグ ef に2が
入り、スコアが10加算されます。 自弾状態フラグ sf にも0が入り自弾も消えます。自弾が画面外に出てしまったら、miss が一つ加算されます。
// 敵機移動
if ( ef == 1 ) {
if ( eh == 0 ) {
ex -= 4;
if ( ex < 15 ) eh = 1;
} else {
ex += 4;
if ( ex > 185 ) eh = 0;
}
}
敵機移動方向変数 eh が0ならば左へ移動。 1ならば右へ移動。 画面端まで敵機が到達すれば、フラグには逆の値が入ります。
// 敵機表示
if ( ef == 1 ) {
Image1->Canvas->Font->Color = clRed;
Image1->Canvas->TextOut( ex-19, ey, "∈∋" );
} else {
Image1->Canvas->Font->Color = clYellow;
if ( ef%2 == 0 ) {
Image1->Canvas->TextOut( ex-19, ey, "●●" );
} else {
Image1->Canvas->TextOut( ex-19, ey, "○○" );
}
if ( ++ef > 20 ) ef = 0;
}
敵機状態フラグに応じて、表示されるものが変わります。ef の値が1ならば敵機「∈∋」が表示されます。 ef の値が1以外なら爆発パターンが表示されますが、ef の値が1以上で偶数ならば「●●」が表示され、奇数ならば「○○」が表示されます。 交互にパタパタアニメさせているわけです。
// 敵機現る
if ( ef == 0 ) {
ex = 100;
eh = random(2);
}
敵機が画面から居なくなれば、また中央に現れます。 移動方向は乱数で決めます。
// Image1 -> Image2 へ転送
Image2->Canvas->CopyRect( Image2->Canvas->ClipRect,
Image1->Canvas, Image2->Canvas->ClipRect);
}
作業が終わった Image1 の画面は、表示用画面の Image2 に転送です。 これでチラツキ無く、表示できます。
○ プログラム完成
○ プログラム配布
○ 入門編終了 |