C++ vector容器實(shí)現(xiàn)貪吃蛇小游戲
本文實(shí)例為大家分享了C++ vector容器 實(shí)現(xiàn)貪吃蛇,供大家參考,具體內(nèi)容如下
使用vector容器實(shí)現(xiàn)貪吃蛇簡(jiǎn)化了很多繁瑣操作,且相比之前我的代碼已經(jīng)做到了盡量的簡(jiǎn)潔
技術(shù)環(huán)節(jié):
編譯環(huán)境:windows VS2019
需求:
控制貪吃蛇吃食物,吃到一個(gè)食物蛇身變長(zhǎng)一節(jié),得分增加,撞墻或撞自己則游戲結(jié)束。
思路:
創(chuàng)建一個(gè)vector容器,容器內(nèi)存儲(chǔ)蛇的每節(jié)身體的結(jié)構(gòu)變量,結(jié)構(gòu)變量中保存蛇身體的xy坐標(biāo),通過(guò)使用vector成員方法不斷添加和刪除容器中的數(shù)據(jù),實(shí)現(xiàn)蛇坐標(biāo)的規(guī)律移動(dòng),吃到食物等時(shí)執(zhí)行對(duì)應(yīng)操作。
在代碼注釋中標(biāo)注了每一步是怎么實(shí)現(xiàn)的。
注意:
由于編譯器原因程序中_kbhit()和_getch()函數(shù)可能在其他編譯器上編譯會(huì)出現(xiàn)錯(cuò)誤,解決辦法是去掉函數(shù)前面的“_”。
運(yùn)行效果:
#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)生一個(gè)食物 { 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)變量防止改變移動(dòng)方向后重新改回來(lái) if (_kbhit()) //改變蛇前進(jìn)的方向 { char temp = _getch(); switch (temp) //如果臨時(shí)變量的值為wasd中的一個(gè),則賦值給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的值確定蛇的移動(dòng)方向 { case 'd': nexthead.x = snakecoor.front().x + 2; //新的蛇頭的頭部等于容器內(nèi)第一個(gè)數(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é)束時(shí)需要做的事情 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; //臨時(shí)結(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); } } //蛇運(yùn)動(dòng)主要函數(shù) void move(Food& food, int& score) { Snakecoor nexthead; //新蛇頭變量 degdir(nexthead); //判斷和改變蛇前進(jìn)的方向 snakecoor.insert(snakecoor.begin(), nexthead); //將新的蛇頭插入容器頭部 gotoxy(0, 0); cout << "得分:" << score; //每次移動(dòng)都在左上角刷新得分 finishgame(score); //判斷游戲結(jié)束函數(shù) if (snakecoor[0].x == food.getFoodm_x() && snakecoor[0].y == food.getFoodm_y()) //蛇頭與食物重合 { gotoxy(snakecoor[0].x, snakecoor[0].y); //吃到食物時(shí)因?yàn)橹苯臃祷卮舜我苿?dòng)沒(méi)有輸出蛇身,會(huì)少輸出一次蛇 cout << "●"; //所以在這里補(bǔ)上蛇移動(dòng)時(shí)需要輸出的字符 gotoxy(snakecoor[1].x, snakecoor[1].y); cout << "■"; score++; //吃到食物得分+1 food.randfood(); //如果蛇頭坐標(biāo)和食物坐標(biāo)重合則重新產(chǎn)生一個(gè)食物 return; //直接結(jié)束本次移動(dòng) } for (int i = 0; i < snakecoor.size(); i++) //遍歷容器,判斷食物與蛇身是否重合并輸出整條蛇 { gotoxy(snakecoor[i].x, snakecoor[i].y); if (!i) //頭部輸出圓形否則輸出方塊 cout << "●"; else cout << "■"; //如果食物刷新到了蛇身上,則重新產(chǎn)生一個(gè)食物 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(); //刪除容器中最后一個(gè)數(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è)置控制臺(tái)窗口大小 system("title C++ 貪吃蛇"); //設(shè)置標(biāo)題 HideCursor(); //光標(biāo)隱藏 int score = 0; //得分變量 Food food; //食物對(duì)象 food.randfood(); //開(kāi)局隨機(jī)產(chǎn)生一個(gè)食物 Snake snake; //蛇對(duì)象 while (true) { snake.move(food, score);//蛇移動(dòng) Sleep(150); //游戲速度 } return 0; }
不足之處:
因?yàn)槌鯇W(xué)C++,所以程序中肯定還有一些不規(guī)范或不合理的地方。
關(guān)于C++小游戲的更多精彩內(nèi)容請(qǐng)點(diǎn)擊專題: 《C++經(jīng)典小游戲》 學(xué)習(xí)了解
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++ 中malloc()和free()函數(shù)的理解
這篇文章主要介紹了C++ 中malloc()和free()函數(shù)的理解的相關(guān)資料,這里提供用法示例幫助大家理解這部分知識(shí),需要的朋友可以參考下2017-08-08C++生成格式化的標(biāo)準(zhǔn)字符串實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于C++生成格式化的標(biāo)準(zhǔn)字符串的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09史上最貼心的 VS code C++ 環(huán)境配置超詳細(xì)教程
這篇文章主要介紹了史上最貼心的 VS code C++ 環(huán)境配置超詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02C語(yǔ)言數(shù)組與地址、數(shù)組名到底是什么詳解
在寫(xiě)代碼的時(shí)候,我們經(jīng)常用到數(shù)組,那么有沒(méi)有想過(guò)數(shù)組名是什么呢?這篇文章主要給大家介紹了關(guān)于C語(yǔ)言數(shù)組與地址、數(shù)組名到底是什么的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06C++判斷主機(jī)是否處于聯(lián)網(wǎng)狀態(tài)
這篇文章主要為大家詳細(xì)介紹了C++判斷主機(jī)是否處于聯(lián)網(wǎng)狀態(tài),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06C語(yǔ)言中的強(qiáng)符號(hào)和弱符號(hào)介紹
這篇文章主要介紹了C語(yǔ)言中的強(qiáng)符號(hào)和弱符號(hào)介紹,本文用多個(gè)實(shí)例來(lái)講解強(qiáng)符號(hào)和弱符號(hào),需要的朋友可以參考下2015-03-03Matlab實(shí)現(xiàn)黑洞優(yōu)化算法的示例代碼
根據(jù)黑洞現(xiàn)象原理首次提出BH 算法,它在傳統(tǒng)PSO基礎(chǔ)上引入了新的機(jī)制,有效地提高了收斂速度并防止了陷入局部極值的情況發(fā)生.本文將用Matlab實(shí)現(xiàn)這一算法,需要的可以參考一下2022-06-06