C++ vector容器實現(xiàn)貪吃蛇小游戲
本文實例為大家分享了C++ vector容器 實現(xiàn)貪吃蛇,供大家參考,具體內(nèi)容如下
使用vector容器實現(xiàn)貪吃蛇簡化了很多繁瑣操作,且相比之前我的代碼已經(jīng)做到了盡量的簡潔
技術(shù)環(huán)節(jié):
編譯環(huán)境:windows VS2019
需求:
控制貪吃蛇吃食物,吃到一個食物蛇身變長一節(jié),得分增加,撞墻或撞自己則游戲結(jié)束。
思路:
創(chuàng)建一個vector容器,容器內(nèi)存儲蛇的每節(jié)身體的結(jié)構(gòu)變量,結(jié)構(gòu)變量中保存蛇身體的xy坐標(biāo),通過使用vector成員方法不斷添加和刪除容器中的數(shù)據(jù),實現(xiàn)蛇坐標(biāo)的規(guī)律移動,吃到食物等時執(zhí)行對應(yīng)操作。
在代碼注釋中標(biāo)注了每一步是怎么實現(xiàn)的。
注意:
由于編譯器原因程序中_kbhit()和_getch()函數(shù)可能在其他編譯器上編譯會出現(xiàn)錯誤,解決辦法是去掉函數(shù)前面的“_”。
運行效果:
#include <iostream> #include <vector> #include <windows.h> #include <conio.h> #include <ctime> using namespace std; void gotoxy(int x, int y); //光標(biāo)定位 //食物類 class Food { private: int m_x; int m_y; public: void randfood() //隨機(jī)產(chǎn)生一個食物 { srand((int)time(NULL)); L1: m_x = rand() % (85) + 2; m_y = rand() % (25) + 2; if (m_x % 2) //如果食物的x坐標(biāo)不是偶數(shù)則重新確定食物的坐標(biāo) goto L1; gotoxy(m_x, m_y); //在確認(rèn)好的位置輸出食物 cout << "★"; } int getFoodm_x() //返回食物的x坐標(biāo) { return m_x; } int getFoodm_y() //返回食物的y坐標(biāo) { return m_y; } }; //蛇類 class Snake { private: //蛇坐標(biāo)結(jié)構(gòu) struct Snakecoor { int x; int y; }; //蛇容器 vector<Snakecoor> snakecoor; //判斷和改變方向函數(shù) void degdir(Snakecoor& nexthead) //參數(shù):新蛇頭結(jié)構(gòu)變量、蛇坐標(biāo)容器 { static char key = 'd'; //靜態(tài)變量防止改變移動方向后重新改回來 if (_kbhit()) //改變蛇前進(jìn)的方向 { char temp = _getch(); switch (temp) //如果臨時變量的值為wasd中的一個,則賦值給key { default: break; case 'w': case 'a': case 's': case 'd': //如果temp的方向和key的方向不相反則賦值 if ((key == 'w' && temp != 's') || (key == 's' && temp != 'w') || \ (key == 'a' && temp != 'd') || (key == 'd' && temp != 'a')) key = temp; } } switch (key) //根據(jù)key的值確定蛇的移動方向 { case 'd': nexthead.x = snakecoor.front().x + 2; //新的蛇頭的頭部等于容器內(nèi)第一個數(shù)據(jù)(舊蛇頭)x坐標(biāo)+2 nexthead.y = snakecoor.front().y; break; case 'a': nexthead.x = snakecoor.front().x - 2; nexthead.y = snakecoor.front().y; break; case 'w': nexthead.x = snakecoor.front().x; nexthead.y = snakecoor.front().y - 1; break; case 's': nexthead.x = snakecoor.front().x; nexthead.y = snakecoor.front().y + 1; } } //游戲結(jié)束時需要做的事情 void finmatt(const int score) { system("cls"); gotoxy(40, 14); cout << "游戲結(jié)束"; gotoxy(40, 16); cout << "得分:" << score; gotoxy(0, 26); exit(0); } //游戲結(jié)束的情況 void finishgame(const int score) { //撞墻情況 if (snakecoor[0].x >= 88 || snakecoor[0].x < 0 || snakecoor[0].y >= 28 || snakecoor[0].y < 0) finmatt(score); //撞到自己情況 for (int i = 1; i < snakecoor.size(); i++) if (snakecoor[0].x == snakecoor[i].x && snakecoor[0].y == snakecoor[i].y) finmatt(score); } public: //構(gòu)造初始化蛇的位置 Snake() { Snakecoor temp; //臨時結(jié)構(gòu)變量用于創(chuàng)建蛇 for (int i = 5; i >= 0; i--) //反向創(chuàng)建初始蛇身,初始蛇頭朝東 { temp.x = 16 + (i << 1); //偶數(shù) temp.y = 8; snakecoor.push_back(temp); } } //蛇運動主要函數(shù) void move(Food& food, int& score) { Snakecoor nexthead; //新蛇頭變量 degdir(nexthead); //判斷和改變蛇前進(jìn)的方向 snakecoor.insert(snakecoor.begin(), nexthead); //將新的蛇頭插入容器頭部 gotoxy(0, 0); cout << "得分:" << score; //每次移動都在左上角刷新得分 finishgame(score); //判斷游戲結(jié)束函數(shù) if (snakecoor[0].x == food.getFoodm_x() && snakecoor[0].y == food.getFoodm_y()) //蛇頭與食物重合 { gotoxy(snakecoor[0].x, snakecoor[0].y); //吃到食物時因為直接返回此次移動沒有輸出蛇身,會少輸出一次蛇 cout << "●"; //所以在這里補上蛇移動時需要輸出的字符 gotoxy(snakecoor[1].x, snakecoor[1].y); cout << "■"; score++; //吃到食物得分+1 food.randfood(); //如果蛇頭坐標(biāo)和食物坐標(biāo)重合則重新產(chǎn)生一個食物 return; //直接結(jié)束本次移動 } for (int i = 0; i < snakecoor.size(); i++) //遍歷容器,判斷食物與蛇身是否重合并輸出整條蛇 { gotoxy(snakecoor[i].x, snakecoor[i].y); if (!i) //頭部輸出圓形否則輸出方塊 cout << "●"; else cout << "■"; //如果食物刷新到了蛇身上,則重新產(chǎn)生一個食物 if (snakecoor[i].x == food.getFoodm_x() && snakecoor[i].y == food.getFoodm_y()) food.randfood(); } gotoxy(snakecoor.back().x, snakecoor.back().y); //在容器尾部的地方輸出空格 cout << " "; snakecoor.pop_back(); //刪除容器中最后一個數(shù)據(jù) } }; void HideCursor() //隱藏光標(biāo) { CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); } void gotoxy(int x, int y) //光標(biāo)定位 { COORD pos = { x,y }; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); } //主函數(shù) int main() { system("mode con cols=88 lines=28"); //設(shè)置控制臺窗口大小 system("title C++ 貪吃蛇"); //設(shè)置標(biāo)題 HideCursor(); //光標(biāo)隱藏 int score = 0; //得分變量 Food food; //食物對象 food.randfood(); //開局隨機(jī)產(chǎn)生一個食物 Snake snake; //蛇對象 while (true) { snake.move(food, score);//蛇移動 Sleep(150); //游戲速度 } return 0; }
不足之處:
因為初學(xué)C++,所以程序中肯定還有一些不規(guī)范或不合理的地方。
關(guān)于C++小游戲的更多精彩內(nèi)容請點擊專題: 《C++經(jīng)典小游戲》 學(xué)習(xí)了解
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++ 中malloc()和free()函數(shù)的理解
這篇文章主要介紹了C++ 中malloc()和free()函數(shù)的理解的相關(guān)資料,這里提供用法示例幫助大家理解這部分知識,需要的朋友可以參考下2017-08-08C++生成格式化的標(biāo)準(zhǔn)字符串實例代碼
這篇文章主要給大家介紹了關(guān)于C++生成格式化的標(biāo)準(zhǔn)字符串的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09史上最貼心的 VS code C++ 環(huán)境配置超詳細(xì)教程
這篇文章主要介紹了史上最貼心的 VS code C++ 環(huán)境配置超詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02C++判斷主機(jī)是否處于聯(lián)網(wǎng)狀態(tài)
這篇文章主要為大家詳細(xì)介紹了C++判斷主機(jī)是否處于聯(lián)網(wǎng)狀態(tài),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-06-06Matlab實現(xiàn)黑洞優(yōu)化算法的示例代碼
根據(jù)黑洞現(xiàn)象原理首次提出BH 算法,它在傳統(tǒng)PSO基礎(chǔ)上引入了新的機(jī)制,有效地提高了收斂速度并防止了陷入局部極值的情況發(fā)生.本文將用Matlab實現(xiàn)這一算法,需要的可以參考一下2022-06-06