c语言实现贪吃蛇

话不多说,先看效果

在这里插入图片描述
实现的基本思路是把蛇用链表表示出来,每隔一段时间用头插法在这个链表中添加头,然后再把最结尾的给删掉并用空格把他给填充掉。这样不会发生像其他人的那种疯狂清空屏幕再打印导致的闪花眼的现象了。至于食物随机数就行了吧,下面开始:
首先

#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<time.h>
typedef struct sheshen
{
    int x;
    int y;
    struct sheshen*next;
} snake;
snake *head=NULL,*p1=NULL,*pd=NULL,*wei=NULL;
int fenshu=0,fangxiang=4,lenth=5,sleeptime=80,suijix=0,suijiy=0,begin=0,zhuangtai=0,panduan=0;//panduan为0无操作为1死亡为2加分
char caidankongzhi=0,jiemiankongzhi=0,name1[50]= {0};

然后
这个函数的作用是把光标移动到相应的地方

void zuobiao(int x,int y)
{
    COORD xy;
    xy.X=x;
    xy.Y=y;
    HANDLE guangbiao;
    guangbiao=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(guangbiao,xy);
}

下面的代码时用来把光标隐藏的
不然光标一直显示影响观感

void yincangguangbiao()
{
    CONSOLE_CURSOR_INFO guangbiao;
    guangbiao.bVisible = FALSE;
    guangbiao.dwSize = sizeof(guangbiao);
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorInfo(handle, &guangbiao);
}

为了使代码更短,我在这里写了一些图形,之后可以随便调用不用再辛苦的写了
传的参数
第一个函数x,y为坐标z是宽度
第二个函数x,y为坐标,widtn为宽度height为高度
以后使用直接传参就行了

void sucai001(int x,int y,int z)
{
    zuobiao(x,y);
    for(int i=1; i<=z; i++)
        printf("■");
    zuobiao(x,y+2);
    for(int i=1; i<=z; i++)
        printf("■");
    zuobiao(x,y+1);
    printf("■");
    zuobiao(x+2*z-2,y+1);
    printf("■\n");
}
void sucai002(int x,int y,int width,int height)
{
    for(int i=0; i<=height; i+=height)
    {
        for(int j=1; j<=width; j++)
        {
            zuobiao(x+j,y+i);
            printf("*");
        }
    }
    for(int i=0; i<=width; i+=width)
    {
        for(int j=1; j<=height; j++)
        {
            zuobiao(x+i,y+j);
            printf("*");
        }
    }
}

