C语言贪吃蛇小游戏

C语言编写贪吃蛇

整个代码都是C语言,其中调用少部分库函数,不如实现屏幕坐标打印的函数,贪吃蛇游戏代码的核心在于蛇身体坐标的更新,实现细节请看代码注释,

代码



//#include "stdafx.h"   如果是vc环境的话加上该头文件 
#include<stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
#define  TURNUP    1     //宏定义蛇运动的四个方向 
#define  TURNDOWN  2
#define  TURNRIGHT 3
#define  TURNLEFT  4
#define  MAXROW    20
#define  MAXCOL    30

void printSnake(int bodylen,COORD bodypos[]);
void run (int bodylen,COORD *body,int dirction,int times);
void initSnake (int bodylen,COORD* body,COORD head);
void disappeartSnake(int bodylen,COORD *bodypos);
void createFood();
void printwall();
void printscore(int len);
void supervisekeybot(COORD *body,int direction,int times);
void createFood1();

int len=5;
COORD gfoodPos;            //定义三个全局变量,身体长度和两种食物 坐标
COORD gfoodPos1;           // COORD为系统定义结构体,可实现屏幕坐标表示 

int main(int argc, char* argv[])
{
    int direction=TURNRIGHT;//没有按键输入时默认的初始方向

    COORD body[20]={0};
    COORD head={1,1};          

    printwall();
    initSnake (len,body,head);//根据head初始化蛇的身体
    printSnake(len,body);     //打印初始的蛇
    createFood();
    createFood1();

    supervisekeybot(body,direction,10);

    return 0;
}


/*******************************************
函数名称:printSnake
函数功能:打印蛇的身体
函数参数:bodylen --身体的长度
          bodypos --蛇身体的坐标 
函数返回:
函数作者:forxn@qq.com 
********************************************/
void printSnake(int bodylen,COORD *bodypos)
{
        //调用库函数,获取蛇身体的坐标,并在该坐标点打印信息,蛇头为8,蛇身为* 
        HANDLE hOut;
        COORD pos=bodypos[bodylen-1];
        hOut=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(hOut,pos);
        printf("8\n");
    for(int i=0;i<bodylen-1;i++)
    {
        HANDLE hOut;
        //获取蛇身体的坐标
        COORD pos=bodypos[i];
        hOut=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(hOut,pos);
        //打印该点
        printf("*\n");

    }
} 

/*******************************************
函数名称:changeDirction
函数功能:实现蛇的转弯,或者说蛇身体的更新
该函数为整个贪吃蛇的核心点,核心思想为以蛇头坐标为起点,
此程序将蛇头坐标定为body[len-1]; 
后面点的坐标都取其前一个点的的位置 
********************************************/
void  changeDirction(int bodylen,COORD *body,int dirction)
{
    int     p=bodylen;
    for(int i=0;bodylen>1;bodylen--)
    {
        body[i]=body[i+1];
        i++;
    }
    switch (dirction)
    {
    case TURNUP :
        {
            body[p-1].Y--;
            break;
        }
    case TURNDOWN :
        {
            body[p-1].Y++;
            break;
        }
    case TURNRIGHT:
        {
            body[p-1].X++;
            break;
        }
    case TURNLEFT :
        {
            body[p-1].X--;
            break;
        }
    default:
        {
            break;
        }
    }
    //吃到食物的时候
    if(body[p-1].X==gfoodPos.X
        &&body[p-1].Y==gfoodPos.Y)
    {


        body[p].X=body[p-1].X;
        body[p].Y=body[p-1].Y;
        len++;
        createFood();
        printscore(bodylen);

    }
else    if(body[p-1].X==gfoodPos1.X   //此处必须加else;不然有bug
        &&body[p-1].Y==gfoodPos1.Y)
    {
        body[p].X=body[p-1].X;
        body[p].Y=body[p-1].Y;
        body[p+1].X=body[p].X;
        body[p+1].Y=body[p].Y;
        len=len+2;
        createFood1();
        printscore(bodylen);
    }

    //边界检测
    if(body[p-1].X==0||body[p-1].Y==0||body[p-1].X==MAXCOL||body[p-1].Y==MAXROW)
    {
        COORD a;
        a.X=5;
        a.Y=10;
        HANDLE hOut;
        hOut=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(hOut,a);  
        printf("GAME  OVER!");
        printSnake(len,body);  
        exit(0);

    }


    for (int j=0;j<p;j++)
    {
        if (body[p-1].X==body[p-j-2].X&&body[p-1].Y==body[p-j-2].Y)
        {
            COORD b;
            b.X=5;
            b.Y=10;
            HANDLE hOut;
            hOut=GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleCursorPosition(hOut,b);  
            printf("GAME  OVER!");
            printSnake(len,body);  
            exit(0);
        }

    }



}

