#include #include #include #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); } //====================================================================