C++實(shí)現(xiàn)簡易貪吃蛇游戲
更新時(shí)間:2021年07月29日 11:11:19 作者:AAH。
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡易貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
C++實(shí)現(xiàn)建議貪吃蛇(不會閃屏幕)
使用vs2013完成。記錄踏上游戲開發(fā)的道路。
效果圖
代碼
// 2021.7.24.1貪吃蛇.cpp : 定義控制臺應(yīng)用程序的入口點(diǎn)。 // #include "stdafx.h" #include <iostream> #include <list> #include <numeric> #include <algorithm> #include <Windows.h> #include <WinUser.h> #include <cstdlib> #include <ctime> #include <vector> using namespace std; #define KEY_DOWN(vk_code) (GetAsyncKeyState(vk_code) & 0x8000 ? 1 : 0) #define MAX_SNAKE_LEN 20 #define MAP_MAXIMUM_HEIGHT 20 #define MAP_MAXIMUM_WIDTH 20 #define MAX_NUMBER_FRUIT 5 struct sSnakeBody { void setPostion(int x, int y) { nSnakeBodyX = x; nSnakeBodyY = y; } void setPostion(sSnakeBody* temp) { nSnakeBodyX = temp->nSnakeBodyX; nSnakeBodyY = temp->nSnakeBodyY; } int nSnakeBodyX; int nSnakeBodyY; }; typedef list<sSnakeBody> LISTSNAKEBODY; struct sSnake { sSnake() { nSnakeHeadX = 1; nSnakeHeadY = 1; nSnakeDirection = 1; speed = 5; } bool isExit(sSnakeBody temp) { if (nSnakeHeadX==temp.nSnakeBodyX&&nSnakeHeadY==temp.nSnakeBodyY) { return true; } return false; } bool isExit(int x, int y) { if (nSnakeHeadX == x&&nSnakeHeadY == y) { return true; } return false; } void reduction(sSnakeBody temp) { nSnakeHeadX = 2 * nSnakeHeadXBk - temp.nSnakeBodyX; nSnakeHeadY = 2 * nSnakeHeadYBk - temp.nSnakeBodyY; } int nSnakeHeadX; int nSnakeHeadY; int nSnakeHeadXBk; int nSnakeHeadYBk; int nSnakeDirection;//0表示上,1表示右,2表示下,3表示左,順時(shí)針 int speed;//指的是幾個循環(huán)前進(jìn)一次 LISTSNAKEBODY snakeBodyList[MAX_SNAKE_LEN]; }; struct sFruit { int FruitX; int FruitY; sFruit() { FruitX = -1; FruitY = -1; } sFruit(int x, int y) { FruitX = x; FruitY = y; } bool isExit(sSnake snake) { if (FruitX == snake.nSnakeHeadX && FruitY == snake.nSnakeHeadY) return true; else return false; } }; vector<sFruit> gFruitVector; sSnake gSnake; //顯示地圖 void showArrMap(int arrMap[MAP_MAXIMUM_HEIGHT][MAP_MAXIMUM_WIDTH]) { system("cls"); for (int i = 0; i < MAP_MAXIMUM_HEIGHT; i++) { for (int j = 0; j < MAP_MAXIMUM_WIDTH; j++) { if (1 == arrMap[i][j] || gSnake.isExit(i,j)) { cout << "■"; } else if (arrMap[i][j] == 2) { cout << "●"; } else { cout << " "; } } if (4 == i) { cout << "\t得分:" << gSnake.snakeBodyList->size(); } cout << endl; } } //將數(shù)據(jù)加載到地圖上。返回值為加載后游戲是否失敗 bool mapLoadData(int arrMap[MAP_MAXIMUM_HEIGHT][MAP_MAXIMUM_WIDTH]) { //加載水果的數(shù)據(jù) for (unsigned int i = 0; i < gFruitVector.size(); i++) { arrMap[gFruitVector[i].FruitX][gFruitVector[i].FruitY] = 2; } //加載蛇的身體數(shù)據(jù) for (LISTSNAKEBODY::iterator iter = gSnake.snakeBodyList->begin(); iter != gSnake.snakeBodyList->end(); iter++) { arrMap[iter->nSnakeBodyX][iter->nSnakeBodyY] = 1; } // 吃到第一個水果的時(shí)候,一定不是游戲失敗 if (gSnake.snakeBodyList->size() == 1 && gSnake.isExit(gSnake.snakeBodyList->front())) { return false; } if (arrMap[gSnake.nSnakeHeadX][gSnake.nSnakeHeadY] == 1) return true; return false; } //更新蛇的數(shù)據(jù) void updateSnake(int &nProgramCounter) { if (nProgramCounter > gSnake.speed) { gSnake.nSnakeHeadXBk = gSnake.nSnakeHeadX; gSnake.nSnakeHeadYBk = gSnake.nSnakeHeadY; if (gSnake.nSnakeDirection == 0) { gSnake.nSnakeHeadX--; } else if (gSnake.nSnakeDirection == 1) { gSnake.nSnakeHeadY++; } else if (gSnake.nSnakeDirection == 2) { gSnake.nSnakeHeadX++; } else if (gSnake.nSnakeDirection == 3) { gSnake.nSnakeHeadY--; } if (gSnake.snakeBodyList->size() != 0) { if (gSnake.isExit(gSnake.snakeBodyList->front())) { gSnake.reduction(gSnake.snakeBodyList->front()); } } //蛇的身體移動 if (gSnake.snakeBodyList->size() != 0) { sSnakeBody snakeBody; snakeBody.setPostion(gSnake.nSnakeHeadXBk, gSnake.nSnakeHeadYBk); gSnake.snakeBodyList->push_front(snakeBody); gSnake.snakeBodyList->pop_back(); } nProgramCounter = 0; } } //綁定鍵盤事件 void bindKeyboardEvents() { if (KEY_DOWN(VK_UP)) { gSnake.nSnakeDirection = 0; } else if (KEY_DOWN(VK_RIGHT)) { gSnake.nSnakeDirection = 1; } else if (KEY_DOWN(VK_DOWN)) { gSnake.nSnakeDirection = 2; } else if (KEY_DOWN(VK_LEFT)) { gSnake.nSnakeDirection = 3; } if (KEY_DOWN(VK_SHIFT)) { gSnake.speed = 2; } else { gSnake.speed = 5; } } //隨機(jī)生成 N 個水果, void randomlyGeneratedFruit(int N, int arrMap[MAP_MAXIMUM_HEIGHT][MAP_MAXIMUM_WIDTH]) { int maxi = MAP_MAXIMUM_HEIGHT; int maxj = MAP_MAXIMUM_WIDTH; int AllCnt = 0; vector<int> randMap; for (int i = 0; i < maxi; i++) { for (int j = 0; j < maxj; j++) { if (0 == arrMap[i][j]) { randMap.push_back(i*maxj + j); AllCnt++; } } } if (AllCnt < N) { N = AllCnt; } for (int i = 0; i < N; i++) { int temp = (rand() % AllCnt--); randMap.erase(randMap.begin() + temp); sFruit fruitTemp = sFruit(temp / maxi + 1, temp % (maxi - 2) + 1); gFruitVector.push_back(fruitTemp); } } //初始化地圖 void initArrMap(int arrMap[MAP_MAXIMUM_HEIGHT][MAP_MAXIMUM_WIDTH]) { for (int i = 0; i < MAP_MAXIMUM_HEIGHT; i++) { for (int j = 0; j < MAP_MAXIMUM_WIDTH; j++) { if (i == 0 || j == 0 || i == MAP_MAXIMUM_HEIGHT - 1 || j == MAP_MAXIMUM_WIDTH - 1) arrMap[i][j] = 1; else arrMap[i][j] = 0; } } } //初始化水果數(shù)據(jù) void initFruit(int arrMap[MAP_MAXIMUM_HEIGHT][MAP_MAXIMUM_WIDTH]) { randomlyGeneratedFruit(MAX_NUMBER_FRUIT, arrMap); } //蛇頭吃到水果事件 void eatFruitEvent(int arrMap[MAP_MAXIMUM_HEIGHT][MAP_MAXIMUM_WIDTH]) { for (unsigned int i = 0; i < gFruitVector.size(); i++) { if (gFruitVector[i].isExit(gSnake)) { sSnakeBody snakeBodyTemp; if (gSnake.snakeBodyList->size() == 0) { snakeBodyTemp.setPostion(gSnake.nSnakeHeadX, gSnake.nSnakeHeadY); } else { snakeBodyTemp.setPostion(&gSnake.snakeBodyList->back()); } gSnake.snakeBodyList->push_back(snakeBodyTemp); gFruitVector.erase(gFruitVector.begin() + i); randomlyGeneratedFruit(1, arrMap); } } } int _tmain(int argc, _TCHAR* argv[]) { HANDLE hOutput; COORD coord = { 0, 0 }; hOutput = GetStdHandle(STD_OUTPUT_HANDLE); //創(chuàng)建新的緩沖區(qū) HANDLE hOutBuf = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, NULL ); //設(shè)置新的緩沖區(qū)為活動顯示緩沖 SetConsoleActiveScreenBuffer(hOutBuf); //隱藏兩個緩沖區(qū)的光標(biāo) CONSOLE_CURSOR_INFO cci; cci.bVisible = 0; cci.dwSize = 1; SetConsoleCursorInfo(hOutput, &cci); SetConsoleCursorInfo(hOutBuf, &cci); //雙緩沖處理顯示 DWORD bytes = 0; char data[3200]; //地圖,需要將數(shù)據(jù)映射到地圖上,再去渲染地圖。 int arrMap[MAP_MAXIMUM_HEIGHT][MAP_MAXIMUM_WIDTH]; srand(time(NULL)); //計(jì)數(shù)器。 int nProgramCounter = 0; //初始化各個數(shù)據(jù) initArrMap(arrMap); initFruit(arrMap); while (true) { nProgramCounter++; initArrMap(arrMap); bindKeyboardEvents(); updateSnake(nProgramCounter); eatFruitEvent(arrMap); bool bIsWin = mapLoadData(arrMap); showArrMap(arrMap); if (bIsWin) { cout << endl << "游戲失?。。?!"; ReadConsoleOutputCharacterA(hOutput, data, 3200, coord, &bytes); WriteConsoleOutputCharacterA(hOutBuf, data, 3200, coord, &bytes); break; } ReadConsoleOutputCharacterA(hOutput, data, 3200, coord, &bytes); WriteConsoleOutputCharacterA(hOutBuf, data, 3200, coord, &bytes); } system("pause"); return 0; }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
- C++ 情懷游戲貪吃蛇的實(shí)現(xiàn)流程詳解
- 利用C/C++實(shí)現(xiàn)貪吃蛇游戲
- C++入門指南之貪吃蛇游戲的實(shí)現(xiàn)
- C++實(shí)現(xiàn)簡單貪吃蛇小游戲
- C++實(shí)現(xiàn)貪吃蛇游戲
- C++代碼實(shí)現(xiàn)貪吃蛇小游戲
- 基于easyx的C++實(shí)現(xiàn)貪吃蛇
- C++控制臺循環(huán)鏈表實(shí)現(xiàn)貪吃蛇
- C++控制臺實(shí)現(xiàn)貪吃蛇游戲
- C++通過類實(shí)現(xiàn)控制臺貪吃蛇
- C++結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)貪吃蛇
- c++實(shí)現(xiàn)超簡單的貪吃蛇游戲?qū)嵗榻B
相關(guān)文章
C++控制臺實(shí)現(xiàn)簡單人機(jī)對弈井字棋
這篇文章主要為大家詳細(xì)介紹了C++控制臺實(shí)現(xiàn)簡單人機(jī)對弈井字棋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05最新VScode C/C++ 環(huán)境配置的詳細(xì)教程
這篇文章主要介紹了最新VScode C/C++ 環(huán)境配置的詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11c++利用vector創(chuàng)建二維數(shù)組的幾種方法總結(jié)
這篇文章主要介紹了c++利用vector創(chuàng)建二維數(shù)組的幾種方法總結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11C語言程序設(shè)計(jì)之指針的應(yīng)用詳解
為了讓大家能夠更準(zhǔn)確的了解C語言中指針的使用,本文為大家準(zhǔn)備了四個指針相關(guān)的例題,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下2022-11-11