C++控制臺實現(xiàn)貪吃蛇游戲
本文實例為大家分享了C++實現(xiàn)貪吃蛇游戲的具體代碼,供大家參考,具體內(nèi)容如下
剛學完了C語言,便嘗試的寫了貪吃蛇的代碼,但是效果不佳,很多的bug,所以,這個學了C++,便重新的寫了這個小游戲,用類來封裝!
先是頭文件:
struct Snake { int x, y; }; class snake { public: snake() //構(gòu)造函數(shù) { length = 3; s[2].x = 10; s[2].y = 10; s[1].x = 9; s[1].y = 10; s[0].x = 8; s[0].y = 10; up = right = left = down = 0; } ~snake(){} void display(); //顯示蛇身函數(shù) void Rightmove(); //右移函數(shù) void Leftmove(); //左移函數(shù) void Upmove(); //上移函數(shù) void Downmove(); //下移函數(shù) int cheak(); //檢查是否撞墻或撞到自身 void creat_food(); //產(chǎn)生食物 int eat_food(); //吃食物 private: struct Snake s[100]; //先定義蛇身最長100 int length; //當前蛇長度 int x3, y3; //食物坐標 int up, down, right, left; //蛇的狀態(tài),是上移還是下移或... }; void make_frame(); //打印框架的函數(shù) void show(); //游戲開始倒計時函數(shù) void gameover(); //游戲結(jié)束函數(shù)
下面是各個函數(shù)的實現(xiàn)的cpp文件:
# include <iostream> # include <Windows.h> # include <time.h> # include "snake.h" # define MaxLen 20 # define MaxWen 30 using namespace std; HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //獲取句柄 void gotoxy(HANDLE hOut, int x, int y) //輸出位置的函數(shù) { COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(hOut, pos); } void snake::display() //打印蛇身 { for (int i = length - 1; i >= 0; i--) { if (i == length - 1) //打印蛇頭 { gotoxy(hOut, s[i].x, s[i].y); cout << char(15); } else //打印蛇身 { gotoxy(hOut, s[i].x, s[i].y); cout << '*'; } } gotoxy(hOut, 0, 22); } void snake::Rightmove() //右移 { right = 1; up = down = left = 0; int x1, x2, y1, y2; x1 = x2 = s[length - 1].x; y1 = y2 = s[length - 1].y; s[length - 1].x++; //蛇頭x坐標自增 for (int i = length - 2; i >= 0; i--) //除了蛇頭,其他的結(jié)點都等于它的上一個結(jié)點的坐標 { x2 = s[i].x; y2 = s[i].y; s[i].x = x1; s[i].y = y1; x1 = x2; y1 = y2; } gotoxy(hOut, x2, y2); //消除蛇移動遺留的 ‘*' cout << ' '; } void snake::Leftmove() //左移 { left = 1; right = up = down = 0; int x1, x2, y1, y2; x1 = x2 = s[length - 1].x; y1 = y2 = s[length - 1].y; s[length - 1].x--; //同上 for (int i = length - 2; i >= 0; i--) { x2 = s[i].x; y2 = s[i].y; s[i].x = x1; s[i].y = y1; x1 = x2; y1 = y2; } gotoxy(hOut, x2, y2); //同上 cout << ' '; } void snake::Downmove() //下移 { down = 1; right = up = left = 0; int x1, x2, y1, y2; x1 = x2 = s[length - 1].x; y1 = y2 = s[length - 1].y; s[length - 1].y++; //同上 for (int i = length - 2; i >= 0; i--) { x2 = s[i].x; y2 = s[i].y; s[i].x = x1; s[i].y = y1; x1 = x2; y1 = y2; } gotoxy(hOut, x2, y2); //同上 cout << ' '; } void snake::Upmove() //上移 { up = 1; down = right = left = 0; int x1, x2, y1, y2; x1 = x2 = s[length - 1].x; y1 = y2 = s[length - 1].y; s[length - 1].y--; //同上 for (int i = length - 2; i >= 0; i--) { x2 = s[i].x; y2 = s[i].y; s[i].x = x1; s[i].y = y1; x1 = x2; y1 = y2; } gotoxy(hOut, x2, y2); //同上 cout << ' '; } int snake::cheak() { int flag = 0; for (int i = length - 2; i >= 0; i--) //是否撞到自身 { if (s[i].x == s[length - 1].x && s[i].y == s[length - 1].y) { flag = 1; //是,標識符為1 break; } } if (flag == 1 || (s[length - 1].x >= 30 + 1 || s[length - 1].x < 4) || (s[length - 1].y <= 1 || s[length - 1].y >= 20)) { return 0; //檢測是否撞自身,或者撞墻 } else { return 1; } } void snake::creat_food() //產(chǎn)生食物坐標 { xy: x3 = (rand() % (25)) + 3; y3 = (rand() % (17)) + 2; for (int i = length - 1; i >= 0; i--) //檢查食物是否在蛇身上 { if (s[i].x == x3 && s[i].y == y3) //是就重新產(chǎn)生食物坐標 goto xy; } gotoxy(hOut, x3, y3); //顯示食物 cout << '*'; } int snake::eat_food() { if (s[length - 1].x == x3 && s[length - 1].y == y3) //蛇頭碰到食物 { if (up == 1) //如果蛇是在上移,增加一個結(jié)點,為蛇頭的上一個結(jié)點 { s[length].x = x3; s[length].y = y3 - 1; } else if (down == 1) //同上 { s[length].x = x3; s[length].y = y3 + 1; } else if (right == 1) //同上 { s[length].x = x3 + 1; s[length].y = y3; } else if (left == 1) //同上 { s[length].x = x3 - 1; s[length].y = y3; } length++; //蛇長加1 return 1; } else return 0; } void make_frame() //打印框架函數(shù) { cout << " 貪吃蛇游戲" << endl; gotoxy(hOut, 2, 1); cout << "╔"; for (int i = 4; i < 2 + MaxWen; i++) { gotoxy(hOut, i, 1); printf("="); } for (int i = 2; i < MaxLen; i++) { gotoxy(hOut, 2, i); printf("║"); } gotoxy(hOut, 2 + MaxWen, 1); printf("╗"); for (int i = 2; i < MaxLen; i++) { gotoxy(hOut, 2 + MaxWen, i); printf("║"); } gotoxy(hOut, 2, MaxLen); printf("╚"); gotoxy(hOut, 2 + MaxWen, MaxLen); printf("╝"); for (int i = 4; i < 2 + MaxWen; i++) { gotoxy(hOut, i, MaxLen); printf("="); } } void show() //顯示操作方法和游戲開始倒計時 { gotoxy(hOut, 35, 5); cout << "↑:" << 'w'; gotoxy(hOut, 35, 6); cout << "←:" << 'a'; gotoxy(hOut, 35, 7); cout << "↓:" << 's'; gotoxy(hOut, 35, 8); cout << "→:" << 'd'; gotoxy(hOut, 16, 5); cout << '3'; Sleep(1000); gotoxy(hOut, 16, 5); cout << '2'; Sleep(1000); gotoxy(hOut, 16, 5); cout << '1'; Sleep(1000); gotoxy(hOut, 16, 5); cout << ' '; } void gameover() //游戲結(jié)束函數(shù) { system("cls"); system("color 3B"); gotoxy(hOut, 14, 5); cout << " GAME OVER!"; gotoxy(hOut, 14, 6); cout << "PLAY AGAIN ? Y(yes) \ N(no)"; }
主函數(shù)的cpp文件:
# include <iostream> # include <Windows.h> # include <conio.h> # include "snake.h" using namespace std; char ch; int main() { while (1) { snake sn; //聲明對象 system("cls"); //清屏 system("color 3B"); //背景和字體顏色調(diào)整 make_frame(); //打印框架 sn.display(); //顯示蛇 show(); //游戲開始 sn.creat_food(); //產(chǎn)生食物 while (sn.cheak()) //檢查是否死亡 { sn.Rightmove(); //右移 sn.display(); //顯示蛇身 if (sn.eat_food()) //檢查是否吃到食物 { sn.creat_food(); //重新產(chǎn)生食物 sn.display(); } Sleep(500); //等待500Ms p: if (_kbhit()) //是否有按鍵 { ch = _getch(); if (ch == 97 || ch == 100) goto p; if (ch == 115 || ch == 119) break; } } pp: switch (ch) //有按鍵 { case 119: //上移的情況 { while (sn.cheak()) { sn.Upmove(); sn.display(); if (sn.eat_food()) { sn.creat_food(); sn.display(); Sleep(300); } Sleep(500); pw: if (_kbhit()) { ch = _getch(); if (ch == 119 || ch == 115) goto pw; if (ch == 97 || ch == 100) goto pp; } } }break; case 97: //左移的情況 { while (sn.cheak()) { sn.Leftmove(); sn.display(); if (sn.eat_food()) { sn.creat_food(); sn.display(); } Sleep(500); pa: if (_kbhit()) { ch = _getch(); if (ch == 97 || ch == 100) goto pa; if (ch == 115 || ch == 119) goto pp; } } }break; case 115: //下移的情況 { while (sn.cheak()) { sn.Downmove(); sn.display(); if (sn.eat_food()) { sn.creat_food(); sn.display(); Sleep(300); } Sleep(500); ps: if (_kbhit()) { ch = _getch(); if (ch == 115 || ch == 119) goto ps; if (ch == 97 || ch == 100) goto pp; } } }break; case 100: //右移的情況 { while (sn.cheak()) { sn.Rightmove(); sn.display(); if (sn.eat_food()) { sn.creat_food(); sn.display(); } Sleep(500); pd: if (_kbhit()) { ch = _getch(); if (ch == 100 || ch == 97) goto pd; if (ch == 119 || ch == 115) goto pp; } } }break; default: break; } gameover(); //顯示游戲結(jié)束,是否重玩 py: ch = _getch(); if (ch == 110) //否 { system("cls"); break; } else if (ch == 121) //是 continue; else goto py; } return 0; }
下面是游戲的截圖:
控制臺的實現(xiàn),不是很美觀,主要是由于上下和左右的間隙不一樣大,所以看起來不是很好看,但總體還是實現(xiàn)了貪吃蛇!
關(guān)于C++小游戲的更多精彩內(nèi)容請點擊專題: 《C++經(jīng)典小游戲》 學習了解
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++實現(xiàn)LeetCode(兩個有序數(shù)組的中位數(shù))
這篇文章主要介紹了C++實現(xiàn)LeetCode(兩個有序數(shù)組的中位數(shù)),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07c++靜態(tài)局部變量和靜態(tài)函數(shù)示例
這篇文章主要介紹了c++靜態(tài)局部變量和靜態(tài)函數(shù)示例,需要的朋友可以參考下2014-04-04Protocol Buffer技術(shù)深入理解(C++實例)
C++實例Protocol Buffer技術(shù)詳解,感興趣的朋友可以了解下2013-01-01C++利用easyx圖形庫實現(xiàn)創(chuàng)意天天酷跑小游戲
這篇文章主要為大家詳細介紹了C++如何利用easyx圖形庫實現(xiàn)創(chuàng)意小游戲——天天酷跑,文中的示例代碼講解詳細,快跟隨小編一起了解一下吧2023-03-03C++中繼承與多態(tài)的基礎(chǔ)虛函數(shù)類詳解
這篇文章主要給大家介紹了關(guān)于C++中繼承與多態(tài)的基礎(chǔ)虛函數(shù)類的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。2017-09-09