C语言小游戏————贪吃蛇.c

 1.主函数框架的搭建

int main (void)
{
	starup();//数据初始化
	while(1)
	{
		show();//打印画面
		updateWithoutInput();//与用户输入无关的更新
		updateWithInput();//与用户输入有关的更新 
	} 
	return 0;
} 
说明:

    a.startup()对全局变量的初始化;

    b.while(1)为死循环:

每次循环进行的内容:

    c show().先清屏在打印一次画面(元素:围墙,蛇头,蛇身,果子,空白);

    d.updateWithoutInput()进行与输入无关的更新(判断是否吃到的果子,食物的刷新);

    e.updateWithInput()进行与输入有关的更新(蛇的移动,方向的改变);

2.全局变量的设定

#define High 20//地图的尺寸 
#define Width 30
#define SerpentNum 200//蛇长的最大值 

//全局变量
int serpent_x[SerpentNum],serpent_y[SerpentNum];//蛇的坐标 
int serpent_long; //蛇的长度 
int canvas[High][Width]={0};//地图对应元素 0空格 1蛇 2食物 3围墙  4蛇头 
int food_x,food_y;//食物的坐标 
int score; //分数 
char input;//方向的控制 
说明:

   a.对于画面上所有的元素均用两个值即可确定位置,所以每个点都(x,y)表示,但是不同于直角坐标系,(x,y)表示x行y列;

   b.起始行由于以数组形式存储所以,从0行0列开始;

   c.地图的打印使用的是二维数组,第一维表示列,第二维表示行,例canvas[i][j]表示i行j列;

3.第一个函数startup():对数据的初始化

