C++實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲
本文實(shí)例為大家分享了C++實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲的具體代碼,供大家參考,具體內(nèi)容如下
代碼是單線程執(zhí)行,無界面,(博主下一步學(xué)習(xí)QT之后融入)還有待改進(jìn)。
先放張界面圖:
話不多說 上代碼(注釋很清楚,不懂可和博主交流)
main.cpp:
#include<iostream> #include<ctime> #include<string> #include"game.h" using namespace std; int main() { ?? ?srand((unsigned int)time(NULL));//隨機(jī)時(shí)間種子 ?? ?HideCursor();//隱藏光標(biāo) ?? ?Game game; ?? ?int a=drawMenu(); ?? ?if (a == 2) ?? ?{ ?? ??? ?game.rank = 20; ?? ?} ?? ?system("cls"); ?? ?drawPlaying(); ?? ?game.Playing(); }
game.h:
#pragma once #include<iostream> #include<Windows.h>//定義控制臺應(yīng)用程序的入口點(diǎn) using namespace std; //定義敵人結(jié)構(gòu) 其中最后面Frame代表結(jié)構(gòu)體類型 若不加typedef代表定義的結(jié)構(gòu)體變量 typedef struct Frame { ?? ?COORD position[2]; ?? ?// ?COORD 是Windows API中定義的一種結(jié)構(gòu),表示一個字符在控制臺屏幕上的坐標(biāo)。 ?? ?// 其定義為: ?? ?// typedef struct _COORD { ?? ?// ? ? ? ? SHORT X;? ?? ?// ? ? ? ? SHORT Y; ?? ?// ? ? ? } COORD; ?? ?int flag; }Frame; class Game { public: ?? ?COORD position[10]; ?? ?COORD bullet[10];//子彈坐標(biāo) ?? ?Frame enemy[8];//敵人數(shù)量 ?? ?int score; ?? ?int rank;//級別,難度 ?? ?int rankf;//等級標(biāo)志 ?? ?string title; ?? ?int flag_rank;//等級標(biāo)志 ?? ?//構(gòu)造函數(shù) ?? ?Game(); ?? ?//初始化所有 ?//設(shè)定位置 ?? ?void initPlane(); ?? ?void initBullet(); ?? ?void initEnemy(); ?? ?//填充所有 ?--畫出形狀和消失的形狀 ?? ?void drawPlane(); ?? ?void drawPlaneToNull(); ?? ?void drawBullet(); ?? ?void drawBulletToNull(); ?? ?void drawEnemy(); ?? ?void drawEnemyToNull(); ?? ?//執(zhí)行某一個操作 ?? ?void Playing();//游戲主循環(huán) ?? ?void planeMove(char x);//飛機(jī)移動 ?? ?void judgePlane();//判斷飛機(jī)是否與敵機(jī)重疊 ?? ?void GameOver();//游戲失敗 ?? ?void Pause();// 該成員函數(shù)用來使得游戲暫停 ?? ?void Shoot();//發(fā)射子彈 ?? ?void bulletMove();//子彈移動 ?? ?void drawThisBulletToNull(COORD c);//畫出失效子彈 ?? ?void judgeEnemy();//判斷子彈是否擊中敵機(jī) ?? ?void drawThisEnemyToNull(Frame f);?? ?//擊敗的敵機(jī)清空 ?? ?void enemyMove();//敵機(jī)移動 ?? ?void printScore();//輸出分?jǐn)?shù) }; //主菜單 int drawMenu(); //隱藏光標(biāo) void HideCursor(); void SetPos(int i, int j);//設(shè)置光標(biāo) COORD random(COORD a, COORD b);//產(chǎn)生隨機(jī)敵機(jī)位置 void drawFrame(COORD a, COORD ?b, char row, char col);//畫出敵機(jī) //把第y行,[x1, x2) 之間的坐標(biāo)填充為 ch void drawRow(int y, int x1, int x2, char ch); //把第x列,[y1, y2] 之間的坐標(biāo)填充為 ch void drawCol(int x, int y1, int y2, char ch); // 繪制游戲界面 void drawPlaying(); void drawFrame(Frame frame, char row, char col);//畫墜毀后的戰(zhàn)機(jī) // 該函數(shù)用來判斷戰(zhàn)機(jī)的某一部分是否與敵機(jī)有接觸 bool ?judgeCoordInFrame(Frame frame, COORD spot); void drawRow(COORD a, COORD b, char ch);
game.cpp:
#include"game.h" #include<Windows.h> #include<conio.h> Game::Game() { ?? ?// 調(diào)用類成員函數(shù)來進(jìn)行初始化 ?? ?initPlane(); ?? ?initBullet(); ?? ?initEnemy(); ?? ?// 初始化四個int型數(shù)據(jù)成員,采用賦值的方式進(jìn)行初始化 ?? ?// string類型的數(shù)據(jù)成員title沒有進(jìn)行初始化,因?yàn)椋? ?? ?// string本身就是一個標(biāo)準(zhǔn)庫類類型,它的類定義中設(shè)置了默認(rèn)構(gòu)造函數(shù), ?? ?// 這些默認(rèn)構(gòu)造函數(shù)會將對象初始化為合理的默認(rèn)狀態(tài), ?? ?// ?string的默認(rèn)構(gòu)造函數(shù)會產(chǎn)生空字符串,相當(dāng)于"" 。 ?? ?this->score = 0; ?? ?rank = 25; ?? ?rankf = 25; ?? ?flag_rank = 0; } void Game::initPlane() { ?? ?COORD centren; ?? ?centren.X = 39; ?? ?centren.Y = 22; ?? ?position[0].X = position[5].X = position[7].X = position[9].X = centren.X; ?? ?position[1].X = centren.X - 2; ?? ?position[2].X = position[6].X = centren.X - 1; ?? ?position[3].X = position[8].X = centren.X + 1; ?? ?position[4].X = centren.X + 2; ?? ?for (int i = 0; i <= 4; i++) ?? ?{ ?? ??? ?position[i].Y = centren.Y; ?? ?} ?? ?for (int i = 6; i <= 8; i++) ?? ?{ ?? ??? ?position[i].Y = centren.Y + 1; ?? ?} ?? ?position[5].Y = centren.Y - 1; ?? ?position[9].Y = centren.Y - 2; ?? ??? ? ?? ?// 這個函數(shù)體類的代碼其實(shí)就是為了初始化戰(zhàn)機(jī)的十個部分的位置,戰(zhàn)機(jī)的組成如下所示: ?? ?? ?// ? ? ? ? ? ? ? ? ? | ? ? ? 5? ?? ?//?? ??? ??? ??? ? ? ? | ? ? ? 9 ? ? ?? ?//?? ??? ??? ??? ? ? ***** ? 12034 ?? ?//?? ??? ??? ??? ? ? ?*** ? ? 678 ?? ?// ? 第一排5個0的坐標(biāo)依次對應(yīng)了position[1]position[2]position[0]position[3]position[4] ?? ?// ? 第二排三個0的坐標(biāo)依次對應(yīng)了position[6]position[7]position[8] ?? ?// ? 兩排0上面的兩|的坐標(biāo)從上往下依次對應(yīng)了position[5]position[9] } void Game::drawPlane() { ?? ?for (int i = 0; i < 9; i++) ?? ?{ ?? ??? ?SetPos(position[i].X,position[i].Y); ?? ??? ?if (i != 5) ?? ??? ?{ ?? ??? ??? ?cout << "*"; ?? ??? ?} ?? ??? ?else if (i == 5) ?? ??? ?{ ?? ??? ??? ?cout << "|"; ?? ??? ?} ?? ?} } // 這個成員函數(shù)通過將戰(zhàn)機(jī)的每個坐標(biāo)處輸出" "來代替"0"和"|", // 來達(dá)到將戰(zhàn)機(jī)消除的目的。 void Game::drawPlaneToNull() { ?? ?for (int i = 0; i < 9; i++) ?? ?{ ?? ??? ?SetPos(position[i].X, position[i].Y); ?? ??? ?cout << " "; ?? ?} } // 該成員函數(shù)用來初始化子彈, // 即將每個子彈的Y坐標(biāo)初始化為30(bullet[i].Y = 30)來表示子彈處于失效狀態(tài) void Game::initBullet() { ?? ?for (int i = 0; i < 10; i++) ?? ?{ ?? ??? ?bullet[i].Y = 30; ?? ?}?? ? } // 該成員函數(shù)用來畫出子彈 // 首先檢查每顆子彈的有效性,如果子彈有效,則定位到該子彈的坐標(biāo)處,輸出 "^",表示該子彈, // 如果子彈是無效的,則不繪制 void Game::drawBullet() { ?? ?for (int i = 0; i < 10; i++) ?? ?{ ?? ??? ?if (bullet[i].Y != 30) ?? ??? ?{ ?? ??? ??? ?SetPos(bullet[i].X,bullet[i].Y); ?? ??? ??? ?cout << "^"; ?? ??? ?} ?? ?} } //子彈失效 void Game::drawBulletToNull() { ?? ?for (int i = 0; i < 10; i++) ?? ??? ?if (bullet[i].Y != 30) ?? ??? ?{ ?? ??? ??? ?SetPos(bullet[i].X, bullet[i].Y + 1); ?? ??? ??? ?cout << " "; ?? ??? ?} } // 這個函數(shù)用來初始敵機(jī)的位置, // 屏幕當(dāng)中只能同時(shí)存在八架敵機(jī), // 且每架敵機(jī)用如下結(jié)構(gòu)體Frame來表示,如下所示: // ? ? typedef struct Frame // ? ? ? ?{ //?? ? ? ? ?COORD position[2]; // ? ? ??? ?int flag; // ? ? ? ?}Frame; COORD random(COORD a, COORD b) { ?? ?int x = rand() % (a.X - b.X) + a.X; ?? ?int y = rand() % (a.Y - b.Y) + a.Y; ?? ?COORD c = { x,y }; ?? ?return c; } void Game::initEnemy() { ?? ?COORD a = { 1, 1 }; ?? ?COORD b = { 45, 15 }; ?? ?for (int i = 0; i < 8; i++) ?? ?{ ?? ??? ?enemy[i].position[0] = random(a, b); ?? ??? ?// ?random(a, b)是調(diào)用了一個重載的函數(shù),它表示在坐標(biāo)a、b之間的矩形框 ?? ??? ?// ?內(nèi)隨機(jī)生成一個坐標(biāo)值,并將該坐標(biāo)值作為敵機(jī)的左上角的坐標(biāo)。 ?? ??? ?// enemy[i].position[0]中是一個Frame結(jié)構(gòu)體類型的變量,存放了敵機(jī)i的左上角的坐標(biāo)。 ?? ??? ?enemy[i].position[1].X = enemy[i].position[0].X + 3; ?? ??? ?enemy[i].position[1].Y = enemy[i].position[0].Y + 2; ?? ??? ?// enemy[i].position[1]也中是一個Frame結(jié)構(gòu)體類型的變量,存放了敵機(jī)i的右下角的坐標(biāo)。 ?? ?} } // 接下來要根據(jù)敵機(jī)的左上角坐標(biāo)和右下角坐標(biāo)畫出敵機(jī), // 顯然,敵機(jī)的外形如下所示: // ? -- // ?| ?| // ? -- void Game::drawEnemy() { ?? ?for (int i = 0; i < 8; i++) ?? ?{ ?? ??? ?drawFrame(enemy[i].position[0], enemy[i].position[1], '-', '|'); ?? ?}?? ? } // 將敵機(jī)消除,通過輸出空白的方式 void Game::drawEnemyToNull() { ?? ?for (int i = 0; i < 8; i++) ?? ?{ ?? ??? ?drawFrame(enemy[i].position[0], enemy[i].position[1], ' ', ' '); ?? ?} } //隱藏光標(biāo) void HideCursor() { ?? ?CONSOLE_CURSOR_INFO cursor_info = { 1,0 };//第二個值0表示隱藏光標(biāo) ?? ?SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); } void SetPos(int i, int j)//設(shè)置坐標(biāo)點(diǎn)位(光標(biāo)) { ?? ?HANDLE hout; ?? ?COORD coord; ?? ?coord.X = i; ?? ?coord.Y = j; ?? ?hout = GetStdHandle(STD_OUTPUT_HANDLE); ?? ?SetConsoleCursorPosition(hout, coord); } //左上角坐標(biāo)、右下角坐標(biāo)、用row填充行、用col填充列 void drawFrame(COORD a, COORD ?b, char row, char col) { ?? ?drawRow(a.Y, a.X + 1, b.X - 1, row); ?? ?drawRow(b.Y, a.X + 1, b.X - 1, row); ?? ?drawCol(a.X, a.Y + 1, b.Y - 1, col); ?? ?drawCol(b.X, a.Y + 1, b.Y - 1, col); } //把第y行,[x1, x2) 之間的坐標(biāo)填充為 ch void drawRow(int y, int x1, int x2, char ch) { ?? ?SetPos(x1, y); ?? ?for (int i = 0; i <= (x2 - x1); i++) ?? ?{ ?? ??? ?cout << ch; ?? ?} } //把第x列,[y1, y2] 之間的坐標(biāo)填充為 ch void drawCol(int x, int y1, int y2, char ch) { ?? ?int y = y1; ?? ?while (y != y2 + 1) ?? ?{ ?? ??? ?SetPos(x, y); ?? ??? ?cout << ch; ?? ??? ?y++; ?? ?} } //主菜單繪制 int drawMenu() { ?? ?SetPos(30,1); ?? ?cout << "飛 機(jī) 大 戰(zhàn)"; ?? ?drawRow(3, 0, 79, '-'); ?? ?drawRow(5, 0, 79, '-'); ?? ?SetPos(28, 4); ?? ?cout << "w 和 s選擇,k確定"; ?? ?int j = 11; ?? ?SetPos(12, j); ?? ?cout << ">>"; ?? ?SetPos(15, 11); ?? ?cout << "1. 簡單的敵人"; ?? ?SetPos(15, 13); ?? ?cout << "2. 冷酷的敵人"; ?? ?drawRow(20, 0, 79, '-'); ?? ?SetPos(47, 11); ?? ?cout << "簡單的敵人:"; ?? ?SetPos(47, 13); ?? ?cout << "簡單敵人有著較慢的移動速度。"; ?? ?SetPos(30, 21); ?? ?cout << "copy right@風(fēng)兮木蕭"; ?? ?drawRow(22, 0, 79, '-'); ?? ?while (true) ?? ?{ ?? ??? ?if (_kbhit()) ?? ??? ?{ ?? ??? ??? ?char x = _getch(); ?? ??? ??? ?switch (x) ?? ??? ??? ?{ ?? ??? ??? ?case'w': ?? ??? ??? ?{ ?? ??? ??? ??? ?if (j == 13) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?SetPos(12, j); ?? ??? ??? ??? ??? ?cout << " ?"; ?? ??? ??? ??? ??? ?j = 11; ?? ??? ??? ??? ??? ?SetPos(12, j); ?? ??? ??? ??? ??? ?cout << ">>"; ?? ??? ??? ??? ??? ?SetPos(51, 13); ?? ??? ??? ??? ??? ?cout << " "; ?? ??? ??? ??? ??? ?SetPos(47, 11); ?? ??? ??? ??? ??? ?cout << "簡單的敵人:"; ?? ??? ??? ??? ??? ?SetPos(51, 13); ?? ??? ??? ??? ??? ?cout << "簡單敵人有著較慢的移動速度,比較容易對付"; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?break; ?? ??? ??? ?} ?? ??? ??? ?case's': ?? ??? ??? ?{ ?? ??? ??? ??? ?if (j == 11) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?SetPos(12, j); ?? ??? ??? ??? ??? ?cout << " "; ?? ??? ??? ??? ??? ?j = 13; ?? ??? ??? ??? ??? ?SetPos(12, j); ?? ??? ??? ??? ??? ?cout << ">>"; ?? ??? ??? ??? ??? ?SetPos(51, 13); ?? ??? ??? ??? ??? ?cout << " ? ? ? ? ? ? ? ? ? "; ?? ??? ??? ??? ??? ?SetPos(47, 11); ?? ??? ??? ??? ??? ?cout << "冷酷的敵人:"; ?? ??? ??? ??? ??? ?SetPos(51, 13); ?? ??? ??? ??? ??? ?cout << "冷酷的敵人移動速度較快,難對付喲。"; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?break; ?? ??? ??? ?} ?? ??? ??? ?case 'k': ?? ??? ??? ?{ ?? ??? ??? ??? ? ?? ??? ??? ??? ?if (j == 11)//源代碼為8? ?? ??? ??? ??? ??? ?return 1; ?? ??? ??? ??? ?else ?? ??? ??? ??? ??? ?return 2; ?? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?return 0; } void drawFrame(int x1, int y1, int x2, int y2, char row, char col) { ?? ?COORD a = { x1, y1 }; ?? ?COORD b = { x2, y2 }; ?? ?drawFrame(a, b, row, col); } // 繪制游戲界面 void drawPlaying() { ?? ?drawFrame(0, 0, 48, 24, '=', '|');//?? ?draw map frame主界面 ?? ?drawFrame(49, 0, 79, 4, '-', '|');//?? ?draw output frame 狀態(tài)界面 ?? ?drawFrame(49, 4, 79, 9, '-', '|');//?? ?draw score frame 分?jǐn)?shù)界面 ?? ?drawFrame(49, 9, 79, 20, '-', '|');//?? ?draw operate frame 操作界面 ?? ?drawFrame(49, 20, 79, 24, '-', '|');//?? ?draw other message frame 提示界面 ?? ?SetPos(52, 6); ?? ?cout << "得分:"; ?? ?SetPos(52, 7); ?? ?cout << "稱號:"; ?? ?SetPos(52, 11); ?? ?cout << "操作方式:"; ?? ?SetPos(52, 13); ?? ?cout << " ?a,s,d,w:控制戰(zhàn)機(jī)移動。"; ?? ?SetPos(52, 15); ?? ?cout << " ?p:暫停游戲。"; ?? ?SetPos(52, 17); ?? ?cout << " ?e:退出游戲。"; ?? ?SetPos(52, 22); ?? ?cout << " 游戲雖好玩,不要貪多哦 "; } // 該成員函數(shù)用過響應(yīng)戰(zhàn)機(jī)的一個動作 // a,s,w,d,來控制戰(zhàn)機(jī)的移動 void Game::planeMove(char x) { ?? ?if (x == 'a') ?? ?{ ?? ??? ?if (position[1].X != 1) ?? ??? ?{ ?? ??? ??? ?for (int i = 0; i <= 9; i++) ?? ??? ??? ?{ ?? ??? ??? ??? ?position[i].X -= 2; ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?// 如果玩家按下 'a' 鍵,說明玩家想讓戰(zhàn)機(jī)往左移動一個距離(2個單位), ?? ?// 首先檢測,戰(zhàn)機(jī)的最左側(cè)的位置坐標(biāo)(即position[1].X)有沒有達(dá)到左邊界, ?? ?// 如果到達(dá)了邊界,那就不做出移動;如果沒有達(dá)到邊界,則將戰(zhàn)機(jī)10個部分的X值減小2。 ?? ?if (x == 's') ?? ?{ ?? ??? ?if (position[7].Y != 23) ?? ??? ?{ ?? ??? ??? ?for (int i = 0; i <= 9; i++) ?? ??? ??? ?{ ?? ??? ??? ??? ?position[i].Y += 1; ?? ??? ??? ?} ?? ??? ?} ?? ?}?? ??? ? ?? ?// 如果玩家按下 's' 鍵,說明玩家想讓戰(zhàn)機(jī)往下移動一個距離(1個單位), ?? ?// 首先檢測,戰(zhàn)機(jī)的最底部的位置坐標(biāo)(即position[6].Y或者position[7].Y或者position[8].Y)有沒有達(dá)到下邊界, ?? ?// ?如果到達(dá)了邊界,那就不做出移動;如果沒有達(dá)到邊界,則將戰(zhàn)機(jī)10個部分的Y值增加1。 ?? ?if (x == 'd' && (position[4].X != 47)) ?? ?{ ?? ??? ?for (int i = 0; i <= 9; i++) ?? ??? ?{ ?? ??? ??? ?position[i].X += 2; ?? ??? ?}?? ? ?? ?}?? ??? ? ?? ?// 如果玩家按下 'd' 鍵,說明玩家想讓戰(zhàn)機(jī)往右移動一個距離(2個單位), ?? ?// 首先檢測,戰(zhàn)機(jī)的最右側(cè)的位置坐標(biāo)(即position[4].X)有沒有達(dá)到右邊界, ?? ?// ?如果到達(dá)了邊界,那就不做出移動;如果沒有達(dá)到邊界,則將戰(zhàn)機(jī)10個部分的X值增加2。 ?? ?if (x == 'w'&&(position[5].Y != 3)) ?? ?{ ?? ??? ?for (int i = 0; i <= 9; i++) ?? ??? ?{ ?? ??? ??? ?position[i].Y -= 1; ?? ??? ?} ?? ?} ?? ?// 如果玩家按下'w'鍵,說明玩家想讓戰(zhàn)機(jī)往上移動一個距離(1個單位), ?? ?// 首先檢測,戰(zhàn)機(jī)的最頂部的位置坐標(biāo)(即position[5].Y)有沒有達(dá)到上邊界, ?? ?// ?如果到達(dá)了邊界,那就不做出移動;如果沒有達(dá)到邊界,則將戰(zhàn)機(jī)10個部分的Y值減少1。 } // 該函數(shù)用來判斷戰(zhàn)機(jī)的某一部分是否與敵機(jī)有接觸 // 如果與敵機(jī)有接觸在判斷為墜毀 bool ?judgeCoordInFrame(Frame frame, COORD spot) { ?? ?if ((spot.X >= frame.position[0].X) && (spot.X <= frame.position[1].X) && (spot.Y >= frame.position[0].Y) && (spot.Y <= frame.position[1].Y)) ?? ?{ ?? ??? ?return true; ?? ?} ?? ?return false; } void drawFrame(Frame frame, char row, char col) { ?? ?COORD a = frame.position[0]; ?? ?COORD b = frame.position[1]; ?? ?drawFrame(a, b, row, col); } //游戲結(jié)束 void Game::GameOver() { ?? ?system("cls"); ?? ?COORD p1 = { 28,9 }; ?? ?COORD p2 = { 53,15 }; ?? ?drawFrame(p1, p2, '=', '|'); ?? ?SetPos(36, 12); ?? ?string str = "Game Over!"; ?? ?for (int i = 0; i < str.size(); i++) ?? ?{ ?? ??? ?Sleep(80); ?? ??? ?cout << str[i]; ?? ?} ?? ?Sleep(1000); ?? ?system("cls"); ?? ?drawFrame(p1, p2, '=', '|'); ?? ?SetPos(31, 11); ?? ?cout << "擊落敵機(jī):" << score / 5 << " 架"; ?? ?SetPos(31, 12); ?? ?cout << "得 分:" << score; ?? ?SetPos(31, 13); ?? ?cout << "獲得稱號:" << title; ?? ?SetPos(30, 18); ?? ?Sleep(1000); ?? ?cout << "繼續(xù)? 是(y)| 否(n)"; as://goto 語句標(biāo)簽 直接跳轉(zhuǎn)至此 ?? ?char x = _getch(); ?? ?if (x == 'n') ?? ?{ ?? ??? ?exit(0); ?? ?} ?? ?else if (x == 'y') ?? ?{ ?? ??? ?system("cls"); ?? ??? ?Game game; ?? ??? ?int a = drawMenu(); ? ? ? // 繪制游戲開始界面主菜單 ?? ??? ?if (a == 2) ?? ??? ??? ?game.rank = 20; ?? ??? ?system("cls"); ?? ??? ?drawPlaying(); ? ? ? ? ? // 繪制游戲界面框架 ?? ??? ?game.Playing(); ?? ?} ?? ?else? ?? ??? ?goto as; } // 該成員函數(shù)用來判斷戰(zhàn)機(jī)是否墜毀, // 依次判斷每架敵機(jī)與戰(zhàn)機(jī)的每個部分是否有接觸, // 如果有接觸,則表示戰(zhàn)機(jī)墜毀 void Game::judgePlane() { ?? ?for (int i = 0; i < 8; i++) ?? ?{ ?? ??? ?for (int j = 0; j < 9; j++) ?? ??? ??? ?// 此處的實(shí)參position[j]是指戰(zhàn)機(jī)的10個部分的COORD坐標(biāo), ?? ??? ??? ?// 類中的成員函數(shù)可以訪問數(shù)據(jù)成員變量。 ?? ??? ??? ?// 此處也可以寫成this-> position[j],因?yàn)? ?? ??? ??? ?// 成員函數(shù)具有一個附加的隱含形參,即指向該類對象的一個指針, ?? ??? ??? ?// 這個隱含形參命名為this,與調(diào)用成員函數(shù)的對象綁定在一起。 ?? ??? ??? ?// 成員函數(shù)不能定義this形參,而是由編譯器隱含地定義。 ?? ??? ??? ?// 成員函數(shù)的函數(shù)體可以顯式使用this指針,但不是必須這么做。 ?? ??? ??? ?if (judgeCoordInFrame(enemy[i], position[j])) ?? ??? ??? ?{ ?? ??? ??? ??? ?SetPos(62, 1); ?? ??? ??? ??? ?cout << "墜毀"; ?? ??? ??? ??? ?drawFrame(enemy[i], '+', '+'); ?? ??? ??? ??? ?// 將與戰(zhàn)機(jī)相撞的敵機(jī)的形狀繪制為: ?? ??? ??? ??? ?// ? ?++ ?? ??? ??? ??? ?// ? + ?+ ?? ??? ??? ??? ?// ? ?++ ?? ??? ??? ??? ?Sleep(1000); ?? ??? ??? ??? ?GameOver(); ?? ??? ??? ??? ?break; ?? ??? ??? ?} ?? ?} } // 該成員函數(shù)用來使得游戲暫停 void Game::Pause() { ?? ?SetPos(61, 2); ?? ?cout << " ? ? ? ? "; ?? ?SetPos(61, 2); ?? ?cout << "暫停中..."; ?? ?// 當(dāng)出現(xiàn)"暫停中..."的提示以后,程序不停的接收按下的按鍵, ?? ?// 當(dāng)按下'p'鍵以后,說明要退出暫停狀態(tài),此時(shí)需要清除"暫停中..."的提示 ?? ?// 通過輸出空白 " ? ? ? ? "來將其覆蓋,達(dá)到效果 ?? ?char c = _getch(); ?? ?while (c != 'p') ?? ?{ ?? ??? ?c = _getch(); ?? ?} ?? ?SetPos(61, 2); ?? ?cout << " ? ? ? ? "; } // 這個成員函數(shù)用來響應(yīng)一次射擊操作, // 也就是,當(dāng)游戲中的時(shí)候,玩家按下"k"鍵,就執(zhí)行該函數(shù)。 // 由于子彈是由COORD bullet[10]定義的,因此同一時(shí)刻,界面內(nèi)只能有10顆子彈同時(shí)出現(xiàn)。 // 如果界面內(nèi)不夠10顆子彈,按下"k"鍵后戰(zhàn)機(jī)應(yīng)該發(fā)射出一顆子彈, // 于是,依次遍歷10顆子彈,當(dāng)遇到第一顆失效的子彈后, // 立即將該子彈賦予新的坐標(biāo)(戰(zhàn)機(jī)的炮口,也就是(position[5].X,position[5].Y - 1)), // 讓其激活。然后退出for循環(huán),函數(shù)執(zhí)行完畢。 void Game::Shoot() { ?? ?for (int i = 0; i < 10; i++) ?? ?{? ?? ??? ?if (bullet[i].Y == 30) ?? ??? ?{ ?? ??? ??? ?bullet[i].X = position[5].X; ?? ??? ??? ?bullet[i].Y = position[5].Y - 1; ?? ??? ??? ?break; ?? ??? ?} ?? ?} } void Game::drawThisBulletToNull(COORD c) { ?? ?SetPos(c.X,c.Y); ?? ?cout << " "; } // 此成員函數(shù)用來響應(yīng)一次子彈的運(yùn)動 // 每次子彈運(yùn)動,屏幕子彈的坐標(biāo)都會出現(xiàn)變化,即 // 先判斷子彈是否有效(即判斷語句if (bullet[i].Y != 30)), // 若子彈有效,將該子彈的Y坐標(biāo)減少1,X坐標(biāo)不變, // 檢測子彈坐標(biāo)更改之后是否達(dá)到上邊界,如果達(dá)到上邊界,則將該子彈從屏幕上擦除, // 同時(shí),將該子彈置為失效狀態(tài),即 bullet[i].Y = 30。 void Game::bulletMove() { ?? ?for (int i = 0; i < 10; i++) ?? ?{ ?? ??? ?if (bullet[i].Y != 30) ?? ??? ?{ ?? ??? ??? ?bullet[i].Y -= 1; ?? ??? ??? ?if (bullet[i].Y == 1) ?? ??? ??? ?{ ?? ??? ??? ??? ?COORD pos = { bullet[i].X, bullet[i].Y + 1 }; ?? ??? ??? ??? ?drawThisBulletToNull(pos); ?? ??? ??? ??? ?bullet[i].Y = 30; ?? ??? ??? ?} ?? ??? ?} ?? ?} } //擊敗的敵機(jī)清空 void Game::drawThisEnemyToNull(Frame f) { ?? ?drawFrame(f, ' ', ' '); } // 該成員函數(shù)依次遍歷每一架敵機(jī), // 將每一架敵機(jī)依次與每一顆子彈進(jìn)行檢測, // 判斷敵機(jī)是否與子彈有接觸,如果有接觸,則表示擊中敵機(jī), // 此時(shí)將敵機(jī)和子彈擦除,然后在界面頂部的位置處隨機(jī)生成一架敵機(jī) void Game::judgeEnemy() { ?? ?for (int i = 0; i < 8; i++) ?? ?{ ?? ??? ?for (int j = 0; j < 10; j++) ?? ??? ?{ ?? ??? ??? ?if (judgeCoordInFrame(enemy[i], bullet[j])) ?? ??? ??? ?{ ?? ??? ??? ??? ?score += 5; ?? ??? ??? ??? ?drawThisEnemyToNull(enemy[i]); ?? ??? ??? ??? ?COORD a = { 1, 1 }; ?? ??? ??? ??? ?COORD b = { 45, 3 }; ?? ??? ??? ??? ?enemy[i].position[0] = random(a, b); ?? ??? ??? ??? ?enemy[i].position[1].X = enemy[i].position[0].X + 3; ?? ??? ??? ??? ?enemy[i].position[1].Y = enemy[i].position[0].Y + 2; ?? ??? ??? ??? ?drawThisBulletToNull(bullet[j]); ?? ??? ??? ??? ?bullet[j].Y = 30; ?? ??? ??? ?} ?? ??? ?} ?? ?} } // 該成員函數(shù)用來響應(yīng)一次敵機(jī)的移動 // 界面上必須同時(shí)出現(xiàn)八架敵機(jī),因此, // 如果有某架敵機(jī)運(yùn)動到下邊界處,則重置該敵機(jī)的坐標(biāo) void Game::enemyMove() { ?? ?for (int i = 0; i < 8; i++) ?? ?{ ?? ??? ?for (int j = 0; j < 2; j++) ?? ??? ??? ?enemy[i].position[j].Y++; ?? ??? ?// 我們將每架敵機(jī)的左上角和右下角坐標(biāo)的Y值增加1, ?? ??? ?// 表示該敵機(jī)向下走了一個距離 ?? ??? ? ?? ??? ?// 檢測向下走一個距離后的敵機(jī)的右下角坐標(biāo)的Y值是否達(dá)到24, ?? ??? ?// 如果達(dá)到,代表敵機(jī)已經(jīng)運(yùn)動到下邊界了, ?? ??? ?// 此時(shí)需要隨機(jī)重置該敵機(jī)的坐標(biāo) ?? ??? ?if (enemy[i].position[1].Y==24) ?? ??? ?{ ?? ??? ??? ?COORD a = { 1, 1 }; ?? ??? ??? ?COORD b = { 45, 3 }; ?? ??? ??? ?enemy[i].position[0] = random(a, b); ?? ??? ??? ?enemy[i].position[1].X = enemy[i].position[0].X + 3; ?? ??? ??? ?enemy[i].position[1].Y = enemy[i].position[0].Y + 2; ?? ??? ?} ?? ?} } void Game::printScore() { ?? ?if (score <= 120) ?? ?{ ?? ??? ?flag_rank = 1; ?? ?} ?? ?else if (score > 120 && score <= 360) ?? ?{ ?? ??? ?flag_rank = 2; ?? ?} ?? ?else if (score > 360 && score <= 480) ?? ?{ ?? ??? ?flag_rank = 3; ?? ?} ?? ?else if (score > 480) ?? ?{ ?? ??? ?flag_rank = 4; ?? ?} ?? ?SetPos(60, 6); ?? ?cout << score; ?? ?SetPos(60, 7); ?? ?if (flag_rank == 1) ?? ?{ ?? ??? ?title = "初級飛行員"; ?? ?} ?? ?else if (flag_rank == 2) ?? ?{ ?? ??? ?title = "中級飛行員"; ?? ?} ?? ?else if (flag_rank == 3) ?? ?{ ?? ??? ?title = "高級飛行員"; ?? ?} ?? ?else if (flag_rank == 4) ?? ?{ ?? ??? ?title = "王牌飛行員"; ?? ?} ?? ?cout << title; } // 這個成員函數(shù)是游戲的主循環(huán)函數(shù), // 定義了整個游戲過程。 void Game::Playing() { ?? ?drawEnemy(); ?? ?drawPlane(); ?? ?int flag_bullet = 0; ?? ?int flag_enemy = 0; ?? ?while (true) ?? ?{ ?? ??? ?Sleep(20); ?? ??? ?// 函數(shù)名:kbhit()(VC++6.0下為_kbhit()) ?? ??? ?// 功能及返回值: 檢查當(dāng)前是否有鍵盤輸入,若有則返回一個非0值,否則返回0 ?? ??? ?// 用法:int kbhit(void); ?? ??? ?// 包含頭文件: include <conio.h> ?? ??? ?// kbhit()在執(zhí)行時(shí),檢測是否有按鍵按下,有按下返回非0值,沒有按下則返回0,是非阻塞函數(shù); ?? ??? ?// 不同于getch()的在執(zhí)行時(shí), 檢測按下什么鍵, 如果不按鍵該函數(shù)不返回,也就不進(jìn)行下一步操作,是阻塞函數(shù)。 ?? ??? ?if (_kbhit()) ?? ??? ?{ ?? ??? ??? ?char x = _getch(); ?? ??? ??? ?// getch()是編程中所用的函數(shù),這個函數(shù)是一個不回顯函數(shù), ?? ??? ??? ?// 當(dāng)用戶按下某個字符時(shí),函數(shù)自動讀取,無需按回車 ?? ??? ??? ?// getch()并非標(biāo)準(zhǔn)C中的函數(shù),不存在C語言中。 ?? ??? ??? ?// 所在頭文件是conio.h,而不是stdio.h。 ?? ??? ??? ?// 用ch = getch(); 會等待你按下任意鍵之后,把該鍵字符所對應(yīng)的ASCII碼賦給ch, 再執(zhí)行下面的語句。 ?? ??? ??? ?if ('a' == x || 's' == x || 'd' == x || 'w' == x) ?? ??? ??? ?{ ?? ??? ??? ??? ?drawPlaneToNull(); ? ? // 將戰(zhàn)機(jī)先擦除 ?? ??? ??? ??? ?planeMove(x); ? ? ? ? ?// 根據(jù)所輸入的操作符,對戰(zhàn)機(jī)的坐標(biāo)進(jìn)行更改 ?? ??? ??? ??? ?drawPlane(); ? ? ? ? ? // 訪問類中的數(shù)據(jù)成員——戰(zhàn)機(jī)的坐標(biāo),在新的坐標(biāo)處重新繪制戰(zhàn)機(jī) ?? ??? ??? ??? ?judgePlane(); ? ? ? ? ?// 判斷戰(zhàn)機(jī)是否有墜毀 ?? ??? ??? ?} ?? ??? ??? ?// ?在某一循環(huán)當(dāng)中,如果檢測到有'p'鍵按下, ?? ??? ??? ?// 首先在右側(cè)游戲界面輸出"暫停中...",然后陷入while()循環(huán)一直等待'p'鍵再次按下, ?? ??? ??? ?// 如果'p'鍵沒有按下,就一直處在while()循環(huán)內(nèi),因此不能執(zhí)行后面的程序,起到暫停的效果。 ?? ??? ??? ?else if ('p' == x) ?? ??? ??? ?{ ?? ??? ??? ??? ?Pause(); ?? ??? ??? ?} ?? ??? ??? ?// 如果是檢測到'k'鍵按下,則運(yùn)行Shoot()函數(shù), ?? ??? ??? ?else if ('k' == x) ?? ??? ??? ?{ ?? ??? ??? ??? ?Shoot(); ?? ??? ??? ?} ?? ??? ??? ?// 如果是檢測到'k'鍵按下,則運(yùn)行GameOver()函數(shù), ?? ??? ??? ?// GameOver()函數(shù)執(zhí)行完畢后,執(zhí)行break;語句跳出while循環(huán)(注意不是if (_kbhit()))。 ?? ??? ??? ?// break語句用于結(jié)束最近的while、do while、for或switch語句,并將程序的執(zhí)行權(quán)傳遞給緊接在 ?? ??? ??? ?// 被終止語句之后的語句。 ?? ??? ??? ?else if ('e' == x) ?? ??? ??? ?{ ?? ??? ??? ??? ?//CloseHandle(MFUN) ?? ??? ??? ??? ?GameOver(); ?? ??? ??? ??? ?break; ?? ??? ??? ?} ?? ??? ?} ?? ??? ?// 接下來處理子彈 ?? ??? ?// 判斷子彈狀態(tài)的程序一直在運(yùn)行 ?? ??? ?if (flag_bullet == 0) ?? ??? ?{ ?? ??? ??? ?bulletMove(); ? ? ? ? ? // 更新界面上有效子彈的坐標(biāo) ?? ??? ??? ?drawBulletToNull(); ? ? // 將處于舊坐標(biāo)的子彈擦除 ?? ??? ??? ?drawBullet(); ? ? ? ? ? // 繪制出新坐標(biāo)上的子彈 ?? ??? ??? ?judgeEnemy(); ? ? ? ? ?// 判斷敵機(jī)是否被子彈擊中 ?? ??? ?} ?? ??? ?flag_bullet++; ?? ??? ?if (flag_bullet==1) ?? ??? ?{ ?? ??? ??? ?flag_bullet = 0; ?? ??? ?} ?? ??? ?// ?接下來處理敵機(jī) ?? ??? ?if (flag_enemy==0) ?? ??? ?{ ?? ??? ??? ?drawEnemyToNull(); ? ? // 將所有的敵機(jī)都擦除 ?? ??? ??? ?enemyMove(); ? ? ? ? ? // ?更新敵機(jī)的坐標(biāo) ?? ??? ??? ?drawEnemy(); ? ? ? ? ? // 繪制出處于新坐標(biāo)上的敵機(jī) ?? ??? ??? ?judgePlane(); ? ? ? ? ?// 判斷敵機(jī)是否與戰(zhàn)機(jī)接觸 ?? ??? ?} ?? ??? ?flag_enemy++; ?? ??? ?if (flag_enemy >= rank) ?? ??? ?{ ?? ??? ??? ?flag_enemy = 0; ?? ??? ?} ?? ??? ?/* 輸出得分 */ ?? ??? ?printScore(); ?? ?} }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++單例模式為何要實(shí)例化一個對象不全部使用static
這篇文章主要介紹了C++單例模式為何要實(shí)例化一個對象不全部使用static,文基于C++圍繞主題展開詳細(xì)內(nèi)容,需要的小伙伴可以參考一下2022-05-05Cocos2d-x UI開發(fā)之CCControlColourPicker控件類使用實(shí)例
這篇文章主要介紹了Cocos2d-x UI開發(fā)之CCControlColourPicker控件類使用實(shí)例,本文代碼中包含大量注釋來講解CCControlColourPicker控件類的使用,需要的朋友可以參考下2014-09-09C/C++?Qt?TreeWidget?單層樹形組件應(yīng)用小結(jié)
TreeWidget?目錄樹組件,該組件適用于創(chuàng)建和管理目錄樹結(jié)構(gòu),在開發(fā)中我們經(jīng)常會把它當(dāng)作一個升級版的ListView組件使用,本文將通過TreeWidget實(shí)現(xiàn)多字段顯示,并增加一個自定義菜單,通過在指定記錄上右鍵可彈出該菜單并對指定記錄進(jìn)行操作2021-11-11詳解VisualS tudio Code開發(fā)Arm嵌入式Linux應(yīng)用
本文介紹如何在 Visual Studio Code 中使用 Yocto Project 生成的 Linux SDK,并針對 Arm 處理器進(jìn)行 C/C++ 應(yīng)用交叉編譯和調(diào)試,感興趣的朋友跟隨小編一起看看吧2021-04-04數(shù)據(jù)結(jié)構(gòu) 雙向鏈表的創(chuàng)建和讀取詳解及實(shí)例代碼
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu) 雙向鏈表的創(chuàng)建和讀取詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-03-03Qt音視頻開發(fā)之視頻文件保存功能的實(shí)現(xiàn)
和音頻存儲類似,視頻的存儲也對應(yīng)三種格式,視頻最原始的數(shù)據(jù)是yuv(音頻對應(yīng)pcm),視頻壓縮后的數(shù)據(jù)是h264(音頻對應(yīng)aac)。本文將利用Qt實(shí)現(xiàn)視頻文件保存功能,感興趣的可以了解一下2022-12-12C++線性表深度解析之動態(tài)數(shù)組與單鏈表和棧及隊(duì)列的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)動態(tài)數(shù)組、單鏈表、棧、隊(duì)列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05