小游戏——贪吃蛇(基础版)

菜鸟上路,可能会存在一些问题,欢迎各位同志指出改正哦!!!

废话不多说,上正文


头文件内容:

#ifndef  __SNAKE_H__
#define __SNAKE_H__
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <time.h>

enum Direction
{
    UP=1,
    DOWN,
    LEFT,
    RIGHT
};

enum GameStatus
{
    OK,
    NORMAL_END,
    KILL_BY_WALL,
    KILL_BY_SELF
};
#define RED           "/033[0;32;31m"   
#define BLUE          "/033[0;32;34m"   
#define WALL "■"
#define FOOD "●"
#define FLOWER "*"
#define INIT_X 10
#define INIT_Y 10


typedef struct SnakeNode
{
    int x;
    int y;
    struct SnakeNode* next;
}SnakeNode, *pSnakeNode;

typedef struct Snake
{
    pSnakeNode _psnake;//维护蛇身的指针
    pSnakeNode _pFood; //维护食物的位置
    int _TotalScore;   //总分数
    int _AddScore;     //增加的分数
    int _SleepTime;    //休眠时间
    enum Direction _Dir;
    enum GameStatus _Status;
}Snake, *pSnake;

void GameStart(pSnake ps);//开始游戏
void WelcomeToGame();//欢迎界面
void CreateMap();//设置地图
void InitSnake(pSnake ps);//初始化蛇
void CreateFood(pSnake ps);//放置食物

void Pause();//暂停游戏
void SnakeMove(pSnake ps);//控制蛇的移动
int NextHasFood(pSnakeNode next,pSnake ps);//判断下一步是否有食物
void EatFood(pSnakeNode Next,pSnake ps);//吃掉食物
void NoFood(pSnakeNode Next,pSnake ps);//没有食物时蛇的移动
void GameRun(pSnake ps);//游戏继续

void GameEnd(pSnake ps);//结束游戏

#endif //__SNAKE_H__

函数设计:

#include"snake.h"
#include<Windows.h>
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include <WinBase.h>
void SetPos(int x,int y)
{
    COORD pos={0};
    HANDLE hOutput=NULL;    
    CONSOLE_CURSOR_INFO CursorInfo;
    pos.X=x;
    pos.Y=y;
    hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOutput,pos);

    GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
    CursorInfo.bVisible = 0; //隐藏控制台光标
    SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态

}

void Line()//开始前的问候语边框
{
    int i = 0;
    //上边界
    for(i=20;i<=80;i+=2)
    {
        SetPos(i, 8);
        printf(FLOWER );
    }
    //下
    for(i=20;i<=80;i+=2)
    {
        SetPos(i,22);
        printf(FLOWER );
    }
    //左
    for(i=9;i<=22;i++)
    {
        SetPos(20,i);
        printf(FLOWER);
    }
    //右
    for(i=9;i<=22;i++)
    {
        SetPos(80,i);
        printf(FLOWER);
    }
}
void WelcomeToGame()
{
    system("mode con cols=100 lines=30");
    Line();
    SetPos(40,14);
    printf("欢迎来到贪吃蛇游戏");
    SetPos(0,28);
    system("pause");

    system("cls");
    SetPos(62,11);
    printf("游戏规则如下:");
    SetPos(62,12);
    printf("请通过↑,↓,←,→控制贪吃蛇的移动");
    SetPos(62,13);
    printf("F1加速可获得高分,F2减速");
    SetPos(0,28);   
    system("pause");
    system("cls");
}

