c++贪吃蛇双缓冲版

由于单缓冲版(非局部绘制)闪屏严重且cls效率过差,双缓冲版应运而生

HDU/数字媒体技术/游戏程序设计作业

#include<iostream>
#include <math.h>
#include<windows.h>
#include<conio.h>

using namespace std;
HANDLE hOutput, hOutBuf;
COORD coord = { 0,0 };
DWORD bytes = 0;
bool bufferSwapFlag = false;

bool gameOver;
const int width = 40;
const int height = 20;

char ScreenData[width + 5][height + 5];

int x, y, fruitX, fruitY, score;
int tailX[100], tailY[100];
int nTail;
enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };
eDirection dir;
void Initial()
{
	hOutBuf = CreateConsoleScreenBuffer(
		GENERIC_WRITE,//定义进程可以往缓冲区写数据
		FILE_SHARE_WRITE,//定义缓冲区可共享写权限
		NULL,
		CONSOLE_TEXTMODE_BUFFER,
		NULL
	);
	hOutput = CreateConsoleScreenBuffer(
		GENERIC_WRITE,
		FILE_SHARE_WRITE,
		NULL,
		CONSOLE_TEXTMODE_BUFFER,
		NULL
	);
	//隐藏两个缓冲区的光标
	CONSOLE_CURSOR_INFO cci;
	cci.bVisible = 0;
	cci.dwSize = 1;
	SetConsoleCursorInfo(hOutput, &cci);
	SetConsoleCursorInfo(hOutBuf, &cci);
	gameOver = false;
	dir = STOP;
	x = width / 2;
	y = height / 2;
	fruitX = rand() % width;
	fruitY = rand() % height;
}
void Draw()
{
	system("cls");
	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);

	for (int i = 0; i < width + 2; i++)
		cout << "#";
	cout << endl;
	int textColor = 0X06;
	SetConsoleTextAttribute(h, textColor);

	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			if (j == 0)
			{
				textColor = 0X0b;
				SetConsoleTextAttribute(h, textColor);
				cout << "#";
			}
			if (i == fruitY && j == fruitX)
			{
				textColor = 0X44;
				SetConsoleTextAttribute(h, textColor);
				cout << "F";
			}
			else if (i == y && j == x)
			{
				textColor = 0Xaa;
				SetConsoleTextAttribute(h, textColor);
				cout << "O";
			}
			else
			{
				bool flagPrint = false;
				for (int k = 0; k < nTail; k++)
				{
					if (tailX[k] == j && tailY[k] == i)
					{
						textColor = 0Xaa;
						SetConsoleTextAttribute(h, textColor);
						cout << "o";
						flagPrint = true;
					}
				}
				textColor = 0X06;
				SetConsoleTextAttribute(h, textColor);
				if (!flagPrint)
					cout << " ";
			}


			if (j == width - 1)
			{
				textColor = 0X0b;
				SetConsoleTextAttribute(h, textColor);
				cout << "#";
			}

		}
		cout << endl;
	}

	for (int i = 0; i < width + 2; i++)
		cout << "#";
	cout << endl;
	cout << "游戏得分:" << score << endl;
}
void Draw2()
{
	WORD textColor = 0Xbb;
	WORD textColor1 = 0X44;
	WORD textColor2 = 0Xaa;
	WORD textColor3 = 0X00;
	WORD textColor4 = 0X11;
	short i, j;
	int currentLine = 0;
	COORD coord1;
	for (int j = 0; j < width; j++)
	{
		coord1.X = j;
		coord1.Y = currentLine;
		WriteConsoleOutputAttribute(hOutBuf, &textColor, 1, coord1, &bytes);
		WriteConsoleOutputAttribute(hOutput, &textColor, 1, coord1, &bytes);
		ScreenData[currentLine][j] = '#';
	}

	currentLine++;

	for (i = 0; i < height; i++)
	{
		for (j = 0; j < width; j++)
		{
			if (j == 0)
			{
				coord1.X = j;
				coord1.Y = currentLine + i;
				WriteConsoleOutputAttribute(hOutBuf, &textColor, 1, coord1, &bytes);
				WriteConsoleOutputAttribute(hOutput, &textColor, 1, coord1, &bytes);
				ScreenData[currentLine + i][j] = '#';
			}

			else if (i == fruitY && j == fruitX)
			{
				coord1.X = j;
				coord1.Y = currentLine + i;
				WriteConsoleOutputAttribute(hOutBuf, &textColor1, 1, coord1, &bytes);
				WriteConsoleOutputAttribute(hOutput, &textColor1, 1, coord1, &bytes);
				ScreenData[currentLine + i][j] = 'F';
			}
			else if (i == y && j == x)
			{
				coord1.X = j;
				coord1.Y = currentLine + i;
				WriteConsoleOutputAttribute(hOutBuf, &textColor4, 1, coord1, &bytes);
				WriteConsoleOutputAttribute(hOutput, &textColor4, 1, coord1, &bytes);
				ScreenData[currentLine + i][j] = '0';
			}
			else
			{
				bool flagPrint = false;
				for (int k = 0; k < nTail; k++)
				{
					if (tailX[k] == j && tailY[k] == i)
					{
						coord1.X = j;
						coord1.Y = currentLine + i;
						WriteConsoleOutputAttribute(hOutBuf, &textColor2, 1, coord1, &bytes);
						WriteConsoleOutputAttribute(hOutput, &textColor2, 1, coord1, &bytes);
						ScreenData[currentLine + i][j] = 'o';
						flagPrint = true;
					}
				}
				if (!flagPrint)
				{
					coord1.X = j;
					coord1.Y = currentLine + i;
					WriteConsoleOutputAttribute(hOutBuf, &textColor3, 1, coord1, &bytes);
					WriteConsoleOutputAttribute(hOutput, &textColor3, 1, coord1, &bytes);
					ScreenData[currentLine + i][j] = ' ';
				}

			}


			if (j == width - 1)
			{
				coord1.X = j;
				coord1.Y = currentLine + i;
				WriteConsoleOutputAttribute(hOutBuf, &textColor, 1, coord1, &bytes);
				WriteConsoleOutputAttribute(hOutput, &textColor, 1, coord1, &bytes);
				ScreenData[currentLine + i][j] = '#';
			}

		}
	}

	for (j = 0; j < width; j++)
	{
		coord1.X = j;
		coord1.Y = currentLine + i;
		WriteConsoleOutputAttribute(hOutBuf, &textColor, 1, coord1, &bytes);
		WriteConsoleOutputAttribute(hOutput, &textColor, 1, coord1, &bytes);
		ScreenData[currentLine + i][j] = '#';
	}

	currentLine++;

	//sprintf_s(ScreenData[currentLine + i], "游戏得分:%d", score)
	sprintf_s(ScreenData[currentLine + i], "游戏得分:%4d", score);
}

