新手上路,C语言贪吃蛇,极简版

写在最前面

  1. 文中的代码是copy一个CSDN博客上的代码,由于时间有点久,我现在找不到那篇文章了。如有人找到请与我联系。侵权必删。
  2. 本人大一开学一个月后,在初学C语言,还没有任何编程基础的前提下,因为要完成团队一周写完贪吃蛇的任务,所以就在网上找了源码直接入手进行的分析。
    ----------------------------手动分割

这是一个啥都不懂的freshman与贪吃蛇的故事,也只适合啥都不懂的小新人看。
我的思路很简单。在啥都不懂的情况下,我觉得靠自己一个字一个字的把贪吃蛇敲出来是有点不太现实,所以我直接在网上copy了一份代码(感谢CSDN的大神们给我提供了如此多优秀的代码),打算直接看懂之后自己再独立复制一个出来。所以下面写的东西是我终于看懂了某大神写的贪吃蛇之后分享的一点经验。
我觉得如果要写一个东西的话,第一点最重要的,就是要从宏观上对这个程序的各种功能有一个清晰的认识。我做贪吃蛇需要用到哪些函数?用到哪些头文件?这些是要在main函数之前就定义好的(个人习惯),所以,我们写一个贪吃蛇,就要搞好头文件与全局变量。

#include<stdio.h>
#include<conio.h>
#include<windows.h>
#include<time.h>
#define framex 5
#define framey 5
#define wide 20
#define high 20
int i,j,a[2];

要定义的函数有:移动光标,制作封面,定义蛇结构体,定义食物结构体,制作框架,打印边框,打印游戏信息,初始化蛇,打印蛇,移动蛇,打印食物,吃食物,死亡判断。
下面一个一个来讲一下。

1. 移动光标

就是一个gotoxy函数。说实话作为一个新人除了知道这个函数是用来移动光标的之外,其他真的什么都不知道了。但是gotoxy函数有自己固定的模板,所以就直接copy模板就可以了(部长说这个我们以后就会懂了)。

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

2. 制作封面

封面的制作就因人而异了,主要是给用户一点提示,告诉用户我们要开始进行贪吃蛇啦。这里要用到我们前面定义的gotoxy函数了,然后在用户按下回车键的时候结束封面,开始游戏。注意在封面函数的最后要清屏方便我们定义游戏界面。

void cover (HANDLE hout)
{
    gotoxy(hout,framex+wide,framey);
    printf("欢迎使用贪吃蛇游戏");
    gotoxy(hout,framex+wide*2,framey+20);
    printf( "游戏制作者:Anastasia"); 
    gotoxy(hout,framex+wide*2,framey+22);
    printf("制作时间:2018年10月"); 
    char a;
    a=getchar();
    system("cls");
}

3.定义蛇与食物的结构体

就直接用结构体就可以啦,这个不细说。

struct  Snake
{
    int x[100];
    int y[100];
    int speed;
    int length;
    int count;
};
struct Food
{
    int x;
    int y;
};

4.制作框架与打印框架

在游戏界面上总要有一些文字来提示游戏操作之类的信息,所以我们需要添加一些东西上去。当然,这里依旧要用到gotoxy函数。还要把蛇的移动限制在一个框框内,所以我们要printf一个边框出来。

void makeframe(struct Snake snake)
{
    HANDLE hout=GetStdHandle(STD_OUTPUT_HANDLE);
    gotoxy(hout,framex+wide*2+5,framey);
    printf( "   贪吃蛇游戏"); 
    gotoxy(hout,framex+wide*2+5,framey+3);
    printf("使用方向键移动");
    gotoxy(hout,framex+wide*2+5,framey+5);
    printf("长按方向键可加速");
    gotoxy(hout,framex+wide*2+5,framey+7);
    printf("按任意键暂停,方向键继续");
    for(i=0;i<wide*2+1;i++)
    {
        gotoxy(hout,framex+i,framey);
        printf("*");
    }
    for(i=0;i<wide*2+2;i++)
    {
        gotoxy(hout,framex+i,framey+high);
        printf("*");
    }
    for(i=0;i<high;i++)
    {
        gotoxy(hout,framex,framey+i);
        printf("*");
    }
    for(i=0;i<high;i++)
    {
        gotoxy(hout,framex+wide*2+1,framey+i);
        printf("*");
    }
}

5.打印游戏信息

我们定义蛇的时候定义了它的speed,count,length,所以我们在界面上需要再弄出一个地方来记录蛇信息的变化。依旧,gotoxy函数。还有就是这里用到了指针,函数里面的->可以简单的理解成“的”。比如snake->count,就可以理解为snack的count。当然如果不用指针的话就是写成snake.count了。

