C++ vector容器實現(xiàn)貪吃蛇小游戲
本文實例為大家分享了C++ vector容器 實現(xiàn)貪吃蛇,供大家參考,具體內(nèi)容如下
使用vector容器實現(xiàn)貪吃蛇簡化了很多繁瑣操作,且相比之前我的代碼已經(jīng)做到了盡量的簡潔
技術環(huán)節(jié):
編譯環(huán)境:windows VS2019
需求:
控制貪吃蛇吃食物,吃到一個食物蛇身變長一節(jié),得分增加,撞墻或撞自己則游戲結束。
思路:
創(chuàng)建一個vector容器,容器內(nèi)存儲蛇的每節(jié)身體的結構變量,結構變量中保存蛇身體的xy坐標,通過使用vector成員方法不斷添加和刪除容器中的數(shù)據(jù),實現(xiàn)蛇坐標的規(guī)律移動,吃到食物等時執(zhí)行對應操作。
在代碼注釋中標注了每一步是怎么實現(xiàn)的。
注意:
由于編譯器原因程序中_kbhit()和_getch()函數(shù)可能在其他編譯器上編譯會出現(xiàn)錯誤,解決辦法是去掉函數(shù)前面的“_”。
運行效果:

#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() //隨機產(chǎn)生一個食物
{
srand((int)time(NULL));
L1:
m_x = rand() % (85) + 2;
m_y = rand() % (25) + 2;
if (m_x % 2) //如果食物的x坐標不是偶數(shù)則重新確定食物的坐標
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;
//判斷和改變方向函數(shù)
void degdir(Snakecoor& nexthead) //參數(shù):新蛇頭結構變量、蛇坐標容器
{
static char key = 'd'; //靜態(tài)變量防止改變移動方向后重新改回來
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) //根據(jù)key的值確定蛇的移動方向
{
case 'd':
nexthead.x = snakecoor.front().x + 2; //新的蛇頭的頭部等于容器內(nèi)第一個數(shù)據(jù)(舊蛇頭)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; //臨時結構變量用于創(chuàng)建蛇
for (int i = 5; i >= 0; i--) //反向創(chuàng)建初始蛇身,初始蛇頭朝東
{
temp.x = 16 + (i << 1); //偶數(shù)
temp.y = 8;
snakecoor.push_back(temp);
}
}
//蛇運動主要函數(shù)
void move(Food& food, int& score)
{
Snakecoor nexthead; //新蛇頭變量
degdir(nexthead); //判斷和改變蛇前進的方向
snakecoor.insert(snakecoor.begin(), nexthead); //將新的蛇頭插入容器頭部
gotoxy(0, 0);
cout << "得分:" << score; //每次移動都在左上角刷新得分
finishgame(score); //判斷游戲結束函數(shù)
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(); //如果蛇頭坐標和食物坐標重合則重新產(chǎn)生一個食物
return; //直接結束本次移動
}
for (int i = 0; i < snakecoor.size(); i++) //遍歷容器,判斷食物與蛇身是否重合并輸出整條蛇
{
gotoxy(snakecoor[i].x, snakecoor[i].y);
if (!i) //頭部輸出圓形否則輸出方塊
cout << "●";
else
cout << "■";
//如果食物刷新到了蛇身上,則重新產(chǎn)生一個食物
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(); //刪除容器中最后一個數(shù)據(jù)
}
};
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);
}
//主函數(shù)
int main()
{
system("mode con cols=88 lines=28"); //設置控制臺窗口大小
system("title C++ 貪吃蛇"); //設置標題
HideCursor(); //光標隱藏
int score = 0; //得分變量
Food food; //食物對象
food.randfood(); //開局隨機產(chǎn)生一個食物
Snake snake; //蛇對象
while (true)
{
snake.move(food, score);//蛇移動
Sleep(150); //游戲速度
}
return 0;
}
不足之處:
因為初學C++,所以程序中肯定還有一些不規(guī)范或不合理的地方。
關于C++小游戲的更多精彩內(nèi)容請點擊專題: 《C++經(jīng)典小游戲》 學習了解
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
C++ 中malloc()和free()函數(shù)的理解
這篇文章主要介紹了C++ 中malloc()和free()函數(shù)的理解的相關資料,這里提供用法示例幫助大家理解這部分知識,需要的朋友可以參考下2017-08-08
史上最貼心的 VS code C++ 環(huán)境配置超詳細教程
這篇文章主要介紹了史上最貼心的 VS code C++ 環(huán)境配置超詳細教程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02
C++判斷主機是否處于聯(lián)網(wǎng)狀態(tài)
這篇文章主要為大家詳細介紹了C++判斷主機是否處于聯(lián)網(wǎng)狀態(tài),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-06-06
Matlab實現(xiàn)黑洞優(yōu)化算法的示例代碼
根據(jù)黑洞現(xiàn)象原理首次提出BH 算法,它在傳統(tǒng)PSO基礎上引入了新的機制,有效地提高了收斂速度并防止了陷入局部極值的情況發(fā)生.本文將用Matlab實現(xiàn)這一算法,需要的可以參考一下2022-06-06