为了让场景切换不是那么的突兀
我无聊的写了个过渡动画(这玩意叫动画?

void donghua001()
{
    for(int k=1; k<=2; k++)
    {
        for(int i=0; i<=119; i++)
        {
            Sleep(0.8);
            for(int j=0; j<=27; j++)
            {
                zuobiao(i,j);
                if(k==1)
                    printf("0");
                else
                    printf(" ");
            }
        }
    }
}

然后是随机数

int suijishu(int x)
{
    if(x==1)
    {
        srand((unsigned)time(NULL));
        suijix=rand()%52+4;
        if(suijix%2==1)
            suijix+=1;
        suijiy=rand()%19+4;
    }
    if(x==2)
    {
        suijix=rand()%52+4;
        if(suijix%2==1)
            suijix+=1;
        suijiy=(rand())%19+4;
    }
}

撞击判定

int hit(int x,int y)
{
    if(head->x==x&&head->y==y)
    {
        return 1;
    }
    return 0;
}

两种死亡方式(撞到自己/撞墙)

void death1()
{
    p1=head->next;
    while(1)
    {
        panduan=hit(p1->x,p1->y);
        if(panduan==1)
            break;
        if(p1->next==NULL)
            break;
        p1=p1->next;
    }
}
int death2()
{
    for(int i=0; i<=60; i+=2)
    {
        panduan=hit(i,3);
        if(panduan==1)
            return 1;
    }
    for(int i=0; i<=20; i++)
    {
        panduan=hit(60,3+i);
        if(panduan==1)
            return 1;
    }
    for(int i=60; i>=0; i-=2)
    {
        panduan=hit(i,23);
        if(panduan==1)
            return 1;
    }
    for(int i=20; i>=0; i--)
    {
        panduan=hit(0,3+i);
        if(panduan==1)
            return 1;
    }
}

得分判定

int defen()
{
    zuobiao(suijix,suijiy);
    printf("■");
    int i=0;
    i=hit(suijix,suijiy);
    if(i==1)
    {
        if(caidankongzhi=='2')//这里我有两个模式第二个模式得分后会加速
        {
            if(sleeptime>=100)
            {
                sleeptime-=50;
            }
            else if(sleeptime>=60)
            {
                sleeptime-=5;
            }
        }
        fenshu+=1;
        zuobiao(72,20);
        printf("分数:%d",fenshu);
        panduan=2;
        suijishu(2);
        return 2;
    }
}

提示

void tishi()
{
    sucai002(70,3,35,20);
    zuobiao(72,4);
    printf("操作提示:");
    zuobiao(72,5);
    printf("按上键向上转头");
    zuobiao(72,6);
    printf("按下键向下转头");
    zuobiao(72,7);
    printf("按左键向左转头");
    zuobiao(72,8);
    printf("按右键向右转头");
}

打印地图,别问我为什么要加sleep(),,为了好看,,就像老式游戏机一样

void map()
{
    tishi();
    for(int i=0; i<=60; i+=2)
    {
        if(begin==0)
            Sleep(20);
        zuobiao(i,3);
        printf("■");
    }
    for(int i=0; i<=20; i++)
    {
        if(begin==0)
            Sleep(20);
        zuobiao(60,3+i);
        printf("■");
    }
    for(int i=60; i>=0; i-=2)
    {
        if(begin==0)
            Sleep(20);
        zuobiao(i,23);
        printf("■");
    }
    for(int i=20; i>=0; i--)
    {
        if(begin==0)
            Sleep(20);
        zuobiao(0,3+i);
        printf("■");
    }
    begin=0;
}

蛇身

void snakebody()
{
    wei=(snake*)malloc(sizeof(snake));
    wei->x=16;
    wei->y=13;
    wei->next=NULL;
    p1=wei;
    for(int i=1; i<=lenth; i++)
    {
        head=(snake*)malloc(sizeof(snake));
        head->x=wei->x+2*i;
        head->y=wei->y;
        head->next=p1;
        p1=head;
    }
    p1=head;
    while(1)
    {
        zuobiao(p1->x,p1->y);
        printf("■");
        if(p1->next==NULL)
            break;
        p1=p1->next;
    }
}

控制

void kongzhi()
{
    if(GetAsyncKeyState(VK_UP)&&fangxiang!=3)
    {
        fangxiang=1;
    }
    else if(GetAsyncKeyState(VK_DOWN)&&fangxiang!=1)
    {
        fangxiang=3;
    }
    else if(GetAsyncKeyState(VK_LEFT)&&fangxiang!=4)
    {
        fangxiang=2;
    }
    else if(GetAsyncKeyState(VK_RIGHT)&&fangxiang!=2)
    {
        fangxiang=4;
    }
}

移动,算是代码的核心地方了,你别看他长,其实里面四部分几乎一摸一样,写的时候就ctrl+c,ctrl+v

void yidong()
{
    if(fangxiang==1)//上
    {
        p1=head;
        head=(snake*)malloc(sizeof(snake));
        head->x=p1->x;
        head->y=p1->y-1;
        head->next=p1;
        zuobiao(head->x,head->y);
        printf("■");
        p1=head;
        if(panduan==2)
        {
            while(1)
            {
                if(p1->next==NULL)
                {
                    zuobiao(p1->x,p1->y);
                    printf("■");
                    zuobiao(head->x,head->y-5);
                    break;
                }
                zuobiao(p1->x,p1->y);
                printf("■");
                pd=p1;
                p1=p1->next;
            }
        }
        else
        {
            while(1)
            {
                if(p1->next==NULL)
                {
                    zuobiao(p1->x,p1->y);
                    printf("  ");
                    zuobiao(head->x,head->y-5);
                    free(p1);
                    pd->next=NULL;
                    break;
                }
                zuobiao(p1->x,p1->y);
                printf("■");
                pd=p1;
                p1=p1->next;
            }
        }
    }
    if(fangxiang==2)//左
    {
        p1=head;
        head=(snake*)malloc(sizeof(snake));
        head->x=p1->x-2;
        head->y=p1->y;
        head->next=p1;
        zuobiao(head->x,head->y);
        printf("■");
        p1=head;
        if(panduan==2)
        {
            while(1)
            {
                if(p1->next==NULL)
                {
                    zuobiao(p1->x,p1->y);
                    printf("■");
                    zuobiao(head->x,head->y-5);
                    break;
                }
                zuobiao(p1->x,p1->y);
                printf("■");
                pd=p1;
                p1=p1->next;
            }
        }
        else
        {
            while(1)
            {
                if(p1->next==NULL)
                {
                    zuobiao(p1->x,p1->y);
                    printf("  ");
                    zuobiao(head->x,head->y-5);
                    free(p1);
                    pd->next=NULL;
                    break;
                }
                zuobiao(p1->x,p1->y);
                printf("■");
                pd=p1;
                p1=p1->next;
            }
        }
    }
    if(fangxiang==3)//下
    {
        p1=head;
        head=(snake*)malloc(sizeof(snake));
        head->x=p1->x;
        head->y=p1->y+1;
        head->next=p1;
        zuobiao(head->x,head->y);
        printf("■");
        p1=head;
        if(panduan==2)
        {
            while(1)
            {
                if(p1->next==NULL)
                {
                    zuobiao(p1->x,p1->y);
                    printf("■");
                    zuobiao(head->x,head->y-5);
                    break;
                }
                zuobiao(p1->x,p1->y);
                printf("■");
                pd=p1;
                p1=p1->next;
            }
        }
        else
        {
            while(1)
            {
                if(p1->next==NULL)
                {
                    zuobiao(p1->x,p1->y);
                    printf("  ");
                    zuobiao(head->x,head->y-5);
                    free(p1);
                    pd->next=NULL;
                    break;
                }
                zuobiao(p1->x,p1->y);
                printf("■");
                pd=p1;
                p1=p1->next;
            }
        }
    }
    if(fangxiang==4)//右
    {
        p1=head;
        head=(snake*)malloc(sizeof(snake));
        head->x=p1->x+2;
        head->y=p1->y;
        head->next=p1;
        zuobiao(head->x,head->y);
        printf("■");
        p1=head;
        if(panduan==2)
        {
            while(1)
            {
                if(p1->next==NULL)
                {
                    zuobiao(p1->x,p1->y);
                    printf("■");
                    zuobiao(head->x,head->y-5);
                    break;
                }
                zuobiao(p1->x,p1->y);
                printf("■");
                pd=p1;
                p1=p1->next;
            }
        }
        else
        {
            while(1)
            {
                if(p1->next==NULL)
                {
                    zuobiao(p1->x,p1->y);
                    printf("  ");
                    zuobiao(head->x,head->y-5);
                    free(p1);
                    pd->next=NULL;
                    break;
                }
                zuobiao(p1->x,p1->y);
                printf("■");
                pd=p1;
                p1=p1->next;
            }
        }
    }
    death1();
    if(panduan!=1)
    {
        death2();
        if(panduan!=1)
        {
            defen();
        }
    }
}

到这里代码其实已经算是结束了,后面都是锦上添花的

//登录
int denglu()
{
    int TorF=0,changdu;
    char name[50]= {0},password[50]= {0},fenge[3],password1[50];
    system("Cls");
    sucai001(30,10,28);
    zuobiao(32,11);
    printf("请输入账号:");
    scanf("%s",&name);
    changdu=strlen(name);
    name[changdu]='\n';
    sucai001(30,14,28);
    zuobiao(32,15);
    printf("请输入密码:");
    scanf("%s",&password);
    changdu=strlen(password);
    password[changdu]='\n';
    FILE*denglu1=fopen("zhanghao.txt","r");
    while(1)
    {
        TorF=0;
        if(fgets(fenge,50,denglu1)==NULL)//判断是否结束
        {
            fclose(denglu1);
            return 0;
        }
        fgets(name1,50,denglu1);
        fgets(password1,50,denglu1);
        if(strcmp(name1,name)==0)
        {
            TorF+=1;
        }
        if(strcmp(password1,password)==0)
        {
            TorF+=1;
        }
        if(TorF==2)
        {
            fclose(denglu1);
            return 1;
        }
    }
}

有没有感觉很熟悉,,没错这是从我上个程序里cp出来的,略加修改

继续:
菜单以及界面

void caidan()
{
    zuobiao(57,4);
    printf("贪吃蛇");
    sucai001(50,6,10);
    zuobiao(52,7);
    if(zhuangtai==0)
    {
        printf("    0登入游戏");
    }
    else
    {
        printf("    0登出游戏");
        sucai001(40,0,20);
        zuobiao(42,1);
        printf("        欢迎玩家%s",name1);
    }
    sucai001(50,10,10);
    zuobiao(52,11);
    printf("    1经典模式");
    sucai001(50,14,10);
    zuobiao(52,15);
    printf("    2急速模式");
    sucai001(54,18,6);
    zuobiao(58,19);
    printf("3关于");
    sucai001(50,22,10);
    zuobiao(53,23);
    printf("我的选择:");
    while(1)
    {
        scanf("%c",&caidankongzhi);
        if(caidankongzhi>'4'||caidankongzhi<'0')
        {
            zuobiao(62,23);
            printf("      ");
            zuobiao(62,23);
        }
        else
        {
            break;
        }
    }
}

int jiemian001()
{
    sucai001(44,10,14);
    zuobiao(46,11);
    printf("  游戏结束,返回主菜单 ");
    sucai001(44,13,14);
    zuobiao(46,14);
    printf("  ");
    system("pause");
}
int jiemian002()
{
    while(1)
    {
        zuobiao(52,7);
        printf("    请选择");
        sucai001(50,10,10);
        zuobiao(52,11);
        printf("     1登录");
        sucai001(50,14,10);
        zuobiao(52,15);
        printf("     2注册");
        sucai001(50,22,10);
        zuobiao(53,23);
        fflush(stdin); //清除键盘缓冲区
        printf("我的选择:");
        scanf("%c",&jiemiankongzhi);
        if(jiemiankongzhi<'3'||jiemiankongzhi>'0')
        {
            break;
        }
        zuobiao(62,21);
        printf("      ");
        zuobiao(62,21);
    }
    return 1;
}
int jiemian003(int x)
{
    sucai001(44,10,14);
    zuobiao(46,11);
    if(x==1)
    {
        printf("          成功          ");
    }
    else
    {
        printf("          失败          ");
    }
    sucai001(44,13,14);
    zuobiao(46,14);
    printf("  ");
    system("pause");
}

链表不要忘了释放内存

void end()
{
    p1=head;
    while(p1->next==NULL)
    {
        pd=p1->next;
        free(p1);
        p1=pd;
    }
}

最后就是那一疙瘩的主函数

int main()
{
    yincangguangbiao();
    suijishu(1);
    system("title 贪吃蛇");
    while(1)
    {

        system("mode con cols=120 lines=30");
        fenshu=0;
        fangxiang=4;
        fflush(stdin); //清除键盘缓冲区
        caidankongzhi=' ';
        donghua001();
        system("Cls");
        caidan();
        donghua001();
        switch(caidankongzhi)
        {
        case '0':
            system("Cls");
            if(zhuangtai==1)
            {
                jiemian003(1);
                zhuangtai=0;
                break;
            }
            jiemian002();
            if(jiemiankongzhi=='1')
            {
                zhuangtai=denglu();
            }
            if(jiemiankongzhi=='2')
            {
                zhuangtai=zhuce();
            }
            system("Cls");
            if(zhuangtai==0)
            {
                jiemian003(0);
            }
            else
            {
                jiemian003(1);
            }
            break;
        case '1':
            system("Cls");
            snakebody();
            map();
            sleeptime=80;
            fangxiang=4;
            while(1)
            {
                kongzhi();
                yidong();
                if(panduan==1)
                {
                    break;
                }
                Sleep(sleeptime);
            }
            jiemian001();
            break;
        case '2':
            system("Cls");
            sleeptime=200;
            snakebody();
            map();
            zuobiao(72,9);
            printf("急速模式速度会逐渐加快");
            fangxiang=4;
            while(1)
            {
                kongzhi();
                yidong();
                if(panduan==1)
                {
                    break;
                }
                Sleep(sleeptime);
            }
            jiemian001();
            break;
        case '3':
            zuobiao(34,13);
            printf("重要提示:");
            zuobiao(34,14);
            printf("本作品csdn头顶有点冷完全独立完成");
            zuobiao(34,15);
            printf("未经本人允许严禁他人用作商业用途");
            zuobiao(34,16);
            system("pause");
            system("Cls");
            break;
        }
        if(caidankongzhi=='1'||caidankongzhi=='2')
            end();
    }
}

结束
码字不易,多多支持
我以后应该还会学习一些c++,汇编,php之类的一些内容,喜欢的话关注一下吧
------------------某二本院校的大一学生

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值