void Show_doublebuffer()
{
	int i;
	Draw2();
	if (bufferSwapFlag == false)
	{
		bufferSwapFlag = true;
		for (i = 0; i < height + 5; i++)
		{
			coord.Y = i;
			WriteConsoleOutputCharacterA(hOutBuf, ScreenData[i], width, coord, &bytes);
		}
		SetConsoleActiveScreenBuffer(hOutBuf);
	}
	else
	{
		bufferSwapFlag = false;
		for (i = 0; i < height + 5; i++)
		{
			coord.Y = i;
			WriteConsoleOutputCharacterA(hOutput, ScreenData[i], width, coord, &bytes);
		}
		SetConsoleActiveScreenBuffer(hOutput);
	}

}
void Input()
{
	if (_kbhit())
	{
		switch (_getch())
		{
		case 'a':
		{
			if (dir == RIGHT)
				dir = RIGHT;
			else
				dir = LEFT;
			break;
		}
		case 'd':
		{
			if (dir == LEFT)
				dir == LEFT;
			else
				dir = RIGHT;
			break;
		}
		case 'w':
		{
			if (dir == DOWN)
				dir == DOWN;
			else
				dir = UP;
			break;
		}

		case 's':
		{
			if (dir == UP)
				dir = UP;
			else
				dir = DOWN;
			break;
		}

		case 'x':
			gameOver = true;
			break;
		default:
			break;
		}
	}
}
void Logic()
{
	int prevX = tailX[0];
	int prevY = tailY[0];
	int prev2X, prev2Y;
	tailX[0] = x;
	tailY[0] = y;
	for (int i = 1; i < nTail; i++)
	{
		prev2X = tailX[i];
		prev2Y = tailY[i];
		tailX[i] = prevX;
		tailY[i] = prevY;
		prevX = prev2X;
		prevY = prev2Y;
	}
	switch (dir)
	{
	case LEFT:
		x--;
		break;
	case RIGHT:
		x++;
		break;
	case UP:
		y--;
		break;
	case DOWN:
		y++;
		break;
	default:
		break;
	}

	//if(x>width || x<0 || y>height||y<0)
	//	gameOver = true;

	if (x >= width - 1)	x = 1;
	else if (x < 1)
		x = width - 2;
	if (y >= height)	y = 0;
	else if (y < 0)
		y = height - 1;


	if (x == fruitX && y == fruitY)
	{
		score += 10;
		fruitX = rand() % (width -2);
		fruitY = rand() % height;
		nTail++;
	}
	for (int i = 0; i < nTail; i++)
	{
		if (tailX[i] == fruitX && tailY[i] == fruitY)
		{
			fruitX = rand() % (width - 2);
			fruitX = rand() % height;
		}
		if (tailX[i] == x && tailY[i] == y)
			gameOver = true;
	}



}
int Over()
{
	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
	int textColor = 0X04;
	SetConsoleTextAttribute(h, textColor);

	cout << "	  _____          __  __ ______    ______      ________ _____" << endl;
	cout << "	 / ____|   /\\   |  \\/  |  ____|  / __ \\ \\    / /  ____| __  \\" << endl;
	cout << "	| |  __   /  \\  | \\  / | |__    | |  | \\ \\  / /| |__  | |__) |" << endl;
	cout << "	| | |_ | / /\\ \\ | |\\/| |  __|   | |  | |\\ \\/ / |  __| |  _  /" << endl;
	cout << "	| |__| |/ ____ \\| |  | | |____  | |__| | \\  /  | |____| | \\ \\" << endl;
	cout << "         \\_____/_/    \\_\\_|  |_|______|  \\____ /  \\/   |______|_|  \\_\\" << endl;
	cout << endl;
	textColor = 0X0b;
	SetConsoleTextAttribute(h, textColor);
	cout << "您的得分为:" << score << endl;
	return 0;
}
int main()
{
	Initial();
	while (!gameOver)
	{
		//Draw();
		Show_doublebuffer();
		Input();
		Logic();
		Sleep(30);
	}
	Over();
	return 0;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于C++语言开发的贪吃蛇游戏的双人对战源码的部分代码,仅供参考: ```c++ #include <iostream> #include <conio.h> #include <windows.h> #include <ctime> #include <cstdlib> using namespace std; bool gameOver; const int width = 20; const int height = 20; int x1, y1, x2, y2, fruitX, fruitY, score1, score2; int tail1X[100], tail1Y[100], tail2X[100], tail2Y[100]; int nTail1, nTail2; enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN }; eDirection dir1, dir2; void Setup() { gameOver = false; dir1 = STOP; dir2 = STOP; x1 = width / 4; y1 = height / 2; x2 = 3 * width / 4; y2 = height / 2; fruitX = rand() % width; fruitY = rand() % height; score1 = 0; score2 = 0; } void Draw() { system("cls"); for (int i = 0; i < width + 2; i++) cout << "#"; cout << endl; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (j == 0) cout << "#"; if (i == y1 && j == x1) cout << "1"; else if (i == y2 && j == x2) cout << "2"; else if (i == fruitY && j == fruitX) cout << "F"; else { bool print = false; for (int k = 0; k < nTail1; k++) { if (tail1X[k] == j && tail1Y[k] == i) { cout << "o"; print = true; } } for (int k = 0; k < nTail2; k++) { if (tail2X[k] == j && tail2Y[k] == i) { cout << "o"; print = true; } } if (!print) cout << " "; } if (j == width - 1) cout << "#"; } cout << endl; } for (int i = 0; i < width + 2; i++) cout << "#"; cout << endl; cout << "Player 1: " << score1 << endl; cout << "Player 2: " << score2 << endl; } void Input() { if (_kbhit()) { switch (_getch()) { case 'a': dir1 = LEFT; break; case 'd': dir1 = RIGHT; break; case 'w': dir1 = UP; break; case 's': dir1 = DOWN; break; case 'j': dir2 = LEFT; break; case 'l': dir2 = RIGHT; break; case 'i': dir2 = UP; break; case 'k': dir2 = DOWN; break; case 'x': gameOver = true; break; } } } void Logic() { int prevX1 = tail1X[0]; int prevY1 = tail1Y[0]; int prevX2 = tail2X[0]; int prevY2 = tail2Y[0]; int prev2X1, prev2Y1, prev2X2, prev2Y2; tail1X[0] = x1; tail1Y[0] = y1; tail2X[0] = x2; tail2Y[0] = y2; for (int i = 1; i < nTail1; i++) { prev2X1 = tail1X[i]; prev2Y1 = tail1Y[i]; tail1X[i] = prevX1; tail1Y[i] = prevY1; prevX1 = prev2X1; prevY1 = prev2Y1; } for (int i = 1; i < nTail2; i++) { prev2X2 = tail2X[i]; prev2Y2 = tail2Y[i]; tail2X[i] = prevX2; tail2Y[i] = prevY2; prevX2 = prev2X2; prevY2 = prev2Y2; } switch (dir1) { case LEFT: x1--; break; case RIGHT: x1++; break; case UP: y1--; break; case DOWN: y1++; break; default: break; } switch (dir2) { case LEFT: x2--; break; case RIGHT: x2++; break; case UP: y2--; break; case DOWN: y2++; break; default: break; } if (x1 >= width) x1 = 0; else if (x1 < 0) x1 = width - 1; if (y1 >= height) y1 = 0; else if (y1 < 0) y1 = height - 1; if (x2 >= width) x2 = 0; else if (x2 < 0) x2 = width - 1; if (y2 >= height) y2 = 0; else if (y2 < 0) y2 = height - 1; for (int i = 0; i < nTail1; i++) if (tail1X[i] == x1 && tail1Y[i] == y1) gameOver = true; for (int i = 0; i < nTail2; i++) if (tail2X[i] == x2 && tail2Y[i] == y2) gameOver = true; if (x1 == fruitX && y1 == fruitY) { score1 += 10; fruitX = rand() % width; fruitY = rand() % height; nTail1++; } if (x2 == fruitX && y2 == fruitY) { score2 += 10; fruitX = rand() % width; fruitY = rand() % height; nTail2++; } } int main() { Setup(); while (!gameOver) { Draw(); Input(); Logic(); Sleep(50); } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值