//====================================================================
// 落ちてくる矢を受け止めるゲーム
//--------------------------------------------------------------------
// 処理内容 : メイン処理
// ファイル名 : ArrowGame.cpp
// 作成者 : Copyright(C) 2004 武千代
//====================================================================
//====================================================================
// ヘッダファイルのインクルード
//====================================================================
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include "Console.h"
//====================================================================
// マクロ定義
//====================================================================
#define MAX_ARROW 10 // 矢の最大数
#define MAX_GROUND 20 // 地面の最大数
//====================================================================
// 構造体定義
//====================================================================
// 矢
struct tagArrow{
bool bExist; // true - 存在する
int x; // x座標
int y; // y座標
};
//====================================================================
// グローバル変数
//====================================================================
CConsole g_cnsl; // コンソール・クラス
int g_nKey; // キーコード
int g_nXPos = 18; // 位置
int g_nScore = 0; // 得点
int g_nMaxScore = 0; // 最高点
bool g_bBeep = false; // true - ビープ音を鳴らす
tagArrow g_Arrow[MAX_ARROW]; // 矢
bool g_bGround[MAX_GROUND]; // true : 地面あり
//====================================================================
// 関数のプロトタイプ宣言
//====================================================================
void Init(void);
void EraseBase(void);
void MoveBase(void);
void DrawBase(void);
void MoveArrow(void);
void DrawScore(void);
//====================================================================
// メイン
//====================================================================
void main(void)
{
// カーソルを消す
g_cnsl.SetCursorInfo(25, FALSE);
// 現在の時刻値を使って、乱数ジェネレータを初期化
srand((unsigned)time(NULL));
Init(); // 初期化する
while(1)
{
MoveBase(); // 受け止める台を移動させる
MoveArrow(); // 矢の処理
::Sleep(60);
}
}
//====================================================================
// 初期化する
//====================================================================
void Init(void)
{
// 画面クリア
g_cnsl.Clear();
g_nScore = 0;
g_cnsl.SetCursorPosition(0, 0);
g_cnsl.SetColor(L_WHITE, L_BLACK);
printf("落ちてくる矢を受け止めろ!!!\n左移動:Z 右移動:X");
DrawScore(); // 得点を描画
for(int i = 0; i < MAX_GROUND; i++)
{
g_bGround[i] = true;
g_Arrow[i].bExist = false;
}
// 地面作成
g_cnsl.SetCursorPosition(0, MAX_GROUND);
g_cnsl.SetColor(L_WHITE, L_YELLOW);
printf(" ");
DrawBase(); // 受け止める台を描画する
// "GAME OVER" 消去
g_cnsl.SetCursorPosition(15, 10);
g_cnsl.SetColor(L_WHITE, L_BLACK);
printf(" ");
}
//====================================================================
// 受け止める台を移動させる
//====================================================================
void MoveBase(void)
{
if(kbhit())
g_nKey = getch(); // キーコード取得
else
g_nKey = 0;
if(g_nKey == 'z' || g_nKey == 'Z') // 左
{
if(g_nXPos > 0)
{
EraseBase(); // 受け止める台を消去する
g_nXPos -= 2;
DrawBase(); // 受け止める台を描画する
}
}
if(g_nKey == 'x' || g_nKey == 'X') // 右
{
if(g_nXPos < 36)
{
EraseBase(); // 受け止める台を消去する
g_nXPos += 2;
DrawBase(); // 受け止める台を描画する
}
}
}
//====================================================================
// 受け止める台を消去する
//====================================================================
void EraseBase(void)
{
g_cnsl.SetCursorPosition(g_nXPos, 19);
g_cnsl.SetColor(L_WHITE, L_BLACK);
printf(" ");
}
//====================================================================
// 受け止める台を描画する
//====================================================================
void DrawBase(void)
{
g_cnsl.SetCursorPosition(g_nXPos, 19);
g_cnsl.SetColor(L_WHITE, H_WHITE);
printf(" ");
g_cnsl.SetCursorPosition(g_nXPos + 1, 19);
g_cnsl.SetColor(H_WHITE, L_BLACK);
printf("__");
}
//====================================================================
// 矢の処理
//====================================================================
void MoveArrow(void)
{
static s_nTime; // 時間
int i;
if(++s_nTime == 5)
{
s_nTime = 0;
// 矢、発生
if(rand() % 4 == 0)
{
for(i = 0; i < MAX_ARROW; i++)
{
if(!g_Arrow[i].bExist)
{
g_Arrow[i].bExist = true;
g_Arrow[i].x = (rand() % MAX_GROUND) * 2;
g_Arrow[i].y = 1;
break;
}
}
}
for(i = 0; i < MAX_ARROW; i++)
{
if(g_Arrow[i].bExist)
{
if(g_Arrow[i].y > 1)
{
// 矢を消去する
g_cnsl.SetCursorPosition(g_Arrow[i].x, g_Arrow[i].y);
g_cnsl.SetColor(H_CYAN, L_BLACK);
printf(" ");
}
g_Arrow[i].y++;
// 矢を受け止めたかどうか
if(g_Arrow[i].y == 19 && (g_Arrow[i].x == g_nXPos || g_Arrow[i].x == g_nXPos + 2))
{
g_Arrow[i].bExist = false;
g_nScore++; // 得点を加える
if(g_bBeep)
::Beep(5000, 30);
DrawScore(); // 得点を描画
}
else
{
// 矢を描画する
g_cnsl.SetCursorPosition(g_Arrow[i].x, g_Arrow[i].y);
g_cnsl.SetColor(H_CYAN, L_BLACK);
printf("↓");
// 一番下に到達したかどうか
if(g_Arrow[i].y == 20)
{
if(g_bBeep)
::Beep(50, 500);
g_Arrow[i].bExist = false;
if(g_bGround[g_Arrow[i].x / 2])
g_bGround[g_Arrow[i].x / 2] = false;
else
{
// "GAME OVER" 描画
g_cnsl.SetCursorPosition(15, 10);
g_cnsl.SetColor(H_RED, L_BLACK);
printf("GAME OVER");
if(g_nMaxScore < g_nScore)
g_nMaxScore = g_nScore; // 最高点を保存
getch(); // 何かキーが押されるまで待つ
Init(); // 初期化する
break;
}
}
}
}
}
}
}
//====================================================================
// 得点を描画
//====================================================================
void DrawScore(void)
{
g_cnsl.SetCursorPosition(20, 1);
g_cnsl.SetColor(H_YELLOW, L_BLACK);
printf("得点:%02d 最高点:%02d", g_nScore, g_nMaxScore);
}
//====================================================================
|