【C语言游戏开发】初级贪吃蛇

一,静止的小蛇

画面中显示一条静止的小蛇,对于二维数组canvas[High][Width]的对应元素,值为0输出空格,值为-1,输出边框#,值为1输出蛇头@,值大于1的正数输出蛇身*.在startup()函数中初始化蛇头在画布中间位置(canvas[High/2][Width/2]=1;),蛇头向左依次生成4个蛇身(for(i=1;i<=4;i++) canvas[High/2][Width/2-i]=i+1;),元素分别为2,3,4,5.

小蛇

小蛇

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>

#define High 20
#define Width 30		//游戏画面尺寸 

//全局变量 
int canvas[High][Width] = {0};
	//0为空格,-1为边框#,1为蛇头@,大于1的正数为蛇身* 
	
void gotoxy(int x,int y)		//将光标移动到(x,y)位置  
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle,pos);
}

void startup()		//数据的初始化 
{
	int i,j;
	
	//初始化边框 
	for(i=0;i<High;i++)
	{
		canvas[i][0]= -1;
		canvas[i][Width-1] = -1;
	}
	for(j=0;j<Width;j++)
	{
		canvas[0][j] = -1;
		canvas[High-1][j]= -1;
	}
	
	//初始化蛇头的位置 
	canvas[High/2][Width/2] = 1;
	//初始化蛇身,画布中的元素值分别为2,3,4,5等 
	for(i=1;i<=4;i++)
		canvas[High/2][Width/2-i]=i+1;
}

void show()		//显示画面 
{
	gotoxy(0,0);		//光标移动到原点位置,以下重画清屏 
	int i,j;
	for(i=0;i<High;i++)
	{
		for(j=0;j<Width;j++)
		{
			if(canvas[i][j] == 0)
				printf(" ");		//输出空格 
			else if(canvas[i][j] == -1)
				printf("#");		//输出边框#	
			else if(canvas[i][j] == 1)
				printf("@");		//输出蛇头@ 
			else if(canvas[i][j] > 1)
				printf("*");		//输出蛇身* 
		}	
		printf("\n");
	}
}

void updateWithoutInput()		//与用户输入无关的更新 
{
	
}

void updateWithInput()		//与用户输入有关的更新 
{
	
}

int main()
{
	startup();		//数据的初始化 
	while(1)		//游戏循环执行 
	{
		show();		//显示画面 
		updateWithoutInput();		//与用户输入无关的更新 
		updateWithInput();		//与用户输入有关的更新 
	}
	return 0;
}

二,小蛇的移动

1,实现移动

假设小蛇元素为54321,其中1为蛇头,54332为蛇身,最大值为蛇尾.首先将所有大于0的元素加1,得到65432;将最大值6变为0,即除去原来的蛇尾;再根据对应的移动方向将2对应方向的元素由0变成1;如此即实现小蛇的移动
定义变量int move Direction表示小蛇移动的方向,值为1,2,3,4分别表示上下左右方向移动,小蛇的移动再moveSnakeByDirection()函数中实现

2,控制移动

在updateWithInput()函数中按asdw键改变moveDirection的值,然后调用moveSnakeByDirection()实现小蛇向不同方向移动

移动的小蛇
ps:下图以向上移动为例
在这里插入图片描述
代码为

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>

#define High 20
#define Width 30		//游戏画面尺寸 

//全局变量 
int moveDirection;		//小蛇移动的方向,上,下,左,右分别用1,2,3,4表示 
int canvas[High][Width] = {0};		//二维数组存储游戏画布中对应的元素 
	//0为空格,-1为边框#,1为蛇头@,大于1的正数为蛇身* 
	
void gotoxy(int x,int y)		//将光标移动到(x,y)位置  
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle,pos);
}