void CreatMap()
{
    int i = 0;
    //上边界
    for(i=0;i<=58;i+=2)
    {
        SetPos(i, 0);
        printf(WALL);
    }
    //下
    for(i=0;i<=58;i+=2)
    {
        SetPos(i,27);
        printf(WALL);
    }
    //左
    for(i=1;i<=27;i++)
    {
        SetPos(0,i);
        printf(WALL);
    }
    //右
    for(i=1;i<=27;i++)
    {
        SetPos(58,i);
        printf(WALL);
    }
}
pSnakeNode BuyNode()
{
    pSnakeNode pRet=(pSnakeNode)malloc(sizeof(SnakeNode));
    if(pRet==NULL)
    {
        perror("BuyNode::malloc()");
        exit(EXIT_FAILURE);
    }
    pRet->x=0;
    pRet->y=0;
    pRet->next=NULL;
    return pRet;
}
void InitSnake(pSnake ps)
{
    pSnakeNode First=(pSnakeNode)malloc(sizeof(SnakeNode));
    int i=0;
    pSnakeNode cur=NULL;
    First->x=INIT_X;//设置第一个节点的位置
    First->y=INIT_Y;
    First->next=NULL;
    for(i=1;i<=4;i++)//蛇的后四个节点
    {
        cur=BuyNode();
        cur->x=(First->x)+2;
        cur->y=(First->y);
        cur->next=First;
        First=cur;
    }
    while(cur)//打印蛇身
    {
        SetPos(cur->x,cur->y);
        printf(FOOD);
        cur=cur->next;
    }
    ps->_SleepTime=500;//确定蛇的速度
    ps->_TotalScore=0;
    ps->_Status=OK;
    ps->_Dir=RIGHT;
    ps->_AddScore=10;
    ps->_psnake=First;
}

void CreatFood(pSnake ps)//创建食物
{
    pSnakeNode pFood=BuyNode();//维护食物
    pSnakeNode cur=ps->_psnake;//维护蛇头
    pFood->y=rand()%26+1;
    do
    {
        pFood->x=rand()%55+2;
    }while(pFood->x%2!=0);//坐标在合法范围内
    while(cur)//避免在蛇身上
    {
        if( (cur->x==pFood->x) &&  (cur->y==pFood->y) )
        {
            CreatFood(ps);
            return ;
        }
        cur=cur->next;
    }
    SetPos(pFood->x,pFood->y);
    printf(FOOD);
    ps->_pFood=pFood;
}

void GameStart(pSnake ps)
{
    WelcomeToGame();
    CreatMap();
    InitSnake(ps);

    CreatFood(ps);
    SetPos(0,28);
    ps->_TotalScore=0;
    ps->_AddScore=10;
}

 int NextHasFood(pSnakeNode next,pSnake ps)//判断next是否有食物
{
    return( (next->x == ps->_pFood->x) && (next->y== ps->_pFood->y)  );
}

 void EatFood(pSnakeNode Next,pSnake ps)
{
    pSnakeNode cur=NULL;
    Next->next=ps->_psnake;
    ps->_psnake=Next;
    cur=ps->_psnake;
    while(cur != NULL)//打印吃掉的食物
    {
        SetPos(cur->x,cur->y);
        printf(FOOD);
        cur=cur->next;
    }
    ps->_TotalScore+=ps->_AddScore;//吃掉食物加分
    CreatFood(ps);//再次放置食物
}

 void NoFood(pSnakeNode Next,pSnake ps)
{
    pSnakeNode cur=NULL;
    Next->next=ps->_psnake;
    ps->_psnake=Next;
    cur=ps->_psnake;
    while(cur->next->next != NULL)//打印吃掉的食物
    {
        SetPos(cur->x,cur->y);
        printf(FOOD);
        cur=cur->next;
    }
    SetPos(cur->next->x,cur->next->y);
    printf("  ");
    free(cur->next);
    cur->next=NULL;
}
void SnakeMove(pSnake ps)
{
    pSnakeNode nextNode=BuyNode();
    nextNode->x=ps->_psnake->x;
    nextNode->y=ps->_psnake->y;
    SetPos(65,8);
    printf("总分:%d  \n",ps->_TotalScore);
    SetPos(65,7);
    printf("加分:%d  \n",ps->_AddScore);
    switch (ps->_Dir)
    {
    case UP:
        {
            (nextNode->y)-=1;
            if(NextHasFood(nextNode,ps))//蛇头和食物在同一位置,吃掉食物
                EatFood(nextNode,ps);
            else
                NoFood(nextNode,ps);
            break;
        }
    case DOWN:
        {
            (nextNode->y)+=1;
            if(NextHasFood(nextNode,ps))//蛇头和食物在同一位置,吃掉食物
                EatFood(nextNode,ps);
            else
                NoFood(nextNode,ps);
            break;
        }
    case LEFT:
        {
            (nextNode->x)-=2;
            if(NextHasFood(nextNode,ps))//蛇头和食物在同一位置,吃掉食物
                EatFood(nextNode,ps);
            else
                NoFood(nextNode,ps);
            break;
        }
    case RIGHT:
        {
            (nextNode->x)+=2;
            if(NextHasFood(nextNode,ps))//蛇头和食物在同一位置,吃掉食物
                EatFood(nextNode,ps);
            else
                NoFood(nextNode,ps);
            break;
        }
    }
}