void startup()
{
	serpent_x[0]=High/2;serpent_y[0]=Width/3;//蛇的初始位置 
	serpent_x[1]=High/2;serpent_y[1]=Width/3+1;
	serpent_long=2;
	food_x=High/3;food_y=Width/3;//食物
	score=0;
	
	int i,j;
	canvas[serpent_x[0]][serpent_y[0]]=4;
	canvas[serpent_x[1]][serpent_y[1]]=1;
	canvas[food_x][food_y]=2;
	for(i=0;i

说明:

     a.蛇,食物坐标可以随意设置;

     b.对地图中元素的初始化:0空格 1蛇 2食物 3围墙  4蛇头;在定义时已经对二维数组进行了初始化赋0;

     c.对围墙元素的初始化:使用两重循环,将行数为0和Higj-1列数为0和Width-1的点全部赋值为3;

4.第二个函数show():画面打印

void gotoxy(int x,int y)
{
	HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X=x;
	pos.Y=y;
	SetConsoleCursorPosition(handle,pos);
} 
void show()//画面打印 
{
	gotoxy(0,0);
	int i,j;
	for(i=0;i

说明:

    a.对于gotoxy()功能为返回某点重新打印,即相当于清屏函数system("cls"),但是不存在闪屏问题。具体原理牵扯到windows系统的操作,嗯,本人不太懂(๑• . •๑)

使用时需加载#include 头文件

    b.打印效果如下:

C语言小游戏————贪吃蛇.c_第1张图片


5.第三个函数updateWithoutInput()与输入无关的更新

void updateWithoutInput()//与输入无关的更新 
{
    int i;
    if(serpent_x[0]==food_x&&serpent_y[0]==food_y)//如果蛇吃到果子 
    {
        score++;
        
        srand((unsigned)time(NULL));//食物刷新
        food_x=rand()%(High-3)+1;
        food_y=rand()%(Width-3)+1;
        canvas[food_x][food_y]=2;
        
        serpent_long++;//蛇的增长 
    }
    if((serpent_x[0]==0||serpent_y[0]==0||serpent_x[0]==High-1||serpent_y[0]==Width-1))
    {
        printf("死亡游戏结束!\n");//撞墙死亡 
        getch();
        exit(1);
    }
    for(i=1;i
说明:

    a.判断蛇是否吃到果子:即蛇头的坐标等于食物的坐标serpent_x[0]==food_x&&serpent_y[0]==food_y;   

    b.如果蛇吃到果子:食物坐标变0,蛇身加长(只需要加长,在下一个函数中自动实现赋值1)

    b.食物的刷新:使用rand()函数获得随机数,然后对(High-3)取余,使食物的坐标落在围墙内;

     c. srand((unsigned)time(NULL))使用时间函数作随机数的种子;

   e.死亡判定,如果蛇头坐标等于墙的坐标死亡;如果等于蛇身的坐标死亡

   f.死亡后,先提示,然后输入任意键退出,exit(1)退出程序

6.第四个函数updateWithInput() 与输入有关的更新

void updateWithInput()//与输入有关的更新 
{
	int i=1;
	if(kbhit())//输入方向
		input=getch();
	if(input=='w'||input=='s'||input=='a'||input=='d')//蛇的移动
	{	
		canvas[serpent_x[serpent_long-1]][serpent_y[serpent_long-1]]=0;
		for(i=serpent_long-1;i>0;i--)
		{
			serpent_x[i]=serpent_x[i-1];
			serpent_y[i]=serpent_y[i-1];
			canvas[serpent_x[i]][serpent_y[i]]=1;
		}
	}
	
	if(input=='w')//头的移动
		serpent_x[0]--;
	else if(input=='s')
		serpent_x[0]++;
	else if(input=='a')
		serpent_y[0]--;
	else if(input=='d')
		serpent_y[0]++;
		
	canvas[serpent_x[0]][serpent_y[0]]=4;
	
}

说明:

    a.四个函数中,这个函数最麻烦也是最难理解的。

    b.输入方向:if(kbhit())   input=getch(); kbhit()函数作用为检测当前是否有输入的值,有的话返回1,getch()作用:接受键盘输入的字符,并返回;类似于scanf("%c",& input);但是不需要回车键表示输入完成;

    c.蛇身的移动:让蛇从第二个节点开始等于前一个节点,让最后一个节点变为零(这个方法想了很久);

    d.方向的控制:根据键盘输入的方向键(wasd)改变蛇头的坐标,注意,input一定要设为全局变量,在其他控制台小游戏中如果想实现输入动,不输入不动,则设为自动局部变量;

7.完整代码

#include 
#include 
#include 
#include 
#include  

#define High 20//地图的尺寸 
#define Width 30
#define SerpentNum 200//蛇长的最大值 

//全局变量
int serpent_x[SerpentNum],serpent_y[SerpentNum];//蛇的坐标 
int serpent_long; //蛇的长度 
int canvas[High][Width]={0};//地图对应元素 0空格 1蛇 2食物 3围墙  4蛇头 
int food_x,food_y;//食物的坐标 
int score; //分数 
char input;//方向的控制 

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

void startup()
{
	serpent_x[0]=High/2;serpent_y[0]=Width/3;//蛇的初始位置 
	serpent_x[1]=High/2;serpent_y[1]=Width/3+1;
	serpent_long=2;
	food_x=High/3;food_y=Width/3;//食物
	score=0;
	
	int i,j;
	canvas[serpent_x[0]][serpent_y[0]]=4;
	canvas[serpent_x[1]][serpent_y[1]]=1;
	canvas[food_x][food_y]=2;
	for(i=0;i0;i--)
		{
			serpent_x[i]=serpent_x[i-1];
			serpent_y[i]=serpent_y[i-1];
			canvas[serpent_x[i]][serpent_y[i]]=1;
		}
	}
	
	if(input=='w')
		serpent_x[0]--;
	else if(input=='s')
		serpent_x[0]++;
	else if(input=='a')
		serpent_y[0]--;
	else if(input=='d')
		serpent_y[0]++;
		
	canvas[serpent_x[0]][serpent_y[0]]=4;
	
}

int main(void)
{
	startup();
	while(1)
	{
		show();
		updateWithoutInput();
		updateWithInput(); 
	}
	return 0;
}

8.总结:

    优点:

        a.函数功能明确,找错好找

        b.思路较为简单

   缺点:

       a.功能不太完善

       b.蛇的横向和纵向移动速度不同

       c.食物刷新存在bug

   后续优化:

       a.暂停功能

       b.难度的递增

说明:在这里非常感谢知乎上童晶老师的做游戏,学编程的专栏。程序大方向(框架)是由他提供的,我结合他的教程自己制作的贪吃蛇。


第二次更新:

a.可以暂停

b.难度的递增

c.修复食物刷新bug(原因,食物被刷新到蛇的体内)

#include 
#include 
#include 
#include 
#include  

#define High 20//地图的尺寸 
#define Width 30
#define SerpentNum 200//蛇长的最大值 

//全局变量
int serpent_x[SerpentNum],serpent_y[SerpentNum];//蛇的坐标 
int serpent_long; //蛇的长度 
int canvas[High][Width]={0};//地图对应元素 0空格 1蛇 2食物 3围墙  4蛇头 
int food_x,food_y;//食物的坐标 
int score; //分数 
char input;//方向的控制 
int speed; 

 
void gotoxy(int x,int y)
{
	HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X=x;
	pos.Y=y;
	SetConsoleCursorPosition(handle,pos);
} 
void HideCursor()
{
 	CONSOLE_CURSOR_INFO cursor_info = {1, 0}; 
 	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void startup()
{
	serpent_x[0]=High/2;serpent_y[0]=Width/3;//蛇的初始位置 
	serpent_x[1]=High/2;serpent_y[1]=Width/3+1;
	serpent_long=2;
	food_x=High/3;food_y=Width/3;//食物
	score=0;
	speed=5;
	
	int i,j;
	canvas[serpent_x[0]][serpent_y[0]]=4;
	canvas[serpent_x[1]][serpent_y[1]]=1;
	canvas[food_x][food_y]=2;
	for(i=0;i0)
		speed--;
		
	}
	if((serpent_x[0]==0||serpent_y[0]==0||serpent_x[0]==High-1||serpent_y[0]==Width-1))
	{
		printf("死亡游戏结束!\n");//撞墙死亡 
		getch();
		exit(1);
	}
	for(i=1;i0;i--)
			{
				serpent_x[i]=serpent_x[i-1];
				serpent_y[i]=serpent_y[i-1];
				canvas[serpent_x[i]][serpent_y[i]]=1;
			}
		}
	
		if(input=='w')
			serpent_x[0]--;
		else if(input=='s')
			serpent_x[0]++;
		else if(input=='a')
			serpent_y[0]--;
		else if(input=='d')
			serpent_y[0]++;
		
		canvas[serpent_x[0]][serpent_y[0]]=4;
		v=0;
	
	}
		canvas[food_x][food_y]=2;
	
}

int main(void)
{
	startup();
	while(1)
	{
		show();
		updateWithoutInput();
		updateWithInput(); 
	}
	return 0;
}





你可能感兴趣的:(c语言)