//移动小蛇 
//第一步扫描数组canvas的所有元素,找到正数元素都加1 
//找到最大元素(即尾巴),把其变为0 
//找到等于2的元素(即蛇头),根据输出的上下左右方向把对应的另一个像素设为1(新蛇头) 
void moveSnakeByDirection()
{
	int i,j;
	for(i=1;i<High-1;i++)
		for(j=1;j<Width-1;j++)
			if(canvas[i][j]>0)
				canvas[i][j]++;
				
	int oldTail_i,oldTail_j,oldHead_i,oldHead_j;
	int max = 0;
	
	for(i=1;i<High-1;i++)
		for(j=1;j<Width-1;j++)
			if(canvas[i][j]>0)
			{
				if(max<canvas[i][j])
				{
					max = canvas[i][j];
					oldTail_i = i;
					oldTail_j = j;
				}
				if(canvas[i][j]==2)
				{
					oldHead_i = i;
					oldHead_j = j;
				}
			}
			
	canvas[oldTail_i][oldTail_j] = 0;
	
	if(moveDirection == 1)		//向上移动 
		canvas[oldHead_i-1][oldHead_j] = 1;
	if(moveDirection == 2)		//向下移动 
		canvas[oldHead_i+1][oldHead_j] = 1;
	if(moveDirection == 3)		//向左移动 
		canvas[oldHead_i][oldHead_j-1] = 1;
	if(moveDirection == 4)		//向右移动 
		canvas[oldHead_i][oldHead_j+1] = 1;	
}

void startup()		//数据的初始化 
{
	int i,j;
	
	//初始化边框 
	for(i=0;i<High;i++)
	{
		canvas[i][0]= -1;
		canvas[i][Width-1] = -1;
	}
	for(j=0;j<Width;j++)
	{
		canvas[0][j] = -1;
		canvas[High-1][j]= -1;
	}
	
	//初始化蛇头的位置 
	canvas[High/2][Width/2] = 1;
	//初始化蛇身,画布中的元素值分别为2,3,4,5等 
	for(i=1;i<=4;i++)
		canvas[High/2][Width/2-i]=i+1;
		
	//初始小蛇向右移动 
	moveDirection = 4;
}

void show()		//显示画面 
{
	gotoxy(0,0);		//光标移动到原点位置,以下重画清屏 
	int i,j;
	for(i=0;i<High;i++)
	{
		for(j=0;j<Width;j++)
		{
			if(canvas[i][j] == 0)
				printf(" ");		//输出空格 
			else if(canvas[i][j] == -1)
				printf("#");		//输出边框#	
			else if(canvas[i][j] == 1)
				printf("@");		//输出蛇头@ 
			else if(canvas[i][j] > 1)
				printf("*");		//输出蛇身* 
		}	
		printf("\n");
	}
	Sleep(100);
}

void updateWithoutInput()		//与用户输入无关的更新 
{
	moveSnakeByDirection();
	
}

void updateWithInput()		//与用户输入有关的更新 
{
	char input;
	if(kbhit())		//判断是否输入 
	{
		input = getch();		//根据用户的不同输入来移动,不必输入回车 
		if(input == 'a')
		{
			moveDirection = 3;
			moveSnakeByDirection();		//位置左移 
		}
		if(input == 'd')
		{
			moveDirection = 4;
			moveSnakeByDirection();		//位置右移 
		}
		if(input == 'w')
		{
			moveDirection = 1;
			moveSnakeByDirection();		//位置上移 
		}
		if(input == 's')
		{
			moveDirection = 2;
			moveSnakeByDirection();		//位置下移 
		}
	}
}

int main()
{
	startup();		//数据的初始化 
	while(1)		//游戏循环执行 
	{
		show();		//显示画面 
		updateWithoutInput();		//与用户输入无关的更新 
		updateWithInput();		//与用户输入有关的更新 
	}
	return 0;
}

三,判断游戏失败

当小蛇和边框发生碰撞时游戏失败

GG

