C++控制台贪吃蛇小游戏详细教程
游戲截圖
?
?
開始動(dòng)畫:?
?
游戲過程:?
游戲架構(gòu)設(shè)計(jì)
該游戲的玩法簡單,玩家通過鍵盤方向鍵控制蛇上下左右移動(dòng),吃到食物得分并增長,碰到墻或者自己的身體則死亡,游戲結(jié)束。?
整個(gè)游戲其實(shí)就是一個(gè)無窮的循環(huán),直到退出游戲時(shí)退出循環(huán)。我們暫且將這個(gè)循環(huán)稱為一級循環(huán),這個(gè)循環(huán)包含游戲開始動(dòng)畫,游戲難度選擇,游戲過程這三個(gè)子模塊,其中游戲過程這個(gè)模塊亦是一個(gè)循環(huán),我們暫且將其稱為二級循環(huán)。它們之間的關(guān)系大致如下圖:?
?
現(xiàn)在我們根據(jù)上圖進(jìn)行細(xì)化,對各個(gè)模塊的實(shí)現(xiàn)進(jìn)行簡單描述。
1.游戲開始動(dòng)畫
開始動(dòng)畫的實(shí)現(xiàn)主要依靠對點(diǎn)的操作來實(shí)現(xiàn),這里我們先建立一個(gè)概念,就是將控制臺界面看成一個(gè)原點(diǎn)在左上角的坐標(biāo)系,一個(gè)點(diǎn)(x,y)表示坐標(biāo)系中的一個(gè)格子,如下圖所示:?
?
我們的開始動(dòng)畫是由一條蛇和一行文字從左到右移動(dòng)而成,這里我們先單獨(dú)討論一下蛇,要達(dá)到移動(dòng)的效果,我采取的策略是將整個(gè)過程分為三部分:?
第一部分為蛇從左邊開始出現(xiàn)到整個(gè)身體完全出現(xiàn)?
第二部分為蛇身整體從左移動(dòng)到接觸右邊界的過程?
第三部分為蛇從接觸右邊界到完全消失的過程?
我們先來看一下第一部分,這一部分的實(shí)現(xiàn)首先是建立一個(gè)deque雙端隊(duì)列,用于存儲點(diǎn)的對象,這些點(diǎn)就是組成蛇身的元素,然后再用一個(gè)for循環(huán)將容器中的點(diǎn)依次打印出來,每打印一個(gè)點(diǎn)停頓一會,這樣就達(dá)到了移動(dòng)的效果。全部打印完后就到了第二部分,這部分蛇的每次前進(jìn)都是通過計(jì)算將要移動(dòng)到的下一個(gè)點(diǎn)的坐標(biāo),然后將這個(gè)點(diǎn)打印出來,與此同時(shí)將蛇尾,亦即queue中的首端點(diǎn)去掉,并擦除屏幕上該點(diǎn)顏色。第三部分就直接依次從蛇尾擦除即可。?
同理,文字snake的移動(dòng)也基本類似,稍微改動(dòng)即可,因?yàn)闊o需對首尾進(jìn)行操作,而是要對所以點(diǎn)進(jìn)行移動(dòng),因此容器選用vector。?
具體請參看startinterface.h以及startinterface.cpp
2.選擇難度
其實(shí)這個(gè)模塊很簡單,我就簡單介紹一下,先將難度選擇的文字信息打印在屏幕上,然后通過控制鍵盤方向鍵選擇,回車鍵確認(rèn),為了突出選中項(xiàng),需要給選中項(xiàng)打上背景色,然后每一次上下移動(dòng)時(shí),先將當(dāng)前的背景色去掉,然后給下一個(gè)選中項(xiàng)打上背景色,按下回車后通過改變蛇移動(dòng)的速度實(shí)現(xiàn)改變難度。其中讀取鍵盤輸入是通過getch()函數(shù)完成的。?
3.游戲過程
這個(gè)模塊就是整個(gè)游戲最主要的部分了,首先它先繪制出地圖以及側(cè)邊欄,同時(shí)初始化蛇和食物,然后通過一個(gè)無窮循環(huán)監(jiān)聽鍵盤,以此來控制蛇移動(dòng),同時(shí)又進(jìn)行各種判斷,來判斷是否死亡、吃到食物或暫停。需要提一下,這里使用kbhit()函數(shù)來監(jiān)聽鍵盤,它用來判斷在一段固定的時(shí)間內(nèi)是否有鍵盤輸入,要知道,這個(gè)函數(shù)的返回值有兩個(gè),第一個(gè)是是否有輸入的返回值,第二個(gè)才是鍵盤輸入的內(nèi)容,也就是說要經(jīng)過兩次的讀取緩沖區(qū)才能讀到真正的鍵盤輸入。?
游戲代碼實(shí)現(xiàn)
從這里開始我們就可以真正動(dòng)手來實(shí)現(xiàn)游戲了,在動(dòng)手之前,我建議先下載游戲來玩幾局,弄清整個(gè)游戲的邏輯,這樣更能有一個(gè)清晰的思路。?
接著你可以將以下的代碼或者github上的代碼按下面幾張圖的流程添加進(jìn)工程里,當(dāng)然如果你使用其他IDE的話就按照它的方式來弄,然后進(jìn)行編譯試一下。
首先新建工程?
然后將文件一個(gè)一個(gè)添加進(jìn)工程里
最后所有文件添加完就是這樣了
記得要把編譯器改成c++11標(biāo)準(zhǔn)
完成了以上幾步后就可以點(diǎn)編譯按鈕進(jìn)行編譯,同時(shí)運(yùn)行一下,看看效果。然后閱讀源碼或者修改一下,看看編譯后有什么不同。?
這里代碼.h文件是類的定義,.cpp文件是類的實(shí)現(xiàn)。整個(gè)程序共有七個(gè)類,分別為Tools,Point,StartInterface,Snake,Map,Food。?
因?yàn)檎麄€(gè)游戲需要對于點(diǎn)的大量操作,所以建立Tools和Point兩個(gè)類,Tools工具類主要是用于設(shè)置光標(biāo)的位置以及輸出文字的顏色,Point類設(shè)置點(diǎn)的對象,因?yàn)槠渌惗际墙⒃谶@兩個(gè)類的基礎(chǔ)上的,所以閱讀代碼時(shí)要先看這兩個(gè)。然后才開始從main.cpp開始看,一行一行,看到出現(xiàn)新的類就轉(zhuǎn)到該類的聲明與定義文件去看,這樣閱讀起來比較清晰,這里簡要說明一下各個(gè)類的功能,Controller類就是控制整個(gè)游戲過程的,包括游戲的各個(gè)階段,比如更新分?jǐn)?shù),游戲難度選擇等;Food類實(shí)現(xiàn)食物的隨機(jī)出現(xiàn);Map類負(fù)責(zé)繪制地圖,我由于時(shí)間關(guān)系(主要是懶)沒有加入地圖,只有邊界,但原理和邊界是一模一樣的,同樣是將點(diǎn)繪制出來,然后每一次都判斷蛇是否撞到地圖即可;Snake類控制蛇的移動(dòng)和吃到食物等。?
各個(gè)類之間的關(guān)系大致如下:
以下是實(shí)現(xiàn)的代碼
main.cpp
#include "controller.h"int main()//程序入口 {Controller c;//聲明一個(gè)Controller類c.Game();//整個(gè)游戲循環(huán)return 0; }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
controller.h
#ifndef CONTROLLER_H #define CONTROLLER_Hclass Controller { public:Controller() : speed(200), key(1), score(0) {}void Start();void Select();void DrawGame();int PlayGame();void UpdateScore(const int&);void RewriteScore();int Menu();void Game();int GameOver(); private:int speed;int key;int score; }; #endif // CONTROLLER_H- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
controller.cpp
#include <iostream> #include <time.h> #include <conio.h> #include <windows.h> #include "controller.h" #include "tools.h" #include "startinterface.h" #include "map.h" #include "snake.h" #include "food.h"void Controller::Start()//開始界面 {SetWindowSize(41, 32);//設(shè)置窗口大小SetColor(2);//設(shè)置開始動(dòng)畫顏色StartInterface *start = new StartInterface();//動(dòng)態(tài)分配一個(gè)StartInterface類startstart->Action();//開始動(dòng)畫delete start;//釋放內(nèi)存空間/*設(shè)置關(guān)標(biāo)位置,并輸出提示語,等待任意鍵輸入結(jié)束*/SetCursorPosition(13, 26);std::cout << "Press any key to start... " ;SetCursorPosition(13, 27);system("pause"); }void Controller::Select()//選擇界面 {/*初始化界面選項(xiàng)*/SetColor(3);SetCursorPosition(13, 26);std::cout << " " ;SetCursorPosition(13, 27);std::cout << " " ;SetCursorPosition(6, 21);std::cout << "請選擇游戲難度:" ;SetCursorPosition(6, 22);std::cout << "(上下鍵選擇,回車確認(rèn))" ;SetCursorPosition(27, 22);SetBackColor();//第一個(gè)選項(xiàng)設(shè)置背景色以表示當(dāng)前選中std::cout << "簡單模式" ;SetCursorPosition(27, 24);SetColor(3);std::cout << "普通模式" ;SetCursorPosition(27, 26);std::cout << "困難模式" ;SetCursorPosition(27, 28);std::cout << "煉獄模式" ;SetCursorPosition(0, 31);score = 0;/*上下方向鍵選擇模塊*/int ch;//記錄鍵入值key = 1;//記錄選中項(xiàng),初始選擇第一個(gè)bool flag = false;//記錄是否鍵入Enter鍵標(biāo)記,初始置為否while ((ch = getch())){switch (ch)//檢測輸入鍵{case 72://UP上方向鍵if (key > 1)//當(dāng)此時(shí)選中項(xiàng)為第一項(xiàng)時(shí),UP上方向鍵無效{switch (key){case 2:SetCursorPosition(27, 22);//給待選中項(xiàng)設(shè)置背景色SetBackColor();std::cout << "簡單模式" ;SetCursorPosition(27, 24);//將已選中項(xiàng)取消我背景色SetColor(3);std::cout << "普通模式" ;--key;break;case 3:SetCursorPosition(27, 24);SetBackColor();std::cout << "普通模式" ;SetCursorPosition(27, 26);SetColor(3);std::cout << "困難模式" ;--key;break;case 4:SetCursorPosition(27, 26);SetBackColor();std::cout << "困難模式" ;SetCursorPosition(27, 28);SetColor(3);std::cout << "煉獄模式" ;--key;break;}}break;case 80://DOWN下方向鍵if (key < 4){switch (key){case 1:SetCursorPosition(27, 24);SetBackColor();std::cout << "普通模式" ;SetCursorPosition(27, 22);SetColor(3);std::cout << "簡單模式" ;++key;break;case 2:SetCursorPosition(27, 26);SetBackColor();std::cout << "困難模式" ;SetCursorPosition(27, 24);SetColor(3);std::cout << "普通模式" ;++key;break;case 3:SetCursorPosition(27, 28);SetBackColor();std::cout << "煉獄模式" ;SetCursorPosition(27, 26);SetColor(3);std::cout << "困難模式" ;++key;break;}}break;case 13://Enter回車鍵flag = true;break;default://無效按鍵break;}if (flag) break;//輸入Enter回車鍵確認(rèn),退出檢查輸入循環(huán)SetCursorPosition(0, 31);//將光標(biāo)置于左下角,避免關(guān)標(biāo)閃爍影響游戲體驗(yàn)}switch (key)//根據(jù)所選選項(xiàng)設(shè)置蛇的移動(dòng)速度,speed值越小,速度越快{case 1:speed = 135;break;case 2:speed = 100;break;case 3:speed = 60;break;case 4:speed = 30;break;default:break;} }void Controller::DrawGame()//繪制游戲界面 {system("cls");//清屏/*繪制地圖*/SetColor(3);Map *init_map = new Map();init_map->PrintInitmap();delete init_map;/*繪制側(cè)邊欄*/SetColor(3);SetCursorPosition(33, 1);std::cout << "Greedy Snake" ;SetCursorPosition(34, 2);std::cout << "貪吃蛇" ;SetCursorPosition(31, 4);std::cout << "難度:" ;SetCursorPosition(36, 5);switch (key){case 1:std::cout << "簡單模式" ;break;case 2:std::cout << "普通模式" ;break;case 3:std::cout << "困難模式" ;break;case 4:std::cout << "煉獄模式" ;break;default:break;}SetCursorPosition(31, 7);std::cout << "得分:" ;SetCursorPosition(37, 8);std::cout << " 0" ;SetCursorPosition(33, 13);std::cout << " 方向鍵移動(dòng)" ;SetCursorPosition(33, 15);std::cout << " ESC鍵暫停" ; }int Controller::PlayGame()//游戲二級循環(huán) {/*初始化蛇和食物*/Snake *csnake = new Snake();Food *cfood = new Food();SetColor(6);csnake->InitSnake();srand((unsigned)time(NULL));//設(shè)置隨機(jī)數(shù)種子,如果沒有 食物的出現(xiàn)位置將會固定cfood->DrawFood(*csnake);/*游戲循環(huán)*/while (csnake->OverEdge() && csnake->HitItself()) //判斷是否撞墻或撞到自身,即是否還有生命{/*調(diào)出選擇菜單*/if (!csnake->ChangeDirection()) //按Esc鍵時(shí){int tmp = Menu();//繪制菜單,并得到返回值switch (tmp){case 1://繼續(xù)游戲break;case 2://重新開始delete csnake;delete cfood;return 1;//將1作為PlayGame函數(shù)的返回值返回到Game函數(shù)中,表示重新開始case 3://退出游戲delete csnake;delete cfood;return 2;//將2作為PlayGame函數(shù)的返回值返回到Game函數(shù)中,表示退出游戲default:break;}}if (csnake->GetFood(*cfood)) //吃到食物{csnake->Move();//蛇增長UpdateScore(1);//更新分?jǐn)?shù),1為分?jǐn)?shù)權(quán)重RewriteScore();//重新繪制分?jǐn)?shù)cfood->DrawFood(*csnake);//繪制新食物}else{csnake->NormalMove();//蛇正常移動(dòng)}if (csnake->GetBigFood(*cfood)) //吃到限時(shí)食物{csnake->Move();UpdateScore(cfood->GetProgressBar()/5);//分?jǐn)?shù)根據(jù)限時(shí)食物進(jìn)度條確定RewriteScore();}if (cfood->GetBigFlag()) //如果此時(shí)有限時(shí)食物,閃爍它{cfood->FlashBigFood();}Sleep(speed);//制造蛇的移動(dòng)效果}/*蛇死亡*/delete csnake;//釋放分配的內(nèi)存空間delete cfood;int tmp = GameOver();//繪制游戲結(jié)束界面,并返回所選項(xiàng)switch (tmp){case 1:return 1;//重新開始case 2:return 2;//退出游戲default:return 2;} }void Controller::UpdateScore(const int& tmp)//更新分?jǐn)?shù) {score += key * 10 * tmp;//所得分?jǐn)?shù)根據(jù)游戲難度及傳人的參數(shù)tmp確定 }void Controller::RewriteScore()//重繪分?jǐn)?shù) {/*為保持分?jǐn)?shù)尾部對齊,將最大分?jǐn)?shù)設(shè)置為6位,計(jì)算當(dāng)前分?jǐn)?shù)位數(shù),將剩余位數(shù)用空格補(bǔ)全,再輸出分?jǐn)?shù)*/SetCursorPosition(37, 8);SetColor(11);int bit = 0;int tmp = score;while (tmp != 0){++bit;tmp /= 10;}for (int i = 0; i < (6 - bit); ++i){std::cout << " " ;}std::cout << score ; }int Controller::Menu()//選擇菜單 {/*繪制菜單*/SetColor(11);SetCursorPosition(32, 19);std::cout << "菜單:" ;Sleep(100);SetCursorPosition(34, 21);SetBackColor();std::cout << "繼續(xù)游戲" ;Sleep(100);SetCursorPosition(34, 23);SetColor(11);std::cout << "重新開始" ;Sleep(100);SetCursorPosition(34, 25);std::cout << "退出游戲" ;SetCursorPosition(0, 31);/*選擇部分*/int ch;int tmp_key = 1;bool flag = false;while ((ch = getch())){switch (ch){case 72://UPif (tmp_key > 1){switch (tmp_key){case 2:SetCursorPosition(34, 21);SetBackColor();std::cout << "繼續(xù)游戲" ;SetCursorPosition(34, 23);SetColor(11);std::cout << "重新開始" ;--tmp_key;break;case 3:SetCursorPosition(34, 23);SetBackColor();std::cout << "重新開始" ;SetCursorPosition(34, 25);SetColor(11);std::cout << "退出游戲" ;--tmp_key;break;}}break;case 80://DOWNif (tmp_key < 3){switch (tmp_key){case 1:SetCursorPosition(34, 23);SetBackColor();std::cout << "重新開始" ;SetCursorPosition(34, 21);SetColor(11);std::cout << "繼續(xù)游戲" ;++tmp_key;break;case 2:SetCursorPosition(34, 25);SetBackColor();std::cout << "退出游戲" ;SetCursorPosition(34, 23);SetColor(11);std::cout << "重新開始" ;++tmp_key;break;}}break;case 13://Enterflag = true;break;default:break;}if (flag){break;}SetCursorPosition(0, 31);}if (tmp_key == 1) //選擇繼續(xù)游戲,則將菜單擦除{SetCursorPosition(32, 19);std::cout << " " ;SetCursorPosition(34, 21);std::cout << " ";SetCursorPosition(34, 23);std::cout << " ";SetCursorPosition(34, 25);std::cout << " ";}return tmp_key; }void Controller::Game()//游戲一級循環(huán) {Start();//開始界面while (true)//游戲可視為一個(gè)死循環(huán),直到退出游戲時(shí)循環(huán)結(jié)束{Select();//選擇界面DrawGame();//繪制游戲界面int tmp = PlayGame();//開啟游戲循環(huán),當(dāng)重新開始或退出游戲時(shí),結(jié)束循環(huán)并返回值給tmpif (tmp == 1) //返回值為1時(shí)重新開始游戲{system("cls");continue;}else if (tmp == 2) //返回值為2時(shí)退出游戲{break;}else{break;}} }int Controller::GameOver()//游戲結(jié)束界面 {/*繪制游戲結(jié)束界面*/Sleep(500);SetColor(11);SetCursorPosition(10, 8);std::cout << "━━━━━━━━━━━━━━━━━━━━━━" ;Sleep(30);SetCursorPosition(9, 9);std::cout << " ┃ Game Over !!! ┃" ;Sleep(30);SetCursorPosition(9, 10);std::cout << " ┃ ┃" ;Sleep(30);SetCursorPosition(9, 11);std::cout << " ┃ 很遺憾!你掛了 ┃" ;Sleep(30);SetCursorPosition(9, 12);std::cout << " ┃ ┃" ;Sleep(30);SetCursorPosition(9, 13);std::cout << " ┃ 你的分?jǐn)?shù)為: ┃" ;SetCursorPosition(24, 13);std::cout << score ;Sleep(30);SetCursorPosition(9, 14);std::cout << " ┃ ┃" ;Sleep(30);SetCursorPosition(9, 15);std::cout << " ┃ 是否再來一局? ┃" ;Sleep(30);SetCursorPosition(9, 16);std::cout << " ┃ ┃" ;Sleep(30);SetCursorPosition(9, 17);std::cout << " ┃ ┃" ;Sleep(30);SetCursorPosition(9, 18);std::cout << " ┃ 嗯,好的 不了,還是學(xué)習(xí)有意思 ┃" ;Sleep(30);SetCursorPosition(9, 19);std::cout << " ┃ ┃" ;Sleep(30);SetCursorPosition(9, 20);std::cout << " ┃ ┃" ;Sleep(30);SetCursorPosition(10, 21);std::cout << "━━━━━━━━━━━━━━━━━━━━━━" ;Sleep(100);SetCursorPosition(12, 18);SetBackColor();std::cout << "嗯,好的" ;SetCursorPosition(0, 31);/*選擇部分*/int ch;int tmp_key = 1;bool flag = false;while ((ch = getch())){switch (ch){case 75://LEFTif (tmp_key > 1){SetCursorPosition(12, 18);SetBackColor();std::cout << "嗯,好的" ;SetCursorPosition(20, 18);SetColor(11);std::cout << "不了,還是學(xué)習(xí)有意思" ;--tmp_key;}break;case 77://RIGHTif (tmp_key < 2){SetCursorPosition(20, 18);SetBackColor();std::cout << "不了,還是學(xué)習(xí)有意思" ;SetCursorPosition(12, 18);SetColor(11);std::cout << "嗯,好的" ;++tmp_key;}break;case 13://Enterflag = true;break;default:break;}SetCursorPosition(0, 31);if (flag) {break;}}SetColor(11);switch (tmp_key){case 1:return 1;//重新開始case 2:return 2;//退出游戲default:return 1;} }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
food.h
#ifndef FOOD_H #define FOOD_H#include "snake.h" class Snake; class Food { public:Food() : cnt(0), flash_flag(false), big_flag(false), x(0), y(0), big_x(0), big_y(0), progress_bar(0) {}void DrawFood(Snake&);void DrawBigFood(Snake&);int GetCnt();void FlashBigFood();bool GetBigFlag();int GetProgressBar(); private:int cnt;bool flash_flag;//閃爍標(biāo)記bool big_flag;//是否有限時(shí)食物標(biāo)記int x, y;int big_x, big_y;int progress_bar;//限時(shí)食物進(jìn)度條friend class Snake; }; #endif // FOOD_H- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
food.cpp
#include "food.h" #include "tools.h" #include <cstdlib> #include <iostream>void Food::DrawFood(Snake& csnake)//繪制食物 {/*利用rand函數(shù)獲得坐標(biāo),并將其范圍限制在2-29內(nèi),即在地圖內(nèi),如果獲得的坐標(biāo)與蛇身重疊,則重新獲取。同時(shí)每5顆食物就出現(xiàn)一顆限時(shí)食物*/while (true){int tmp_x = rand() % 30;int tmp_y = rand() % 30;if(tmp_x < 2) tmp_x += 2;if(tmp_y < 2) tmp_y += 2;bool flag = false;for (auto& point : csnake.snake){if ((point.GetX() == tmp_x && point.GetY() == tmp_y) || (tmp_x == big_x && tmp_y == big_y)) {flag = true;break;}}if (flag)continue;x = tmp_x;y = tmp_y;SetCursorPosition(x, y);SetColor(13);std::cout << "★" ;++cnt;cnt %= 5;if (cnt == 0){DrawBigFood(csnake);}break;} }void Food::DrawBigFood(Snake& csnake)//繪制限時(shí)食物 {SetCursorPosition(5, 0);SetColor(11);std::cout << "------------------------------------------" ;//進(jìn)度條progress_bar = 42;while (true){int tmp_x = rand() % 30;int tmp_y = rand() % 30;if(tmp_x < 2) tmp_x += 2;if(tmp_y < 2) tmp_y += 2;bool flag = false;for (auto& point : csnake.snake){if ((point.GetX() == tmp_x && point.GetY() == tmp_y) || (tmp_x == x && tmp_y == y)){flag = true;break;}}if (flag)continue;big_x = tmp_x;big_y = tmp_y;SetCursorPosition(big_x, big_y);SetColor(18);std::cout << "■" ;big_flag = true;flash_flag = true;break;} }int Food::GetCnt() {return cnt; }void Food::FlashBigFood()//閃爍限時(shí)食物 {SetCursorPosition(big_x, big_y);SetColor(18);if (flash_flag){std::cout << " " ;flash_flag = false;}else{std::cout << "■" ;flash_flag = true;}SetCursorPosition(26, 0);SetColor(11);for (int i = 42; i >= progress_bar; --i)//進(jìn)度條縮短std::cout << "\b \b" ;--progress_bar;if (progress_bar == 0) {SetCursorPosition(big_x, big_y);std::cout << " " ;big_flag = false;big_x = 0;big_y = 0;} }bool Food::GetBigFlag() {return big_flag; }int Food::GetProgressBar() {return progress_bar; }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
map.h
#ifndef MAP_H #define MAP_H#include <vector> #include "point.h" class Map { public:Map()//默認(rèn)構(gòu)造函數(shù),將正方形各點(diǎn)壓入initmap{initmap.emplace_back(Point(1, 1));initmap.emplace_back(Point(2, 1));initmap.emplace_back(Point(3, 1));initmap.emplace_back(Point(4, 1));initmap.emplace_back(Point(5, 1));initmap.emplace_back(Point(6, 1));initmap.emplace_back(Point(7, 1));initmap.emplace_back(Point(8, 1));initmap.emplace_back(Point(9, 1));initmap.emplace_back(Point(10, 1));initmap.emplace_back(Point(11, 1));initmap.emplace_back(Point(12, 1));initmap.emplace_back(Point(13, 1));initmap.emplace_back(Point(14, 1));initmap.emplace_back(Point(15, 1));initmap.emplace_back(Point(16, 1));initmap.emplace_back(Point(17, 1));initmap.emplace_back(Point(18, 1));initmap.emplace_back(Point(19, 1));initmap.emplace_back(Point(20, 1));initmap.emplace_back(Point(21, 1));initmap.emplace_back(Point(22, 1));initmap.emplace_back(Point(23, 1));initmap.emplace_back(Point(24, 1));initmap.emplace_back(Point(25, 1));initmap.emplace_back(Point(26, 1));initmap.emplace_back(Point(27, 1));initmap.emplace_back(Point(28, 1));initmap.emplace_back(Point(29, 1));initmap.emplace_back(Point(30, 1));initmap.emplace_back(Point(1, 2));initmap.emplace_back(Point(30, 2));initmap.emplace_back(Point(1, 3));initmap.emplace_back(Point(30, 3));initmap.emplace_back(Point(1, 4));initmap.emplace_back(Point(30, 4));initmap.emplace_back(Point(1, 5));initmap.emplace_back(Point(30, 5));initmap.emplace_back(Point(1, 6));initmap.emplace_back(Point(30, 6));initmap.emplace_back(Point(1, 7));initmap.emplace_back(Point(30, 7));initmap.emplace_back(Point(1, 8));initmap.emplace_back(Point(30, 8));initmap.emplace_back(Point(1, 9));initmap.emplace_back(Point(30, 9));initmap.emplace_back(Point(1, 10));initmap.emplace_back(Point(30, 10));initmap.emplace_back(Point(1, 11));initmap.emplace_back(Point(30, 11));initmap.emplace_back(Point(1, 12));initmap.emplace_back(Point(30, 12));initmap.emplace_back(Point(1, 13));initmap.emplace_back(Point(30, 13));initmap.emplace_back(Point(1, 14));initmap.emplace_back(Point(30, 14));initmap.emplace_back(Point(1, 15));initmap.emplace_back(Point(30, 15));initmap.emplace_back(Point(1, 16));initmap.emplace_back(Point(30, 16));initmap.emplace_back(Point(1, 17));initmap.emplace_back(Point(30, 17));initmap.emplace_back(Point(1, 18));initmap.emplace_back(Point(30, 18));initmap.emplace_back(Point(1, 19));initmap.emplace_back(Point(30, 19));initmap.emplace_back(Point(1, 20));initmap.emplace_back(Point(30, 20));initmap.emplace_back(Point(1, 21));initmap.emplace_back(Point(30, 21));initmap.emplace_back(Point(1, 22));initmap.emplace_back(Point(30, 22));initmap.emplace_back(Point(1, 23));initmap.emplace_back(Point(30, 23));initmap.emplace_back(Point(1, 24));initmap.emplace_back(Point(30, 24));initmap.emplace_back(Point(1, 25));initmap.emplace_back(Point(30, 25));initmap.emplace_back(Point(1, 26));initmap.emplace_back(Point(30, 26));initmap.emplace_back(Point(1, 27));initmap.emplace_back(Point(30, 27));initmap.emplace_back(Point(1, 28));initmap.emplace_back(Point(30, 28));initmap.emplace_back(Point(1, 29));initmap.emplace_back(Point(30, 29));initmap.emplace_back(Point(1, 30));initmap.emplace_back(Point(2, 30));initmap.emplace_back(Point(3, 30));initmap.emplace_back(Point(4, 30));initmap.emplace_back(Point(5, 30));initmap.emplace_back(Point(6, 30));initmap.emplace_back(Point(7, 30));initmap.emplace_back(Point(8, 30));initmap.emplace_back(Point(9, 30));initmap.emplace_back(Point(10, 30));initmap.emplace_back(Point(11, 30));initmap.emplace_back(Point(12, 30));initmap.emplace_back(Point(13, 30));initmap.emplace_back(Point(14, 30));initmap.emplace_back(Point(15, 30));initmap.emplace_back(Point(16, 30));initmap.emplace_back(Point(17, 30));initmap.emplace_back(Point(18, 30));initmap.emplace_back(Point(19, 30));initmap.emplace_back(Point(20, 30));initmap.emplace_back(Point(21, 30));initmap.emplace_back(Point(22, 30));initmap.emplace_back(Point(23, 30));initmap.emplace_back(Point(24, 30));initmap.emplace_back(Point(25, 30));initmap.emplace_back(Point(26, 30));initmap.emplace_back(Point(27, 30));initmap.emplace_back(Point(28, 30));initmap.emplace_back(Point(29, 30));initmap.emplace_back(Point(30, 30));}void PrintInitmap();//繪制初始地圖 private:std::vector<Point> initmap;//保存初始地圖/*Map類可自定義多種地圖,只需將表示地圖的各個(gè)點(diǎn)保存在相應(yīng)的map中,并在Snake類中增加相應(yīng)判斷撞墻函數(shù)即可std::vector<Point> map1;std::vector<Point> map2;*/ }; #endif // MAP_H- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
map.cpp
#include "map.h" #include <windows.h>void Map::PrintInitmap()//繪制初始地圖 {for (auto& point : initmap){point.Print();Sleep(10);//調(diào)用Sleep函數(shù)可營造動(dòng)畫效果} }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
point.h
#ifndef POINT_H #define POINT_Hclass Point { public:Point(){}Point(const int x, const int y) : x(x), y(y) {}void Print();void PrintCircular();void Clear();void ChangePosition(const int x, const int y);bool operator== (const Point& point) { return (point.x == this->x) && (point.y == this->y); }int GetX(){ return this->x; }int GetY(){ return this->y; } private:int x, y; }; #endif // POINT_H- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
point.cpp
#include "point.h" #include "tools.h" #include <iostream>void Point::Print()//輸出方塊 {SetCursorPosition(x, y);std::cout << "■" ; }void Point::PrintCircular()//輸出圓形 {SetCursorPosition(x, y);std::cout << "●" ; }void Point::Clear()//清除輸出 {SetCursorPosition(x, y);std::cout << " " ; }void Point::ChangePosition(const int x, const int y)//改變坐標(biāo) {this->x = x;this->y = y; }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
snake.h
#ifndef SNAKE_H #define SNAKE_H#include <deque> #include "point.h" #include "food.h"class Food; class Snake { public:enum Direction {UP, DOWN, LEFT, RIGHT};Snake() {snake.emplace_back(14, 8);snake.emplace_back(15, 8);snake.emplace_back(16, 8);direction = Direction::DOWN;}void InitSnake();void Move();void NormalMove();bool OverEdge();bool HitItself();bool ChangeDirection();bool GetFood(const Food&);bool GetBigFood(Food&); private:std::deque<Point> snake;Direction direction;friend class Food;//將Food類置為友元,以便訪問其私有元素 }; #endif // SNAKE_H- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
snake.cpp
#include "snake.h" #include <conio.h> #include "tools.h" #include <iostream>void Snake::InitSnake()//初始化蛇 {for (auto& point : snake){point.PrintCircular();} }void Snake::Move()//蛇增長 {switch (direction){case Direction::UP:snake.emplace_back(Point(snake.back().GetX(), snake.back().GetY() - 1 ));break;case Direction::DOWN:snake.emplace_back(Point(snake.back().GetX(), snake.back().GetY() + 1 ));break;case Direction::LEFT:snake.emplace_back(Point(snake.back().GetX() - 1, snake.back().GetY() ));break;case Direction::RIGHT:snake.emplace_back(Point(snake.back().GetX() + 1, snake.back().GetY() ));break;default:break;}SetColor(14);snake.back().PrintCircular(); }void Snake::NormalMove()//蛇正常移動(dòng),頭增長,尾縮短 {Move();snake.front().Clear();snake.pop_front(); }bool Snake::OverEdge()//超出邊界 {return snake.back().GetX() < 30 &&snake.back().GetY() < 30 &&snake.back().GetX() > 1 &&snake.back().GetY() > 1; }bool Snake::HitItself()//撞到自身 {std::deque<Point>::size_type cnt = 1;Point *head = new Point(snake.back().GetX(), snake.back().GetY());//獲得頭部坐標(biāo)for (auto& point : snake) //如果整條蛇中與蛇頭不相同的坐標(biāo)不等于蛇長,則意味著蛇頭碰撞到自身{if ( !(point == *head) )++cnt;elsebreak;}delete head;if(cnt == snake.size())return true;elsereturn false; }bool Snake::ChangeDirection()//改變方向 {char ch;if (kbhit())//kbhit函數(shù)返回值為兩個(gè),需注意{ch = getch();switch (ch){case -32:ch = getch();switch (ch){case 72:if (direction != Direction::DOWN)//如果方向與當(dāng)前運(yùn)動(dòng)方向相反,無效direction = Direction::UP;break;case 80:if (direction != Direction::UP)direction = Direction::DOWN;break;case 75:if (direction != Direction::RIGHT)direction = Direction::LEFT;break;case 77:if (direction != Direction::LEFT)direction = Direction::RIGHT;break;default:break;}return true;case 27://ESCreturn false;default:return true;}}return true; }bool Snake::GetFood(const Food& cfood) {if (snake.back().GetX() == cfood.x && snake.back().GetY() == cfood.y)return true;elsereturn false; }bool Snake::GetBigFood(Food& cfood) {if (snake.back().GetX() == cfood.big_x && snake.back().GetY() == cfood.big_y){cfood.big_flag = false;cfood.big_x = 0;cfood.big_y = 0;SetCursorPosition(1, 0);std::cout << " " ;return true;}elsereturn false; }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
startinterface.h
#ifndef STRATINTERFACE_H #define STARTINTERFACE_H#include <deque> #include <vector> #include "point.h" class StartInterface { public:StartInterface() : speed(35) {startsnake.emplace_back(Point(0,14));//é?startsnake.emplace_back(Point(1,14));startsnake.emplace_back(Point(2,15));startsnake.emplace_back(Point(3,16));startsnake.emplace_back(Point(4,17));startsnake.emplace_back(Point(5,18));startsnake.emplace_back(Point(6,17));startsnake.emplace_back(Point(7,16));startsnake.emplace_back(Point(8,15));startsnake.emplace_back(Point(9,14));textsnake.emplace_back(Point(-26, 14));//Stextsnake.emplace_back(Point(-25, 14));textsnake.emplace_back(Point(-27, 15));textsnake.emplace_back(Point(-26, 16));textsnake.emplace_back(Point(-25, 17));textsnake.emplace_back(Point(-27, 18));textsnake.emplace_back(Point(-26, 18));textsnake.emplace_back(Point(-23, 14));//Ntextsnake.emplace_back(Point(-23, 15));textsnake.emplace_back(Point(-23, 16));textsnake.emplace_back(Point(-23, 17));textsnake.emplace_back(Point(-23, 18));textsnake.emplace_back(Point(-22, 15));textsnake.emplace_back(Point(-21, 16));textsnake.emplace_back(Point(-20, 17));textsnake.emplace_back(Point(-19, 14));textsnake.emplace_back(Point(-19, 15));textsnake.emplace_back(Point(-19, 16));textsnake.emplace_back(Point(-19, 17));textsnake.emplace_back(Point(-19, 18));textsnake.emplace_back(Point(-17, 18));//Atextsnake.emplace_back(Point(-16, 17));textsnake.emplace_back(Point(-15, 16));textsnake.emplace_back(Point(-14, 15));textsnake.emplace_back(Point(-14, 16));textsnake.emplace_back(Point(-13, 14));textsnake.emplace_back(Point(-13, 16));textsnake.emplace_back(Point(-12, 15));textsnake.emplace_back(Point(-12, 16));textsnake.emplace_back(Point(-11, 16));textsnake.emplace_back(Point(-10, 17));textsnake.emplace_back(Point(-9, 18));textsnake.emplace_back(Point(-7, 14));//Ktextsnake.emplace_back(Point(-7, 15));textsnake.emplace_back(Point(-7, 16));textsnake.emplace_back(Point(-7, 17));textsnake.emplace_back(Point(-7, 18));textsnake.emplace_back(Point(-6, 16));textsnake.emplace_back(Point(-5, 15));textsnake.emplace_back(Point(-5, 17));textsnake.emplace_back(Point(-4, 14));textsnake.emplace_back(Point(-4, 18));textsnake.emplace_back(Point(-2, 14));//Etextsnake.emplace_back(Point(-2, 15));textsnake.emplace_back(Point(-2, 16));textsnake.emplace_back(Point(-2, 17));textsnake.emplace_back(Point(-2, 18));textsnake.emplace_back(Point(-1, 14));textsnake.emplace_back(Point(-1, 16));textsnake.emplace_back(Point(-1, 18));textsnake.emplace_back(Point(0, 14));textsnake.emplace_back(Point(0, 16));textsnake.emplace_back(Point(0, 18));}void PrintFirst();void PrintSecond();void PrintThird();void PrintText();void ClearText();void Action(); private:std::deque<Point> startsnake;//開始動(dòng)畫中的蛇std::vector<Point> textsnake;//開始動(dòng)畫中的文字int speed;//動(dòng)畫的速度 }; #endif // STRATINTERFACE_H- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
startinterface.cpp
#include "startinterface.h" #include <windows.h>void StartInterface::PrintFirst()//蛇從左邊出現(xiàn)到完全出現(xiàn)的過程 {for (auto& point : startsnake){point.Print();Sleep(speed);} }void StartInterface::PrintSecond()//蛇從左向右移動(dòng)的過程 {for (int i = 10; i != 40; ++i) //蛇頭需要從10移動(dòng)到40{/*計(jì)算蛇頭的下一個(gè)位置,并將其壓入startsnake中,繪制出來,將蛇尾去掉*/int j = ( ((i-2)%8) < 4 )?( 15 + (i-2)%8 ) : ( 21 - (i-2)%8 );startsnake.emplace_back( Point(i, j) );startsnake.back().Print();startsnake.front().Clear();startsnake.pop_front();Sleep(speed);} }void StartInterface::PrintThird()//蛇從接觸右邊到消失的過程 {while ( !startsnake.empty() || textsnake.back().GetX() < 33 ) //當(dāng)蛇還沒消失或文字沒移動(dòng)到指定位置{if ( !startsnake.empty() ) //如果蛇還沒消失,繼續(xù)移動(dòng){startsnake.front().Clear();startsnake.pop_front();}ClearText();//清除已有文字PrintText();//繪制更新位置后的文字Sleep(speed);} }void StartInterface::PrintText() {for (auto& point : textsnake){if (point.GetX() >= 0)point.Print();} }void StartInterface::ClearText() {for (auto& point : textsnake) //清除的同時(shí)將文字整體向右移動(dòng)一格{if (point.GetX() >= 0)point.Clear();point.ChangePosition(point.GetX() + 1, point.GetY());} }void StartInterface::Action() {PrintFirst();PrintSecond();PrintThird(); }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
tools.h
#ifndef TOOLS_H #define TOOLS_Hvoid SetWindowSize(int cols, int lines); void SetCursorPosition(const int x, const int y); void SetColor(int colorID); void SetBackColor();#endif // TOOLS_H- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
tools.cpp
#include "tools.h" #include <windows.h> #include <stdio.h>void SetWindowSize(int cols, int lines)//設(shè)置窗口大小 {system("title 貪吃蛇");//設(shè)置窗口標(biāo)題char cmd[30];sprintf(cmd, "mode con cols=%d lines=%d", cols * 2, lines);//一個(gè)圖形■占兩個(gè)字符,故寬度乘以2system(cmd);//system(mode con cols=88 lines=88)設(shè)置窗口寬度和高度 }void SetCursorPosition(const int x, const int y)//設(shè)置光標(biāo)位置 { COORD position;position.X = x * 2;position.Y = y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position); }void SetColor(int colorID)//設(shè)置文本顏色 {SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colorID); }void SetBackColor()//設(shè)置文本背景色 {SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED ); }總結(jié)
以上是生活随笔為你收集整理的C++控制台贪吃蛇小游戏详细教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: so调用报错 java.lang.Uns
- 下一篇: more命令 – 显示文本文件内容