void Pause()//暂停游戏
{
    while(1)
    {
        Sleep(100);
        if(GetAsyncKeyState(VK_SPACE))
        break;
    }
}

int KillByWall(pSnake ps)
{
    if(  (ps->_psnake->x==0)  ||  (ps->_psnake->x==58)
        ||(ps->_psnake->y==0) || (ps->_psnake->y==27)  )
    {
        ps->_Status=KILL_BY_WALL;
        return 1;//撞墙死掉
    }
    return 0;
}

int KillByItself(pSnake ps)
{
    pSnakeNode pnext=ps->_psnake->next;
    while(pnext)
    {
        if( (pnext->x == ps->_psnake->x)&&(pnext->y == ps->_psnake->y) )
        {
            ps->_Status=KILL_BY_SELF;
            return 1;
        }
        pnext=pnext->next;
    }
    return 0;
}

void PrintfHelp()
{
    SetPos(62,11);
    printf("游戏规则如下:");
    SetPos(62,12);
    printf("请通过↑,↓,←,→控制贪吃蛇的移动");
    SetPos(62,13);
    printf("F1加速可获得高分,F2减速");
}

void GameRun(pSnake ps)
{
    do{
        PrintfHelp();
        //确定方向
        if( GetAsyncKeyState (VK_UP) && ps->_Dir!=DOWN )
        {
            ps->_Dir=UP;
        }
        else if( GetAsyncKeyState (VK_DOWN) && ps->_Dir!=UP )
        {
            ps->_Dir=DOWN;
        }
        else if( GetAsyncKeyState (VK_LEFT) && ps->_Dir!=RIGHT )
        {
            ps->_Dir=LEFT;
        }
        else if( GetAsyncKeyState (VK_RIGHT) && ps->_Dir!=LEFT )
        {
            ps->_Dir=RIGHT;
        }
        else if( GetAsyncKeyState (VK_SPACE) )
        {
            //暂停游戏
            Pause();
        }
        else if( GetAsyncKeyState (VK_ESCAPE) )
        {
            //停止游戏
            ps->_Status=NORMAL_END;
            //break;
        }

        else if( GetAsyncKeyState (VK_F2))
        {
            if(ps->_SleepTime <=560)//减速
            {
                ps->_SleepTime +=20;
                ps->_AddScore-=2;
            }
        }
        else if( GetAsyncKeyState (VK_F1))
        { 
            if(ps->_SleepTime >=200)  //加速,初始的SleepTime=500
            {
                ps->_SleepTime -=20;
                ps->_AddScore+=2;
            }
        }
        Sleep(ps->_SleepTime);
        SnakeMove(ps);  //让蛇移动
        if(KillByWall(ps))
            break;
        if(KillByItself(ps))
            break;          
    }while(ps->_Status == OK);
}

void GameEnd(pSnake ps)
{
    pSnakeNode cul=ps->_psnake;
    pSnakeNode del=NULL;
    switch(ps->_Status )
    {
    case KILL_BY_WALL:
        {
            SetPos(25,14);
            system("color 04");
            printf("游戏结束,你撞墙了");
            SetPos(0,28);
            while(cul->next)//释放蛇的空间
            {
                del=cul;
                cul=cul->next;
                free(del);
                del=NULL;

            }
            free(ps->_pFood);
            ps->_pFood=NULL;
            break;
        }
    case KILL_BY_SELF:
        {
            SetPos(25,14);
            system("color 04");
            printf("游戏结束,你撞到自己了");
            SetPos(0,28);

            while(cul->next)//释放蛇的空间
            {
                del=cul;
                cul=cul->next;
                free(del);
                del=NULL;           
            }
            free(ps->_pFood);
            ps->_pFood=NULL;
            break;
        }
    }
}

测试代码:

#include"snake.h"
#include<stdlib.h>
void test()
{

    Snake  snake;
    srand((unsigned int) (time(NULL)));
    GameStart(&snake);
    GameRun(&snake);    
    GameEnd(&snake);

}

int main()
{
    test();
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/S_Sandra/article/details/82317394