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 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表示左,顺时针

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++实现简易贪吃蛇游戏 的全部内容, 来源链接: utcz.com/p/246645.html

回到顶部