void moveSnakeByDirection()
{
	int i,j;
	for(i=1;i<High-1;i++)
		for(j=1;j<Width-1;j++)
			if(canvas[i][j]>0)
				canvas[i][j]++;
				
	int oldTail_i,oldTail_j,oldHead_i,oldHead_j;
	int max = 0;
	
	for(i=1;i<High-1;i++)
		for(j=1;j<Width-1;j++)
			if(canvas[i][j]>0)
			{
				if(max<canvas[i][j])
				{
					max = canvas[i][j];
					oldTail_i = i;
					oldTail_j = j;
				}
				if(canvas[i][j]==2)
				{
					oldHead_i = i;
					oldHead_j = j;
				}
			}
			
	canvas[oldTail_i][oldTail_j] = 0;
	int newHead_i,newHead_j;
	if(moveDirection == 1)		//向上移动 
	{
		newHead_i = oldHead_i-1;
		newHead_j = oldHead_j;
	}
	if(moveDirection == 2)		//向下移动 
	{
		newHead_i = oldHead_i+1;
		newHead_j = oldHead_j;
	}
	if(moveDirection == 3)		//向左移动 
	{
		newHead_i = oldHead_i;
		newHead_j = oldHead_j-1;
	}
	if(moveDirection == 4)		//向右移动 
	{
		newHead_i = oldHead_i;
		newHead_j = oldHead_j+1;
	}	
		
	//小蛇是否和自身撞或和边框撞,游戏结束 
	if(canvas[newHead_i][newHead_j]>0||canvas[newHead_i][newHead_j] == -1)
	{
		printf("Game Over\n");
		exit(0);
	}
	else
		canvas[newHead_i][newHead_j] = 1;
}

四,增加食物

吃食物增加长度,当二维数组canvas[High][Width]的元素值为-2时输出食物数值’F’.当蛇头碰到食物时长度加1.保持蛇尾,将最大值变为0即可

得分

食物

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>

#define High 20
#define Width 30		//游戏画面尺寸 

//全局变量 
int moveDirection;		//小蛇移动的方向,上,下,左,右分别用1,2,3,4表示 
int food_x,food_y;		//食物的位置 
int score;		//得分数 
int canvas[High][Width] = {0};		//二维数组存储游戏画布中对应的元素 
	//0为空格,-1为边框#,1为蛇头@,大于1的正数为蛇身* 
	
void gotoxy(int x,int y)		//将光标移动到(x,y)位置  
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle,pos);
}

//移动小蛇 
//第一步扫描数组canvas的所有元素,找到正数元素都加1 
//找到最大元素(即尾巴),把其变为0 
//找到等于2的元素(即蛇头),根据输出的上下左右方向把对应的另一个像素设为1(新蛇头) 
void moveSnakeByDirection()
{
	int i,j;
	for(i=1;i<High-1;i++)
		for(j=1;j<Width-1;j++)
			if(canvas[i][j]>0)
				canvas[i][j]++;
				
	int oldTail_i,oldTail_j,oldHead_i,oldHead_j;
	int max = 0;
	
	for(i=1;i<High-1;i++)
		for(j=1;j<Width-1;j++)
			if(canvas[i][j]>0)
			{
				if(max<canvas[i][j])
				{
					max = canvas[i][j];
					oldTail_i = i;
					oldTail_j = j;
				}
				if(canvas[i][j]==2)
				{
					oldHead_i = i;
					oldHead_j = j;
				}
			}
			
	int newHead_i,newHead_j;
	if(moveDirection == 1)		//向上移动 
	{
		newHead_i = oldHead_i-1;
		newHead_j = oldHead_j;
	}
	if(moveDirection == 2)		//向下移动 
	{
		newHead_i = oldHead_i+1;
		newHead_j = oldHead_j;
	}
	if(moveDirection == 3)		//向左移动 
	{
		newHead_i = oldHead_i;
		newHead_j = oldHead_j-1;
	}
	if(moveDirection == 4)		//向右移动 
	{
		newHead_i = oldHead_i;
		newHead_j = oldHead_j+1;
	}
	
	//如果新蛇头吃到食物
	if(canvas[newHead_i][newHead_j] == -2)
	{
		canvas[food_x][food_y] = 0;
		score++;
		//产生一个新食物
		food_x = rand()%(High-5) + 2;
		food_y = rand()%(Width-5) + 2;
		canvas[food_x][food_y] = -2;
		
		//原来旧蛇尾保留,长度加1		 
	}
	else
		canvas[oldTail_i][oldTail_j] = 0; 
		
	//小蛇是否和自身撞或和边框撞,游戏结束 
	if(canvas[newHead_i][newHead_j]>0||canvas[newHead_i][newHead_j] == -1)
	{
		printf("Game Over\n");
		Sleep(2000);
		system("pause");
		exit(0);
	}
	else
		canvas[newHead_i][newHead_j] = 1;
}

