1. 程式人生 > 程式設計 >C++ vector容器實現貪吃蛇小遊戲

C++ vector容器實現貪吃蛇小遊戲

本文例項為大家分享了C++ vector容器 實現貪吃蛇,供大家參考,具體內容如下

使用vector容器實現貪吃蛇簡化了很多繁瑣操作,且相比之前我的程式碼已經做到了儘量的簡潔

技術環節:

編譯環境:windows VS2019

需求:

控制貪吃蛇吃食物,吃到一個食物蛇身變長一節,得分增加,撞牆或撞自己則遊戲結束。

思路:

建立一個vector容器,容器記憶體儲蛇的每節身體的結構變數,結構變數中儲存蛇身體的xy座標,通過使用vector成員方法不斷新增和刪除容器中的資料,實現蛇座標的規律移動,吃到食物等時執行對應操作。

在程式碼註釋中標註了每一步是怎麼實現的。

注意:

由於編譯器原因程式中_kbhit()和_getch()函式可能在其他編譯器上編譯會出現錯誤,解決辦法是去掉函式前面的“_”。

執行效果:

C++ vector容器實現貪吃蛇小遊戲

#include <iostream>
#include <vector>
#include <windows.h>
#include <conio.h>
#include <ctime>

using namespace std;


void gotoxy(int x,int y); //游標定位

//食物類
class Food
{
private:
 int m_x;
 int m_y;
public:
 void randfood()  //隨機產生一個食物
 {
 srand((int)time(NULL));
 L1:
 m_x = rand() % (85) + 2;
 m_y = rand() % (25) + 2;

 if (m_x % 2) //如果食物的x座標不是偶數則重新確定食物的座標
  goto L1;

 gotoxy(m_x,m_y); //在確認好的位置輸出食物
 cout << "★";
 }
 int getFoodm_x() //返回食物的x座標
 {
 return m_x;
 }
 int getFoodm_y() //返回食物的y座標
 {
 return m_y;
 }
};

//蛇類
class Snake
{
private:
 //蛇座標結構
 struct Snakecoor
 {
 int x;
 int y;
 };
 //蛇容器
 vector<Snakecoor> snakecoor;


 //判斷和改變方向函式
 void degdir(Snakecoor& nexthead) //引數:新蛇頭結構變數、蛇座標容器
 {
 static char key = 'd'; //靜態變數防止改變移動方向後重新改回來

 if (_kbhit())  //改變蛇前進的方向
 {
  char temp = _getch();

  switch (temp) //如果臨時變數的值為wasd中的一個,則賦值給key
  {
  default:
  break;
  case 'w':
  case 'a':
  case 's':
  case 'd':
  //如果temp的方向和key的方向不相反則賦值
  if ((key == 'w' && temp != 's') || (key == 's' && temp != 'w') || \
   (key == 'a' && temp != 'd') || (key == 'd' && temp != 'a'))
   key = temp;
  }
 }


 switch (key) //根據key的值確定蛇的移動方向
 {
 case 'd':
  nexthead.x = snakecoor.front().x + 2;  //新的蛇頭的頭部等於容器內第一個資料(舊蛇頭)x座標+2
  nexthead.y = snakecoor.front().y;
  break;
 case 'a':
  nexthead.x = snakecoor.front().x - 2;
  nexthead.y = snakecoor.front().y;
  break;
 case 'w':
  nexthead.x = snakecoor.front().x;
  nexthead.y = snakecoor.front().y - 1;
  break;
 case 's':
  nexthead.x = snakecoor.front().x;
  nexthead.y = snakecoor.front().y + 1;
 }

 }

 //遊戲結束時需要做的事情
 void finmatt(const int score)
 {
 system("cls");
 gotoxy(40,14);
 cout << "遊戲結束";
 gotoxy(40,16);
 cout << "得分:" << score;
 gotoxy(0,26);
 exit(0);
 }

 //遊戲結束的情況
 void finishgame(const int score)
 {
 //撞牆情況
 if (snakecoor[0].x >= 88 || snakecoor[0].x < 0 || snakecoor[0].y >= 28 || snakecoor[0].y < 0)
  finmatt(score);

 //撞到自己情況
 for (int i = 1; i < snakecoor.size(); i++)
  if (snakecoor[0].x == snakecoor[i].x && snakecoor[0].y == snakecoor[i].y)
  finmatt(score);
 }
public:
 //構造初始化蛇的位置
 Snake()
 {
 Snakecoor temp; //臨時結構變數用於建立蛇

 for (int i = 5; i >= 0; i--) //反向建立初始蛇身,初始蛇頭朝東
 {
  temp.x = 16 + (i << 1); //偶數
  temp.y = 8;
  snakecoor.push_back(temp);
 }

 }

 //蛇運動主要函式
 void move(Food& food,int& score)
 {
 Snakecoor nexthead;  //新蛇頭變數

 degdir(nexthead);  //判斷和改變蛇前進的方向

 snakecoor.insert(snakecoor.begin(),nexthead); //將新的蛇頭插入容器頭部

 gotoxy(0,0);
 cout << "得分:" << score;  //每次移動都在左上角重新整理得分

 finishgame(score);  //判斷遊戲結束函式

 if (snakecoor[0].x == food.getFoodm_x() && snakecoor[0].y == food.getFoodm_y()) //蛇頭與食物重合
 {
  gotoxy(snakecoor[0].x,snakecoor[0].y); //吃到食物時因為直接返回此次移動沒有輸出蛇身,會少輸出一次蛇
  cout << "●";   //所以在這裡補上蛇移動時需要輸出的字元
  gotoxy(snakecoor[1].x,snakecoor[1].y);
  cout << "■";

  score++;  //吃到食物得分+1

  food.randfood(); //如果蛇頭座標和食物座標重合則重新產生一個食物
  return;   //直接結束本次移動
 }

 for (int i = 0; i < snakecoor.size(); i++) //遍歷容器,判斷食物與蛇身是否重合並輸出整條蛇
 {
  gotoxy(snakecoor[i].x,snakecoor[i].y);

  if (!i)    //頭部輸出圓形否則輸出方塊
  cout << "●";
  else
  cout << "■";

  //如果食物重新整理到了蛇身上,則重新產生一個食物
  if (snakecoor[i].x == food.getFoodm_x() && snakecoor[i].y == food.getFoodm_y())
  food.randfood();
 }

 gotoxy(snakecoor.back().x,snakecoor.back().y); //在容器尾部的地方輸出空格
 cout << " ";
 snakecoor.pop_back();   //刪除容器中最後一個數據
 }

};


void HideCursor()  //隱藏游標
{
 CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}

void gotoxy(int x,int y) //游標定位
{
 COORD pos = { x,y };
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

//主函式
int main()
{
 system("mode con cols=88 lines=28");  //設定控制檯視窗大小
 system("title C++ 貪吃蛇");      //設定標題
 HideCursor();     //游標隱藏

 int score = 0;  //得分變數

 Food food;   //食物物件
 food.randfood();  //開局隨機產生一個食物

 Snake snake;  //蛇物件


 while (true)
 {
 snake.move(food,score);//蛇移動

 Sleep(150); //遊戲速度
 }

 return 0;
}

不足之處:

因為初學C++,所以程式中肯定還有一些不規範或不合理的地方。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。