ポンクソフト

ブロック崩しの作成 - C言語とelで様々なゲームを作ろう

前ページ C言語とelで様々なゲームを作ろう TOP 次ページ

目次

  1. C言語とelで様々なゲームを作ろう
  2. Visual C++ .NET での設定
  3. テンプレートファイルの解説
  4. シューティングゲームの作成(チュートリアル)
  5. パックマン的ゲームの作成(チュートリアル)
  6. ブロック崩しの作成
  7. 15パズルの作成
  8. 横スクロールジャンピングゲームの作成
  9. オセロの作成
  10. 神経衰弱の作成
  11. 7ならべの作成
  12. テトリスの作成
  13. ぷよぷよの作成

ソース・プロジェクトファイル

ソースファイル
プロジェクトファイル(Visual C++ 6.0)

ゲームの説明

よくあるブロック崩しゲームです。
マウスの左右でパドルを動かして、ボールを下に落とさないようにブロックを全部消せばクリアです。
ボールの跳ね返りかたが少しおかしい部分がありますが、その辺の処理を入れるとプログラムが長くなるのであえてそのままにしてあります。

プログラムの解説

グローバル変数

DDOBJ block;
DDOBJ pad;
DDOBJ ball;
ブロック・パドル・ボールの各画像を表わすスプライトオブジェクトです。それぞれの画像の大きさは
です。
bool bf[5][10];
画面上に複数のブロックがあり、それぞれのブロックについて「表示されている/消えている」を管理しなければいけないので、二次元配列 bf を用意しています。この配列の要素それぞれについて、ブロックが存在すれば true、存在しなければ false となります。
ブロックの表示領域は画面上、横 10 × 縦 5 ブロックあり、配列のどの要素がどのブロックに相当するのかは以下の図の通りです。
block_bf.gif

メイン関数

elWindow(640, 480, TRUE);
elWindow は画面をウインドウモードにする el の関数ですが、第3引数を TRUE にするとマウスが画面からはみ出さないようになります。

ウインドウ生成関数

  block = elDraw::LoadObject("block.bmp");
  pad = elDraw::LoadObject("pad.bmp");
  ball = elDraw::LoadObject("ball.bmp");
各ビットマップをスプライトに読み込んでいる部分です。
  for (int y = 0; y < 5; y++) {
    for (int x = 0; x < 10; x++) {
      if (x == 0 || x == 9 || y == 0) bf[y][x] = false;
      else bf[y][x] = true;
    }
  }
初期のブロックの状態を配列 bf にセットしています。全て true(ブロックあり)にするのではなく、ボールが通りやすいように左右と上の端は false(ブロックなし)にしています。

メイン画面

static int bx = 50, by = 160;
ボールの中央を表わす座標です。今回は当たり判定を簡略化するためにボールを点として扱います。その点の座標が (bx, by) です。
static int ax = 1, ay = 4;
ボールの速度です。初期状態では右に 1 、下に 4 の速度になっています。
static int px = 0;
パドルの x 座標です。これはパドル中央ではなく左端の座標です。
static int score = 0;
得点です。
static bool over = false;
ゲームオーバー、つまりボールを画面下に落とすと true になります。
px = MousePX;
MousePX は el の変数で、常にマウスの x 座標が入ります。マウスの x 座標をそのままパドルの x 座標としています。
if (px > 640 - 128) px = 640 - 128;
elWindow 関数によってマウスは画面からはみ出さないようになっているのですが、画面右へはパドルの長さ分だけはみ出すことがあるので、それを防いでいる部分です。
bx += ax; by += ay;
ボールの座標に速度を加えて移動します。
  if (bx < 0) {bx = 0; ax = -ax;}
  else if (bx > 640) {bx = 640; ax = -ax;}
  if (by < 0) {by = 0; ay = -ay;}
右や左や上の壁に当たったときに、速度を反転してボールを反射させています。
else if (by > 480) over = true;
下の壁に当たったときはゲームオーバーフラグを立てています。
  if (by >= 420 && by < 420 + 16 && bx >= px && bx < px + 128) {
    by = 420;
    ay = -ay;
    ax = (bx - px) / 16 - 4;
    if (ax >= 0) ax++;
  }
ボールの中央座標がパドルの領域内に入ったらボールとパドルが当たったと見なし、ボールを反射させています。
反射する際、y 方向の速度はそのまま反転していますが、x 方向の速度はパドルに当たった位置によって変化させています。パドルを横に8等分し、それぞれについてボールが当たったときの x 方向の速度は以下の図のようになります。
block_padsplit.gif
  int x2 = bx / 64, y2 = by / 32;
  if (y2 < 5 && bf[y2][x2]) {
    bf[y2][x2] = false;
    int x3 = bx % 64;
    int y3 = by % 32;
    if (x3 < 4 || x3 >= 64 - 4) ax = -ax; 
    if (y3 < 4 || y3 >= 32 - 4) ay = -ay; 
    score++;
  }
ボールとブロックとの当たり判定の部分です。
int x2 = bx / 64, y2 = by / 32;
この部分によってボールがある位置のブロックの番号を算出しています。int 型で割り算をした場合、端数が切り捨てられる性質を利用しています。x2 が横の番号(左から 0, 1 ... 9)、y2 が縦の番号(上から 0, 1 ... 4)です。
if (y2 < 5 && bf[y2][x2]) {
まず y2 < 5 でボールがブロックの領域に入っているかチェックし、そこにブロックがある場合(bf[y2][x2])、ボールとブロックが当たったと見なしています。
bf[y2][x2] = false;
ブロックが消えたので false を代入します。
int x3 = bx % 64;
int y3 = by % 32;
x3 と y3 は、ブロックの中でどの位置にボールがいるかを示す相対座標です。剰余を使うことによってどの位置にあるブロックでも関係なく同じ処理をすることができます。
if (x3 < 4 || x3 >= 64 - 4) ax = -ax;
ブロックの左端または右端に当たった場合、x 方向の速度を反転しています。
if (y3 < 4 || y3 >= 32 - 4) ay = -ay;
ブロックの上端または下端に当たった場合、y 方向の速度を反転しています。
この辺の処理をもう少し細かくすれば、ボールをもっと自然に反射させることができると思います。
score++;
最後に得点を +1 しています。
  for (y = 0; y < 5; y++) {
    for (x = 0; x < 10; x++) {
      if (bf[y][x]) elDraw::Layer(x * 64, y * 32, block, 0, 0, 64, 32);
    }
  }
配列 bf の値をチェックして、ブロックが存在するときのみそれを表示しています。
elDraw::Layer(bx - 8, by - 8, ball, 0, 0, 16, 16);
ボールを表示しています。(bx, by) はボールの中央座標なので、左上になるように直しています。
elDraw::Layer(px, 420, pad, 0, 0, 128, 16);
パドルを表示しています。
SHOW2(0, 450, "スコア : %d", score * 10);
スコアを表示している部分です。score はそのままだと 1 点ずつ増えて地味なので、表示のときだけ 10 倍しています。
  if (over) {
    elSystem::Message("ゲームオーバー");
    elDraw::Exit();
  }
ゲームオーバーになったら(フラグが立っていたら)ポップアップメッセージを表示して終了します。
  if (score >= 32) {
    elSystem::Message("ゲームクリア!");
    elDraw::Exit();
  }
ブロックを 32 個消したらゲームクリアなので、ポップアップメッセージを表示して終了します。
前ページ C言語とelで様々なゲームを作ろう TOP 次ページ
このエントリーをはてなブックマークに追加 そっか0