写个贪吃蛇自己玩儿~~

一、思路:

二、前期准备:

1、鉴于是在做游戏,则需要不同的页面:

system("cls");

(1)、此代码意为:clean screen 即 “ 清空屏幕 ” ,以便进入下一画面的描述。

2、画面的输出不可能完全按照顺序,即 “ 从左至右,从上到下 ” 输出,因此需要控制台光标移至指定位置:

void gotoxy(int x,int y){
	COORD c;
	c.X = x;
	c.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}

Ps :

① set console cursor position 意为 设置控制台光标位置;

②get std handle 意为 获取标准句柄;

③std 意为 标准的 ,即 “ standard ”

④coord 意为 坐标 ,即 coordinate

(1)、该 gotoxy()函数需要自己声明定义,而 COORD结构 与 SetConsoleCursorPosition() 函数与GetStdHandle() 函数与 STD_OUTPUT_HANDLE 常量不需要自己声明定义,他们位于<windows.h>中;

(2)、该gotoxy()函数实现了对光标的任意移动;GetStdHandle()函数的返回值为 HANDLE类型。

3、鉴于游戏体验,不需要光标显示:

void CursorOut(){
	
	CONSOLE_CURSOR_INFO cinfo;
  	cinfo.bVisible = 0;
  	cinfo.dwSize = 1;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cinfo);
	
}

(1)、CursorOut 函数直接使用则可消去光标;其他函数、常量、结构体均位于<windows.h>中。

三、游戏设计:

1、设置蛇盘(二维数组),并设计蛇头的x,y坐标,并设计蛇的长度,并设计方向指令:

#define mapxsize 40
#define mapysize 20 

int map[mapxsize][mapysize]={0};
int headx,heady,lenth;
char mem_order;

(1)、为方便,上述变量声明为全局变量。

2、初始化蛇盘与方向指令:

void init(){
	for (int i=0;i<mapxsize;i++){
		for (int j=0;j<mapysize;j++){
			map[i][j] = 0;
		}
	}
	map[1][1] = 2;
	map[2][1] = 1;
	headx=2;heady=1;lenth=2;
	map[5][10] = -1;
	mem_order = 'D'; 
}

(1)、首先初始化蛇盘所有数值为0;此处在声明蛇盘时可一键初始化,即 = {0} ,但为什么当时并没有初始化,而在此处通过遍历初始化呢?这是因为游戏结束之后重开下一把仍需初始化,而在声明时初始化达不到此效果;

(2)、蛇身为大于零的自然数,且蛇头为1,随蛇尾方向,自然数增加;食物处赋值自然数为-1 ;

(3)、方向使用字符型 “WASD” 或 “wasd” 表示蛇头的移动;

(4)、此外,需要初始化蛇长度,蛇头坐标,以及蛇头移动方向。

3、键盘输入指令(可跳过):

if(kbhit()) mem_order = getch();
switch (mem_order) {
    case 'W':case 'w': heady -= 1;break;
    case 'A':case 'a': headx -= 1;break;
    case 'S':case 's': heady += 1;break;
    case 'D':case 'd': headx += 1;break;
}

(1)、kyhit() 函数,即 “KeyBoardHit” 若键盘已敲打则返回非0的数值,未敲打返回0,此函数头在<conio.h>中,意为 “ console input output ”;

(2)、getch() 函数的独特之处在于控制台不显示任何字符,但输入字符实际已进入缓冲区;

(3)、使用 switch 命令,快捷地更新蛇头坐标。

4、根据指令操控蛇盘:

int dispose(){
	int ret = 1;
	if (map[headx][heady]>0||headx==0||headx==mapxsize||heady==0||heady==mapysize) { 
		ret = 0;
	} else if (map[headx][heady]==-1){
		for (int i=1;i<mapxsize-1;i++){
			for (int j=1;j<mapysize-1;j++){
				if (map[i][j]>0) map[i][j]++;
				
			}
		}
		map[headx][heady] = 1;
		lenth++;
		freshfood();
	}else{
		for (int i=1;i<mapxsize-1;i++){
			for (int j=1;j<mapysize-1;j++){
				if (map[i][j] == lenth) {
					map[i][j] = 0;
				}
				else if (map[i][j]>=1) {
					map[i][j]+=1;
				}
			}
		}
		map[headx][heady] = 1;
	}
	return ret;
}

(1)、该处理函数为int型,若蛇撞死返回0,未撞死返回1;

(2)、主体部分分为蛇头到达食物处 以及 蛇头未到达食物处两种情况:

①、蛇头到达食物处:

(①)、蛇身各处增加1,食物处赋值为1,即蛇头;

(②)、蛇身长度增加1;

(③)、更新食物位置。

②、蛇头未到达食物处:

(①)、蛇头新位置更新为1,其余位置(处蛇尾外)增加1;

(②)、蛇尾更新为0。

5、输出蛇盘:

void draw(){
	
	for (int i=1;i<mapysize-1;i++){
		gotoxy(1,i);
		for (int j=1;j<mapxsize-1;j++){
			cout << " ";
		}
	}
	
	for (int i=1;i<mapxsize-1;i++){
		for (int j=1;j<mapysize-1;j++){
			gotoxy(i,j);
			if (map[i][j] == 0) cout << " ";
			else if (map[i][j] == 1) cout << "@";
			else cout << "*";	
		}
	}
}

(1)、首先清理蛇盘,即各处输出空格;

(2)、游戏边框在游戏开始时已经输出完毕,此处不赘余输出,也防止边框闪烁;

(3)、头用 “@” ,蛇身和食物使用 “ * ”。

Ps:

①、

system("title 游戏开始");