void startup()		//数据的初始化 
{
	int i,j;
	
	//初始化边框 
	for(i=0;i<High;i++)
	{
		canvas[i][0]= -1;
		canvas[i][Width-1] = -1;
	}
	for(j=0;j<Width;j++)
	{
		canvas[0][j] = -1;
		canvas[High-1][j]= -1;
	}
	
	//初始化蛇头的位置 
	canvas[High/2][Width/2] = 1;
	//初始化蛇身,画布中的元素值分别为2,3,4,5等 
	for(i=1;i<=4;i++)
		canvas[High/2][Width/2-i]=i+1;
		
	//初始小蛇向右移动 
	moveDirection = 4;
	
	food_x = rand()%(High-5) + 2;
	food_y = rand()%(Width-5) + 2;
	canvas[food_x][food_y] = -2;
}

void show()		//显示画面 
{
	gotoxy(0,0);		//光标移动到原点位置,以下重画清屏 
	int i,j;
	for(i=0;i<High;i++)
	{
		for(j=0;j<Width;j++)
		{
			if(canvas[i][j] == 0)
				printf(" ");		//输出空格 
			else if(canvas[i][j] == -1)
				printf("#");		//输出边框#	
			else if(canvas[i][j] == 1)
				printf("@");		//输出蛇头@ 
			else if(canvas[i][j] > 1)
				printf("*");		//输出蛇身* 
			else if(canvas[i][j] == -2)
				printf("F");		//输出食物 
		}	
		printf("\n");	
	}
	Sleep(100);
	printf("得分数:%d\n",score);
}

void updateWithoutInput()		//与用户输入无关的更新 
{
	moveSnakeByDirection();
	
}

void updateWithInput()		//与用户输入有关的更新 
{
	char input;
	if(kbhit())		//判断是否输入 
	{
		input = getch();		//根据用户的不同输入来移动,不必输入回车 
		if(input == 'a')
		{
			moveDirection = 3;
			moveSnakeByDirection();		//位置左移 
		}
		if(input == 'd')
		{
			moveDirection = 4;
			moveSnakeByDirection();		//位置右移 
		}
		if(input == 'w')
		{
			moveDirection = 1;
			moveSnakeByDirection();		//位置上移 
		}
		if(input == 's')
		{
			moveDirection = 2;
			moveSnakeByDirection();		//位置下移 
		}
	}
}

int main()
{
	startup();		//数据的初始化 
	while(1)		//游戏循环执行 
	{
		show();		//显示画面 
		updateWithoutInput();		//与用户输入无关的更新 
		updateWithInput();		//与用户输入有关的更新 
	}
	return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现移动,吃食变长游戏把子上下左右控制的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。[3] 二、“贪吃游戏的发展编辑 改变此款游戏的特别多。比如在蛋的方面,可能放上带道具的蛋,使吃完后具有保护,穿墙等特种功能,而且难度逐渐变难,游戏制作的精细度和画面的质量也随着版本的提高而不断提高,且有单人及团队联机对战版本陆续推出。 参考资料游戏把子上下左右控制的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。[3] 二、“贪吃游戏的发展编辑 改变此款游戏的特别多。比如在蛋的方面,可能放上带道具的蛋,使吃完后具有保护,穿墙等特种功能,而且难度逐渐变难,游戏制作的精细度和画面的质量也随着版本的提高而不断提高,且有单人及团队联机对战版本陆续推出。 游戏把子上下左右控制的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。[3] 二、“贪吃游戏的发展编辑 改变此款游戏的特别多。比如在蛋的方面,可能放上带道具的蛋,使吃完后具有保护,穿墙等特种功能,而且难度逐渐变难,游戏制作的精细度和画面的质量也随着版本的提高而不断提高,且有单人及团队联机对战版本陆续推出。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值