1. 程式人生 > >【小遊戲】C++手工製作貪吃蛇

【小遊戲】C++手工製作貪吃蛇

//
#include<stdio.h>
//鍵盤敲擊
#include <conio.h>
//螢幕渲染週期,clock函式
#include <time.h>
//
#include <stdlib.h> 

//重新整理週期,控制遊戲速度
#define Period 100
//地圖寬度
#define _width 25
//地圖高度
#define _height 18
//點 結構
typedef struct point
{
	int x;
	int y;
};

//----------------全域性變數----------------

//地圖陣列
char g_map[_height][_width];
//蛇長度,初始化為兩個
int g_snakeLen = 2;
//蛇:一系列點
struct point g_snake[(_width - 1)*(_height - 1)] = { { _height / 2, _width / 2 }, { 1, 1 } };
//食物座標
struct point g_food;

//----------------函式宣告----------------

//歡迎介面
void Welcome();
//置字元
void SetChars();
//設定食物
void ResetFood();
//處理蛇移動
int JugeSnake(char c);
//空格填充
void Padding(int =0);

//--------------------------------------
int main()
{
	//當前時間,上一次重新整理時間,單位為ms(毫秒)
	long timeNow, timeLast = 0;
	int i, j,//計數變數
		keyLast = 'd',
		keyNow = 'd';
	
	
	//顯示歡迎介面
	Welcome();

	//置隨機數種子
	srand((unsigned)time(NULL));
	//初始化食物位置
	ResetFood();
	
	do
	{
		//***********************渲染開始***********************
		//獲取當前時間
		timeNow = clock();
		//判斷是否滿足重新整理條件
		if (timeNow - timeLast >= Period)
		{
			//記錄本次重新整理時間
			timeLast = clock();
			//清屏
			system("cls");
			//1. 顯示影象
			//----------------初始化地圖介面----------------
			for (i = 0; i<_height; i++)
			{
				for (j = 0; j<_width; j++)
				{
					g_map[i][j] = ' ';
					if (i == 0 || i == _height - 1 || j == 0 || j == _width - 1)
						g_map[i][j] = '*';
				}
			}
			//----------------初始化地圖介面----------------
			//空格填充
			Padding(-10);
			printf("----------當前長度%d,已遊戲時間%ds-----------\n", g_snakeLen, timeNow / 1000);
			int resJuge = JugeSnake(keyLast);
			//此處若用switch,則不能跳出最外層的do-while迴圈
			//為了避免用goto語句,所以用if-else處理juge結果
			if (resJuge == 0)
			{
				printf("遊戲結束!");
				break;
			}
			else if (resJuge == 2)
			{
				printf("恭喜你打穿遊戲了!");
				break;
			}
			SetChars();

			for (i = 0; i<_height; i++)
			{
				//空格填充
				Padding();
				for (j = 0; j<_width; j++)
				{
					printf("%c", g_map[i][j]);
				}
				if (i<_height - 1)
					printf("\n");
			}


		}

		//2. 處理鍵盤事件
		if (kbhit() == 1)
		{
			//
			keyNow = getch();
			if (keyNow == 'd'&&keyLast == 'a')
				keyLast = 'a';
			else if (keyNow == 'a'&&keyLast == 'd')
				keyLast = 'd';
			else if (keyNow == 'w'&&keyLast == 's')
				keyLast = 's';
			else if (keyNow == 's'&&keyLast == 'w')
				keyLast = 'w';
			else
			{
				keyLast = keyNow;
			}
		}

		//***********************渲染結束***********************
	} while (1);

	system("pause");

}
//
//判斷 蛇的移動 並 處理 移動效果
//
int JugeSnake(char c)
{
	int i;
	int x, y;//目標位置
	struct point last;
	last = g_snake[g_snakeLen - 1];//記錄移動前的尾巴位置
	x = g_snake[0].x;
	y = g_snake[0].y;
	switch (c)
	{
	case 'w':case 'W':
		x--;
		break;
	case 's':case 'S':
		x++;
		break;
	case 'a':case 'A':
		y--;
		break;
	case 'd':case 'D':
		y++;
		break;
	}
	//在這裡說明移動成功了
	if (x <= 0 || x >= _height - 1)
		return 0;
	if (y <= 0 || y >= _width - 1)
		return 0;


	for (i = g_snakeLen - 1; i>0; i--)//除頭以外都移動
		g_snake[i] = g_snake[i - 1];
	//動完之後判斷目標位置和移動後的軀體是否重合
	for (i = 1; i<g_snakeLen; i++)
	{
		if (g_snake[i].x == x&&g_snake[i].y == y)
			return 0;//重合就撞了,撞了就GG了
	}
	//沒GG。。。
	g_snake[0].x = x;
	g_snake[0].y = y;

	if (g_snake[0].x == g_food.x &&g_snake[0].y == g_food.y)//臥槽吃到食物了
	{
		g_snakeLen++;
		g_snake[g_snakeLen - 1] = last;
		ResetFood();
	}
	if (g_snakeLen == (_width - 1)*(_height - 1))
		return 2;

	return 1;

}
//
//設定蛇的字和食物字元
//
void SetChars()
{
	int i;
	g_map[g_snake[0].x][g_snake[0].y] = 'M';
	for (i = 1; i<g_snakeLen; i++)
		g_map[g_snake[i].x][g_snake[i].y] = 'm';
	g_map[g_food.x][g_food.y] = 'O';
}
//
//重置食物位置
//
void ResetFood()
{
	do
	{
		g_food.x = rand() % _height;
		g_food.y = rand() % _width;
	} while (g_food.x == 0 || g_food.x == _height - 1 || g_food.y == 0 || g_food.y == _width - 1);
}
//
//歡迎介面
//
void Welcome()
{
	Padding(-10);printf("歡迎來到貪吃世界!\n");
	Padding(-10);printf("上下左右為wsad鍵(請調整輸入法),感受這款經典遊戲帶來的快感吧!\n");
	Padding(-10);printf("                           長沙理工大學 何健偉 QQ:296036136\n");
	system("pause");
}
//
//顯示一定數量的空格
//引數1:相對偏移
void Padding(int shift)
{
	int total=20;
	total+=shift;
	for(int i=0;i<total;i++)
	{
		putchar(' ');
	}
}