/*******************************************
函数功能:
函数参数:
********************************************/
void run (int bodylen,COORD *body,int dirction,int times)
{
    for(int i=0;i<times;i++)
    {
        //重新设置蛇身体的点坐标
        changeDirction(bodylen,body,dirction);

        printSnake(bodylen,body);
        Sleep(200);
        disappeartSnake(bodylen,body);
    }          
}
/*******************************************
函数功能:
函数参数:
********************************************/

void initSnake (int bodylen,COORD* body,COORD head)
{
    for (int i=0;i<bodylen;i++)
    {
        body[bodylen-i-1].X=head.X;
        body[bodylen-1-i].Y=head.Y;

    }
}

/*******************************************
函数功能:产生食物,调用rand函数随机位置产生两种食物 
函数参数:
********************************************/
void createFood()
{
    srand(time(0));
    int x=rand()%(MAXCOL-1);
    int y=rand()%(MAXROW-1);

    gfoodPos.X=x;
    gfoodPos.Y=y;
    if(gfoodPos.X==0||gfoodPos.Y==0)
    {
        createFood();
    }

        HANDLE hOut;
        hOut=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(hOut,gfoodPos);
        printf("A\n");

}
void createFood1()
{
    //srand(time(0));
    int x=rand()%(MAXCOL-1);
    int y=rand()%(MAXROW-1);

    gfoodPos1.X=x;
    gfoodPos1.Y=y;
    if(gfoodPos1.X==0||gfoodPos1.Y==0)
    {
        createFood1();
    }

        HANDLE hOut;
        hOut=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(hOut,gfoodPos1);
        printf("B\n");

}
/*******************************************
函数功能:蛇身体的更新,调用system("cls")不能满足要求
          将坐标点依次打印空格可实现“清屏”效果 
函数参数:
********************************************/

void disappeartSnake(int bodylen,COORD *bodypos)
{
    for(int i=0;i<bodylen;i++)
    {
        HANDLE hOut;
        COORD pos=bodypos[i];
        hOut=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(hOut,pos);
        printf(" \n");

    }
} 

/*******************************************
函数功能:打印墙的边界
函数参数:
********************************************/
void printwall()
{
    for(int i=0;i<=MAXROW;i++)
    {
        for(int j=0;j<=MAXCOL;j++)
        {
            if(i==0||j==0||i==MAXROW||j==MAXCOL)          
                putchar('#');
            else
                printf(" ");
        }
        putchar('\n');
    }
}

/*******************************************
函数功能:检测键盘的按键,实现蛇的实时控制 
函数参数:
********************************************/
void supervisekeybot(COORD *body,int direction,int times)
{
    while(1)        // 蛇开始移动并监测键盘
    {   
        run (len,body,direction,1);
        printscore(len);
        if(_kbhit())//监测键盘是否有输入,也可采用多线程实现,此处调用_kbhit()
        {
            char ch=getch();
            switch (ch)
            {
            case 'w':
                {
                    run (len,body,TURNUP,1);//此时times设置为1,才能实现实时控制响应;
                    direction=TURNUP;       //键盘键入时蛇的方向更新并维持
                    break;
                }
            case 's':
                {
                    run (len,body,TURNDOWN,1);
                    direction=TURNDOWN;
                    break;
                }
            case 'a':
                {
                    run (len,body,TURNLEFT,1);
                    direction=TURNLEFT;
                    break;
                }
            case 'd':
                {
                    run (len,body,TURNRIGHT,1);
                    direction=TURNRIGHT;
                    break;
                }
            }
        }



    }

}
/*******************************************
函数功能:将蛇的身体长度打印,作为分数 
函数参数:
********************************************/
void printscore(int len)
{
    COORD score;
    score.X=32;
    score.Y=12;
    HANDLE hOut;
    hOut=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOut,score);
    printf("SCORE:%d",len);     
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值