void infor(HANDLE hout,struct Snake* snake)
{
    gotoxy(hout,framex+wide*2+5,framey+15);
    printf("当前速度:%d",-snake->speed+500);
    gotoxy(hout,framex+wide*2+5,framey+17);
    printf("当前得分:%d",snake->count);
    gotoxy(hout,framex+wide*2+5,framey+19);
    printf("当前长度:%d",snake->length);
} 

6.初始化蛇

这里就是给蛇的各种信息进行初始化,就是把蛇刚刚开始的位置以及蛇最初移动的方向给确定下来。这里的for循环就是让蛇的x坐标在前一个位置上加一(也就是向右移),同时y坐标不变。

void initsnake(struct Snake *snake)
{
    snake->x[0]=framex+2;
    snake->y[0]=framey+high/2;
    snake->count=0;
    snake->length=3;
    snake->speed=400;
    for(i=1;i<snake->length;i++)
    {
        snake->x[i]=snake->x[i-1]+1;
        snake->y[i]=snake->y[i-1];
    }
}

7.打印蛇

遍历蛇身,在头的位置打印○,在蛇身和蛇尾的位置打印●,当然啦,也可以打印别的东西,让用户看懂就好。

void printsnake(HANDLE hout ,struct Snake *snake)
{
    for(i=0;i<snake->length;i++)
    {
        gotoxy(hout,snake->x[i],snake->y[i]);
        if(i==snake->length-1) 
            printf("○");
        else if(i==0)
            printf("●");
        else 
            printf("●"); 
    }
}

8.移动蛇

这是最关键的一点,好多好多人在写贪吃蛇的时候都没办法让蛇动起来。这里的顺序是先把蛇尾清空,再遍历蛇身,把蛇的后一节坐标变成前一节的坐标 。

{
    gotoxy(hout,snake->x[0],snake->y[0]);
    printf("  ");
    for(i=1;i<snake->length;i++)
    {
        snake->x[i-1]=snake->x[i];
        snake->y[i-1]=snake->y[i];
    }
}

9.打印食物

打印食物其实是一个比较麻烦的事情。要用计算机时间获取随机值(这里也是一个固定的函数),要判断食物是否出现在边框上,是否出现在蛇身上,如果出现要重新生成食物。我是用的★表示食物。

void printfood (HANDLE hout,struct Snake *snake,struct Food* food){
    //用计算机时间获取随机值 
    srand((unsigned)time(NULL));
    while(1){
        //将食物的横纵坐标的大小限定在窗口大小内 
        food->x=rand()%(wide-2)+1;
        food->y=rand()%(high-2)+1;
        //避免食物出现在边框上 
        if(food->x==0&&food->y==0)
            continue;
        //将食物的坐标放置在窗口内 
        food->x=2*food->x+framex;
        food->y+=framey;
        //如果食物出现在蛇上,重新产生食物 
        for(i=0;i<snake->length;i++){
            if(food->x==snake->x[i]&&food->y==snake->y[i])
                break;
        }
        //食物不在蛇上,打印食物,结束循环 
        if(i==snake->length){
            gotoxy(hout,food->x,food->y);
            printf("★");
            break;  
        }
    }
}

10.吃食物

如果蛇头的坐标等于食物的坐标,则蛇长加一 ,然后遍历蛇身,蛇身(不包括蛇尾)整体向前移动一格 。

void eatfood(HANDLE hout,struct Snake * snake,struct Food *food)
{
   if(snake->x[snake->length-1]==food->x&&snake->y[snake->length-1]==food->y)
       snake->length++;
       for(i=snake->length-1;i>0;i--)
       {
           snake->x[i]=snake->x[i-1];
           snake->y[i]=snake->y[i-1];
       }
       snake->x[0]=a[0];
       snake->y[0]=a[1];
       printfood(hout,snake,food);
       snake->count++;
       if(snake->count%3==0)
           snake->speed-=50;
   }
}

11.死亡判断

当蛇的头位置触碰到我们之前设定的框架的位置或者触碰到蛇自身,则判断为蛇死亡。return 0.

int ifdead(struct Snake* snake)
{
    if(snake->x[snake->length-1]==framex)
        return 0;
    if(snake->x[snake->length-1]==framex+wide*2)
        return 0;
    if(snake->y[snake->length-1]==framey)
        return 0;
    if(snake->y[snake->length-1]==framey+high)
        return 0;
        for(i=0; i<snake->length-1; i++) 
        if( snake->x[snake->length-1]==snake->x[i] && snake->y[snake->length-1]==snake->y[i] ) 
            return 0;
    return 1;
}

这就是贪吃蛇需要的几个最基本的函数了。
当然进阶版的还有生成毒草,智慧果,分等级之类的更加高级的功能,但是今天就先研究到这里吧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值