c语言 最简版 贪吃蛇 小游戏

全程只需要四个主要的函数:
Map();Gameover();Move(); Creatfood();
和两个用于隐藏光标和移动光标的函数:
gotoxy();hide_cursor();

1,Map() ----- 用于构造地图
2,Move() ----- 用于移动Snake
3,Creatfood() ----- 用于创造食物
4,Gameover() ----- 用于结束游戏

基本思路:
首先利用数组作为结构体成员,用于存储蛇的坐标信息

struct {
	int len;//长度
	//记录蛇身每个方块的坐标
	int x[SNAKESIZE];
	int y[SNAKESIZE];
}snake;

1,蛇的移动:“加头去尾”,其中“消除尾部”用以下代码实现:
//在蛇的尾部处打印空格
//主要是从蛇尾坐标出发,不段记录前一个位置的坐标,从而实现不断移动

if(snake.flag==1)//还没吃到食物,把尾巴擦掉
	{
	    gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);
 	    printf("  ");
	}
for(int i=snake.len-1;i>0;i--)//移动蛇身 
	{ 
		snake.x[i]=snake.x[i-1];
		snake.y[i]=snake.y[i-1];
	}	

而“增加头部”用以下代码实现:
//头坐标在之前已经没用了,改变头坐标

switch(key)
	{
		case 'w':snake.y[0]--;break;
		case 'a':snake.x[0]-= 2;break;
		case 'd':snake.x[0]+= 2;break;
		case 's':snake.y[0]++;break;
	}
	gotoxy(snake.x[0],snake.y[0]);
	printf("■");

2,蛇吃食物:“加头不去尾”,只要蛇长度加一,把flag设置为0,不实现以下代码部分即可

if(snake.flag==1)//还没吃到食物,把尾巴擦掉
	{
	    gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);
 	    printf("  ");
	}

游戏规则:
通过按’w’,‘a’,‘s’,'d’键控制Snake的移动,连续按两下相同方向的键加速

注:
构造蛇对象的图形为方块,占两个水平格,一个竖直格;
食物对象的图形为圆性,占据位置上同;

温馨提醒:_kbhit()可以检测是否按键,若按键则返回真,并通过_getch()接收按键信息,若没按键则返回假,不执行该部分内容

if (_kbhit())
	{
		fflush(stdin);	
		key = _getch();
		snake.breaker = 0;//打开加速开关 
	}
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#define width 60
#define hight 25
#define SNAKESIZE 200//蛇身的最长长度

char key='w';//初始化蛇的运动方向,向上

//'w'为上 
//'s'为下
//'a'为左
//'d'为右

struct {
	
	int len;
	//用来记录蛇身每个方块的坐标
	int x[SNAKESIZE];
	int y[SNAKESIZE];
	int speed; // 速度 
	int breaker; //加速开关 
	int flag;//用来标识是否生成食物,1表示蛇还没吃到食物,0表示吃到食物
}snake;