(①)、该命令可以使得控制台标题改变;

②、

Sleep(1500);

(①)、该命令行可以使得控制台暂停1500毫秒;

(②)、通过该命令可以控制蛇的移速;

(③)、freshfood() 函数可以利用时间随机数设计,不在此赘述。

废话到此位置,感谢各位神犇斧正,全代码奉上:

#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <time.h>

#define mapxsize 40
#define mapysize 20 

int map[mapxsize][mapysize]={0};
int headx,heady,lenth;
char mem_order;
using namespace std;
void gotoxy();
void homepage();
void explaination();
void gamepage();
void draw();
void init();
void freshfood();
void GameBackGround(); 
void CursorOut();
int dispose();

int main(){
	
	
	system("title 贪吃蛇 by高"); 
	CursorOut(); 
	homepage(); 
	
	return 0;
} 

void gotoxy(int x,int y){
	COORD c;
	c.X = x;
	c.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}

void homepage(){
	system("cls");
	gotoxy(20,5);
	for (int i=0;i<=16;i++){
		cout << "_"; 
	}
	gotoxy(20,12);
	for (int i=0;i<=16;i++){
		cout << "_"; 
	}
	for (int i=6;i<=12;i++) {
		gotoxy(19,i);
		cout << "|";
		gotoxy(37,i);
		cout << "|";
	} 
	gotoxy(21,7);
	cout << "1 . 开 始 游 戏 ";
	gotoxy(21,10);
	cout << "2 . 游 戏 说 明 "; 
	gotoxy(20,15);
	cout << "请 选 择 1/2 : [ ]\b\b";
	
	int order;
	cin >> order;
	switch (order) {
		case 1:
			gamepage();
			break;
		case 2:	
			explaination();
			break;
		default:
			gotoxy(41,15);
			cout << "无效输入,请重新输入";
			Sleep(1500);
			homepage();
	}	
}

void explaination(){
	system("cls");
	gotoxy(20,5);
	for (int i=0;i<=16;i++){
		cout << "__"; 
	}
	gotoxy(20,12);
	for (int i=0;i<=16;i++){
		cout << "__"; 
	}
	for (int i=6;i<=12;i++) {
		gotoxy(19,i);
		cout << "|";
		gotoxy(53,i);
		cout << "|";
	} 
	gotoxy(21,7);
	cout << "1 . 蛇头撞到墙壁或蛇身死亡";
	gotoxy(21,10);
	cout << "2 . 请使用WASD键盘操作蛇头的移动"; 
	gotoxy(20,15);
	cout << "敲击键盘任何键可返回主页";
	char temp;
	temp = getch();
	homepage(); 
	} 
void draw(){
	
	for (int i=1;i<mapysize-1;i++){
		gotoxy(1,i);
		for (int j=1;j<mapxsize-1;j++){
			cout << " ";
		}
	}
	
	for (int i=1;i<mapxsize-1;i++){
		for (int j=1;j<mapysize-1;j++){
			gotoxy(i,j);
			if (map[i][j] == 0) cout << " ";
			else if (map[i][j] == 1) cout << "@";
			else cout << "*";	
		}
	}
}
void gamepage(){
	system("title 游戏开始");
	GameBackGround();	
	init();
	draw();
	while (1){
		Sleep(200);
		if(kbhit()) mem_order = getch();
		switch (mem_order) {
				case 'W':case 'w': heady -= 1;break;
				case 'A':case 'a': headx -= 1;break;
				case 'S':case 's': heady += 1;break;
				case 'D':case 'd': headx += 1;break;
			}
		int ret = dispose();
		if (ret) {
			draw();
		} else {
			cout << "游戏结束,按任意键 返回主页";
			char temp;
			temp = getch();
			break;
		}
	}
	homepage();
}
void init(){
	for (int i=0;i<mapxsize;i++){
		for (int j=0;j<mapysize;j++){
			map[i][j] = 0;
		}
	}
	map[1][1] = 2;
	map[2][1] = 1;
	headx=2;heady=1;lenth=2;
	map[5][10] = -1;
	mem_order = 'D'; 
}
int dispose(){
	int ret = 1;
	if (map[headx][heady]>0||headx==0||headx==mapxsize||heady==0||heady==mapysize) { 
		ret = 0;
	} else if (map[headx][heady]==-1){
		for (int i=1;i<mapxsize-1;i++){
			for (int j=1;j<mapysize-1;j++){
				if (map[i][j]>0) map[i][j]++;
				
			}
		}
		map[headx][heady] = 1;
		lenth++;
		freshfood();
	}else{
		for (int i=1;i<mapxsize-1;i++){
			for (int j=1;j<mapysize-1;j++){
				if (map[i][j] == lenth) {
					map[i][j] = 0;
				}
				else if (map[i][j]>=1) {
					map[i][j]+=1;
				}
			}
		}
		map[headx][heady] = 1;
	}
	return ret;
}
void freshfood(){
	srand(time(NULL));
	int x = rand()%(mapxsize-1);
	int y = rand()%(mapysize-1);
	if (x==0) x+=1;
	if (x==mapxsize-1) x-=1;
	if (y==0) y+=1;
	if (y==mapysize-1) y-=1;
	map[x][y] = -1;
}
void GameBackGround(){
	for (int i=0;i<mapxsize;i++){
		for (int j=0;j<mapysize;j++){
			gotoxy(i,j);
			if (i==0 || i==mapxsize-1 || j==0 || j==mapysize-1) cout << "#";
		}
	}
}
void CursorOut(){
	
	CONSOLE_CURSOR_INFO cinfo;
  	cinfo.bVisible = 0;
  	cinfo.dwSize = 1;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cinfo);
	
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值