亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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í)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解CLion配置openMP的方法

    詳解CLion配置openMP的方法

    這篇文章主要介紹了CLion配置openMP的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • C++控制臺實(shí)現(xiàn)簡單人機(jī)對弈井字棋

    C++控制臺實(shí)現(xiàn)簡單人機(jī)對弈井字棋

    這篇文章主要為大家詳細(xì)介紹了C++控制臺實(shí)現(xiàn)簡單人機(jī)對弈井字棋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 從匯編看c++中extern關(guān)鍵字的使用

    從匯編看c++中extern關(guān)鍵字的使用

    本篇文章介紹了,在c++中extern關(guān)鍵字的使用概述,需要的朋友參考下
    2013-05-05
  • 詳解c++ libuv工作隊(duì)列

    詳解c++ libuv工作隊(duì)列

    這篇文章主要介紹了c++ libuv工作隊(duì)列的相關(guān)資料,幫助大家更好的理解和使用libuv,感興趣的朋友可以了解下
    2021-02-02
  • C語言枚舉的使用以及作用

    C語言枚舉的使用以及作用

    這篇文章主要介紹了C語言枚舉的使用以及使用,閱讀下面內(nèi)容我們將掌握枚舉的相關(guān)概念、掌握枚舉的幾種用法、掌握枚舉在實(shí)際產(chǎn)品中的用法,需要的朋友可以參考一下
    2022-03-03
  • 最新VScode C/C++ 環(huán)境配置的詳細(xì)教程

    最新VScode C/C++ 環(huán)境配置的詳細(xì)教程

    這篇文章主要介紹了最新VScode C/C++ 環(huán)境配置的詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Pthread?并發(fā)編程線程自底向上深入解析

    Pthread?并發(fā)編程線程自底向上深入解析

    這篇文章主要為大家介紹了Pthread?并發(fā)編程線程自底向上深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • C++插入排序算法實(shí)例詳解

    C++插入排序算法實(shí)例詳解

    這篇文章主要為大家詳細(xì)介紹了C++插入排序算法實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • c++利用vector創(chuàng)建二維數(shù)組的幾種方法總結(jié)

    c++利用vector創(chuàng)建二維數(shù)組的幾種方法總結(jié)

    這篇文章主要介紹了c++利用vector創(chuàng)建二維數(shù)組的幾種方法總結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語言程序設(shè)計(jì)之指針的應(yīng)用詳解

    C語言程序設(shè)計(jì)之指針的應(yīng)用詳解

    為了讓大家能夠更準(zhǔn)確的了解C語言中指針的使用,本文為大家準(zhǔn)備了四個指針相關(guān)的例題,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下
    2022-11-11

最新評論