C++实现简易贪吃蛇游戏

C++实现建议贪吃蛇(不会闪屏幕)

使用vs2013完成。记录踏上游戏开发的道路。

效果图

代码

// 2021.7.24.1贪吃蛇.cpp : 定义控制台应用程序的入口点。//#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 5struct 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表示左,顺时针 int speed;//指的是几个循环前进一次 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; }}//将数据加载到地图上。返回值为加载后游戏是否失败bool mapLoadData(int arrMap[MAP_MAXIMUM_HEIGHT][MAP_MAXIMUM_WIDTH]){ //加载水果的数据 for (unsigned int i = 0; i < gFruitVector.size(); i++) {  arrMap[gFruitVector[i].FruitX][gFruitVector[i].FruitY] = 2; } //加载蛇的身体数据 for (LISTSNAKEBODY::iterator iter = gSnake.snakeBodyList->begin(); iter != gSnake.snakeBodyList->end(); iter++) {  arrMap[iter->nSnakeBodyX][iter->nSnakeBodyY] = 1; } // 吃到第一个水果的时候,一定不是游戏失败 if (gSnake.snakeBodyList->size() == 1 && gSnake.isExit(gSnake.snakeBodyList->front())) {  return false; } if (arrMap[gSnake.nSnakeHeadX][gSnake.nSnakeHeadY] == 1)  return true; return false;}//更新蛇的数据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; }}//随机生成 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;  } }}//初始化水果数据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); //创建新的缓冲区 HANDLE hOutBuf = CreateConsoleScreenBuffer(  GENERIC_READ | GENERIC_WRITE,  FILE_SHARE_READ | FILE_SHARE_WRITE,  NULL,  CONSOLE_TEXTMODE_BUFFER,  NULL  ); //设置新的缓冲区为活动显示缓冲 SetConsoleActiveScreenBuffer(hOutBuf); //隐藏两个缓冲区的光标 CONSOLE_CURSOR_INFO cci; cci.bVisible = 0; cci.dwSize = 1; SetConsoleCursorInfo(hOutput, &cci); SetConsoleCursorInfo(hOutBuf, &cci); //双缓冲处理显示 DWORD bytes = 0; char data[3200]; //地图,需要将数据映射到地图上,再去渲染地图。 int arrMap[MAP_MAXIMUM_HEIGHT][MAP_MAXIMUM_WIDTH]; srand(time(NULL)); //计数器。 int nProgramCounter = 0; //初始化各个数据 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;}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

世界没有永久的冬天;不要讨厌麻烦,

C++实现简易贪吃蛇游戏

相关文章:

你感兴趣的文章:

标签云: