C语言贪吃蛇(光标版)(前辈的)

//前辈的文章好像失联了,我不能转载他的文章,所以写的原创,请见谅。
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <stdlib.h>//哪里用到了?
#include <conio.h>//控制台

#define INFO_X 100 //提示信息区横坐标
#define WIDE 50 //游戏界面宽度
#define HIGH 36 //游戏界面高度
#define LEVELUP 5 //升级所需的食物个数
/* 蛇身结构 /
struct Snakes
{
int X[100]; //蛇身的横坐标
int Y[100]; //蛇身的纵坐标
int length; //蛇的长度
int speed; //蛇移动速度
int count; //蛇吃到食物个数
};
/
食物结构 */
struct Food
{
int X; //食物横坐标
int Y; //食物纵坐标
};

/* 定义全局变量 */
unsigned char key;
int i,j,k,end[2]; //i,j,k为循环变量,end数组用来做蛇尾坐标的中间变量
struct Snakes s,*snake=&s; //定义蛇的结构体指针并指向蛇的结构体
struct Food f,*food=&f; //定义食物结构体指针并指向食物结构体

/* 设置控制台标题和大小 /
void SetTitle()
{
//设置控制台窗口大小
system(“mode con cols=150 lines=40”);
//设置控制台标题
SetConsoleTitle(“怎么用”);
}
/
设置光标位置 /
void SetPos(int x,int y)
{
HANDLE winhandle;
COORD pos={x,y};//这里直接是 给 pos的两个成员赋值,x,y. COORD是结构体。
winhandle=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(winhandle,pos);
}
/
设置控制台颜色 /
void Setcolor(int forcolor,int bakcolor)
{
/

0=黑色, 8=灰色,
1=蓝色, 9=淡蓝色,
2=绿色, A=淡绿色,
3=湖蓝色, B=淡浅绿色,
4=红色, C=淡红色,
5=紫色, D=淡紫色,
6=黄色, E=淡黄色,
7=白色, F=亮白色
/
HANDLE winhandle;
winhandle=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(winhandle,forcolor+bakcolor
0x10);
}
/* 清楚单行显示 /
void Cleanlin(int x,int y)
{
SetPos(x,y);
for(i=0;i<50;i++)//宽度是50。
{
printf(" ");
}
}
/
设置游戏界面 /
void Table()
{
for (i=0;i<HIGH;i++)//HIGH是游戏界面高度36.,i只宽度j只高度。
{
if(i0||iHIGH-1)
{
for (k=0;k<WIDE
2-1;k+=2)
{
SetPos(k,i);
printf(“■”);
}
continue;
}
else
{
for(j=0;j<WIDE2-1;j+=2)
{
if(j0||jWIDE
2-2)
{
SetPos(j,i);
printf(“■”);
}
}
}
}
}
/* 显示提示和菜单 /
void ShowMenu()
{
SetPos(INFO_X+17,1); //固定侧栏输出
Setcolor(9,0);
printf(“欢迎来到贪吃蛇!”);
SetPos(INFO_X+17,5);
printf(“Esc 退出游戏”);
SetPos(INFO_X+17,7);
printf(“空格 暂停游戏”);
SetPos(INFO_X+17,9);
printf(“↑↓←→ 控制蛇头方向”);
SetPos(INFO_X+17,11);
printf(“长按方向键加速”);
SetPos(INFO_X+17,15);
printf(“游戏得分:%d”,snake->count
100);
SetPos(INFO_X+17,17);
printf(“当前级别:%d”,snake->count/LEVELUP+1);
SetPos(INFO_X+17,19);
printf(“当前速度:%d”,snake->speed);
SetPos(INFO_X+17,21);
printf(“吃到食物:%d”,snake->count);
SetPos(INFO_X+17,23);
printf(“食物坐标:%-2d,%-2d”,food->X,food->Y);
}
/* 初始化蛇身 /
void init_snake()
{
snake->X[0]=WIDE; //初始化蛇的横坐标——尾巴
snake->Y[0]=HIGH/2; //初始化蛇的竖坐标——尾巴
end[0]=snake->X[0]; //记住蛇尾横坐标
end[1]=snake->Y[0]; //记住蛇尾纵坐标
snake->speed=300; //初始化蛇的速度为300ms
snake->length=3; //初始化蛇的长度为3节
snake->count=0; //初始化蛇吃的个数为0
for(i=1;ilength;i++)
{
/
依次得到蛇身、蛇头的坐标 /
snake->X[i]=snake->X[i-1]+2; //+2是因为蛇身初始长为3
snake->Y[i]=snake->Y[i-1]; //蛇初始是横着的,横着的y坐标相等,竖着的x左边相等。
}
}
/
移动蛇身 /
void move_snake() //刷新蛇身信息
{
SetPos(snake->X[0],snake->Y[0]);
printf(" "); //清除蛇尾,外面再重新输出新蛇身
for(i=1;ilength;i++) //从1开始
{/
后一节的坐标依次取代前一节的坐标 /
snake->X[i-1]=snake->X[i];
snake->Y[i-1]=snake->Y[i];
}
}
/
显示蛇身 /
void print_snake()
{
for(i=0;ilength;i++)
{
SetPos(snake->X[i],snake->Y[i]);
if(i0)
{
printf(“○”); //打印蛇尾
}
else if(i
snake->length-1)
{
printf(“¤”); //打印蛇头
}
else
{
printf(“⊙”); //打印蛇身
}
}
}
/
产生食物 */
void get_food()
{
srand((unsigned)time(NULL));
while(1)
{
food->X=((rand()%(WIDE-3))+1)*2;//限制food横坐标
food->Y=(rand()%(HIGH-2))+1;//为什要这样写,rand()后面也没有 空格

    for(i=0;i<snake->length;i++)
    {
        if(food->X==snake->X[i]&&food->Y==snake->Y[i])
        {
            break;
        }
    }
    if(i==snake->length)  //保证食物不在蛇身上
    {
        SetPos(food->X,food->Y);
        Setcolor(10,0);
        printf("⊙");
        Setcolor(9,0);
        break;
    }
}

}
/* 吃食物 /
void eat_food()
{
if(snake->X[snake->length-1]==food->X&&snake->Y[snake->length-1]==food->Y)
{/如果蛇头坐标和食物坐标相同,吃掉食物,身长加1。/
snake->length++;
for(i=snake->length-1;i>0;i–)
{/
蛇后节坐标依次赋值给蛇前一节的坐标,依次得到蛇身及蛇头的坐标 /
snake->X[i]=snake->X[i-1];
snake->Y[i]=snake->Y[i-1];
}
get_food();
snake->count++;
if( snake->count%LEVELUP==0 )
{/
当蛇吃LEVELUP个食物时,速度加快20毫秒并且升一级 /
snake->speed-=20;
}
}
}
/
穿墙 /
void through_wall()
{ /
当蛇碰到移动方向的边界时,蛇身穿过边界从相对的另一边出现。/
if(key==72 && snake->Y[snake->length-1]0)//上键
{
snake->Y[snake->length-1]=HIGH-2;
}
if(
key
77&&snake->X[snake->length-1]==WIDE
2-2)//右键//=98
{
snake->X[snake->length-1]=2;
}
if(key==80&&snake->Y[snake->length-1]HIGH-1)//下键
{
snake->Y[snake->length-1]=1;
}
if(key
75&&snake->X[snake->length-1]==0)//左键
{
snake->X[snake->length-1]=(WIDE-2)2;//=96
}
}
void GameOver()
{
system(“cls”);
SetPos(WIDE,HIGH/2);
printf(“游戏结束!”);
ShowMenu();
SetPos(0,HIGH);
exit(0);
getch();
}
/
判断蛇的死亡 /
void die()
{
for(i=0;ilength-1;i++) //i遍历的就是蛇身,从0开始则包括了蛇尾
{ /
当蛇头碰到蛇身,蛇死亡。 /
if(snake->X[snake->length-1]==snake->X[i]&&snake->Y[snake->length-1]==snake->Y[i])//
{
GameOver();
}
}
}
/
得到用户输入 /
void GetKey()
{
switch(key)
{
case 27://Esc键–结束游戏
{
GameOver();
break;
}
case 32://空格键–暂停游戏
{
SetPos(INFO_X+13,HIGH-5);//光标位置
Setcolor(5,0);//设置颜色
// Sleep(500);
Sleep(0);
printf(“游戏暂停,按方向键继续!”);
Setcolor(9,0);
SetPos(0,HIGH);
break;
}
case 72://上键
{
move_snake();
snake->Y[snake->length-1]-=1;
break;
}
case 77://右键
{
move_snake();
snake->X[snake->length-1]+=2;
break;
}
case 80://下键
{
move_snake();
snake->Y[snake->length-1]+=1;
break;
}
case 75://左键
{
move_snake();
snake->X[snake->length-1]-=2;
break;
}
}
}
/
开始游戏 */
void GameStar()
{

key=77;                 //初始化蛇向右移动,为什么就初始化了?因为 77对应右箭头。 ,进入while,就一直判断为按了→↑ 
SetTitle();             //设置控制台标题和大小
Setcolor(4,0);
Table();                //初始化游戏界面
init_snake();           //初始化蛇身
get_food();             //初始化第一个食物
while(1)   //循环刷新
{
    Cleanlin(INFO_X,HIGH-5);
    ShowMenu();
    end[0]=snake->X[0];//把尾巴记下来。 
    end[1]=snake->Y[0];
    j=0;
    if(kbhit())
    {/* 判断是否按下键盘,如果按下,ch接收键盘输入 */ 
        key=getch();
        if(kbhit())    //库里的
        {/* 如果长按键盘,则加速 */ 
            Sleep(20);
            j=1;
        }
    }
    GetKey();//Key在上面的if语句中得到。 
    through_wall();
    eat_food();
    print_snake();
    die();//死亡 
    if(j==0)
    {
        Sleep(snake->speed);        //延迟时间
    }
    else
    {
        Sleep(10);
    }
    
}

}
/* 游戏结束 */

int main()
{
GameStar();
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值