struct
{
	int x;int y;
}food;
//该部分新手无需深入
void gotoxy(int x,int y)//设置CMD窗口光标位置
{
	COORD coord;
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

void hide_cursor() //隐藏CMD窗口光标
{
    CONSOLE_CURSOR_INFO cci;
    cci.bVisible = FALSE;
    cci.dwSize = sizeof(cci);
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorInfo(handle, &cci);
}


void Map()
{
	//打印图框
	for (int y = 0; y < hight; y++)
	{
		for (int x = 0; x < width; x+=2)
		{
			if (x == 0 || y == 0 || y == hight - 1 || x == width - 2)
			{
				gotoxy(x, y);
				printf("■");
			}
		}
	}
	//打印蛇头
	snake.len=3;
	snake.x[0]=width/2;
	snake.y[0]=hight/2;
	gotoxy(snake.x[0],snake.y[0]);
	printf("■");
	//打印蛇身
	for(int i=1;i<snake.len;i++)
	{
		snake.x[i]=snake.x[i-1];
		snake.y[i]=snake.y[i-1]+1;
		gotoxy(snake.x[i],snake.y[i]);
		printf("■");
	}
	//初始速度 
	snake.speed = 10; 
	//初始加速开关
	snake.breaker = 0; 
	//初始标识
	snake.flag = 1; 
	//初始食物位置
	food.x=20;
	food.y=20;
	gotoxy(food.x,food.y);
	printf("●");
}


void Move()//按键处理函数
{
	int history_speed;
	char history_key=key;
	if (_kbhit())
	{
		fflush(stdin);	
		key = _getch();
		snake.breaker = 0;//打开加速开关 
	}
	if(snake.flag==1)//还没吃到食物,把尾巴擦掉
	{
	    gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);
 	    printf("  ");
	}
	for(int i=snake.len-1;i>0;i--)//移动蛇身 
	{ 
		snake.x[i]=snake.x[i-1];
		snake.y[i]=snake.y[i-1];
	}

	if(history_key=='w'&&key=='s'){
		key='w'; 
		snake.speed-=10; //减速 
	}	
	else if(history_key=='s'&&key=='w'){
		key='s';
		snake.speed-=10; //减速 
	}
	else if(history_key=='a'&&key=='d'){
		key='a';
		snake.speed-=10;//减速 
	}	 
	else if(history_key=='d'&&key=='a'){
		key='d';
		snake.speed-=10;//减速 
	}	 
	else if(history_key=='w'&&key=='w'||history_key=='s'&&key=='s'||history_key=='a'&&key=='a'||history_key=='d'&&key=='d'){
		if(snake.breaker==0){
		   snake.speed+=10;//加速 
		   snake.breaker = 1;//关闭加速开关 
		}
	}  
	
    if(snake.speed >= 270)//速度最大值为270 
    	snake.speed = 270;
    	
	switch(key)
	{
		case 'w':snake.y[0]--;break;
		case 'a':snake.x[0]-= 2;break;
		case 'd':snake.x[0]+= 2;break;
		case 's':snake.y[0]++;break;
	}
	gotoxy(snake.x[0],snake.y[0]);
	printf("■");
	snake.flag=1;	
}
void Creatfood()
{
	if(snake.x[0] == food.x && snake.y[0] == food.y)//只有蛇吃到食物,才能生成新食物
	{
		
		snake.flag=0;	
		snake.len++;
		if(snake.speed<=100)snake.speed+=10;
			srand((unsigned int) time(NULL));
			food.x=(rand()%(width/2-3)+1)*2;//限定食物的x范围不超出围墙,保证food.x为偶数
			food.y=rand()%(hight-2)+1;
			for(int i = 0; i<snake.len; i++)//如果产生的食物与蛇身重合则重新生成食物 
			{
				if(food.x==snake.x[i]&&food.y==snake.y[i]){
				    food.x=rand()%(width-6)+2;
			        food.y=rand()%(hight-2)+1;
		            i = 0;//重新查找  
				} 	
			}
			gotoxy(food.x,food.y);	printf("●");
	}
}

bool Gameover()
{
	//碰到围墙,结束 
	if(snake.x[0]==0){
	         snake.x[0] = width - 4; 
	}else if(snake.x[0]==width-2){
		     snake.x[0] = 2;
	} 
	
	if(snake.y[0]==0){
		snake.y[0] = hight-2;
	}else if(snake.y[0]==hight-1 ){
		snake.y[0] = 1; 
	}

	//蛇身达到最长,结束 
	if(snake.len==SNAKESIZE) return false;
	//头碰到蛇身,结束 
	for(int i=1;i<snake.len;i++)
	{ 
		if(snake.x[0]==snake.x[i]&&snake.y[0]==snake.y[i])
			return false;
	}
	return true;
}
int main()
{	
	 system("mode con cols=60 lines=27");
	 Map();
	 hide_cursor(); 
	 while(Gameover())
	 {
		 Move();
		 Creatfood();
		 Sleep(350-snake.speed);//蛇的移动速度 
	 }
	return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值