贪吃蛇

学了C语言的同学们快来写一个属于自己的贪吃蛇小游戏吧~
我的这个贪吃蛇是最基本的几个功能实现,有了这几个基本的框架,我们可以在后期根据自己的想法来扩展它的功能。下面是我的一些扩展的想法(后面慢慢实现):
1.给界面加上颜色
2.添加一项可以记录最高成绩的功能
3.实现两条蛇竞争的双人贪吃蛇
4.贪吃蛇大作战

Snake.h

#ifndef __Snake__H__
#define __Snake__H__

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>

#define INIT_X 20
#define INIT_Y 10

#define FOOD  "★"//■★□●▼▲♡☞☏⊙◎☻♧♂♀☼▧▨
#define WALL  "■"
#define SNAKE "●"

/*
VK_ESCAPE ESC键

VK_RETURN回车键

VK_TABTAB键

VK_SPACE空格键
*/

//方向
enum Dir
{
    _UP,//上
    _DOWN,//下
    _LEFT,//左
    _RIGHT//右
};

//蛇的状态
enum Status
{
    _OK,//活
    _OKEND,//死
    _KILLBYSELF,//撞到自己而死
    _KILLBYWALL//撞到墙而死
};


typedef struct Snakenode
{
    struct Snakenode* _next;
    int x;
    int y;
}Snakenode;


typedef struct Snake
{
    Snakenode* _Snakebody;//蛇的身体
    Snakenode* _Snakefood;//蛇的食物
    int _TotalScore;//总得分
    int _AddScore;//每次加的分
    int _Time;//速度
    enum Dir _Dir;//蛇走的方向
    enum Status Status;//蛇的状态
}Snake;


Snakenode* Buy_Node();
void Set_Pos(size_t x, size_t y);
void Welcom_To_Game();
void Init(Snake* snake);
void CreatMap();
void ScoreAndTips(Snake* snake);
void CreatFood(Snake* snake);
void Game_Start(Snake* snake);
void Game_Run(Snake* snake);
void Game_End();

#endif

Snake.c

#define _CRT_SECURE_NO_WARNINGS 
#include"Snake.h"

//创建一个结点
Snakenode* Buy_Node()
{
    Snakenode *snakebody;
    snakebody = (Snakenode*)malloc(sizeof(Snakenode));
    if (snakebody == NULL)
    {
        perror("error!\n");
        exit(0);
    }
    snakebody->_next = NULL;
    return snakebody;
}

//设置光标的位置
void Set_Pos(int x, int y)
{
    COORD pos = { 0 };
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//获取这台机器的光标
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle, pos);//设置光标到pos的位置
}

//介绍游戏的游戏界面
void Welcom_To_Game()
{
    system("mode con cols=100 lines=30");//设置游戏界面窗口的大小(横100,竖30)
    //横 竖
    Set_Pos(35, 15);
    printf("欢迎来到贪吃蛇小游戏");
    Set_Pos(20, 17);
    printf("用 ↑.↓.←.→分别控制蛇的移动,F1为加速,F2为减速。");
    Set_Pos(35, 19);
    printf("加速将能得到更高的分数。");
    Set_Pos(35, 29);
    system("pause");
    system("cls");
}

//初始化蛇
void Init(Snake* snake)
{
    Snakenode *node1,*next;
    int i = 0;
    node1 = Buy_Node();
    node1->x = INIT_X;
    node1->y = INIT_Y;
    node1->_next = NULL; 
    //创建一个蛇身为4的蛇(头插法)
    for (i = 1; i < 4; i++)
    {
        next = Buy_Node();
        next->x = node1->x+2;
        next->y = node1->y;
        next->_next = node1;
        node1= next;
    }

    //打印蛇身
    next = node1;
    for (i = 1; i <= 4; i++)
    {
        Set_Pos(next->x,next->y);
        printf(SNAKE);
        next = next->_next;
    }
    snake->_Snakebody = node1;
}

//初始化墙
void CreatMap()
{
    int i, j;
    //上下
    for (i = 0; i <= 58; i += 2)
    {
        Set_Pos(i,0);
        printf(WALL);
        Set_Pos(i,29);
        printf(WALL);
    }
    //左右
    for (j = 1; j <= 28; j++)
    {
        Set_Pos(0,j);
        printf(WALL);
        Set_Pos(58,j);
        printf(WALL);
    }
}

//初始化食物
void CreatFood(Snake* snake)
{
    Snakenode* food,*cur=snake->_Snakebody;
    food = Buy_Node();
    do
    {
        food->x = (rand() % 55) + 2;
    } while ((food->x)%2 != 0);
    food->y = (rand() % 28) + 1;
    while (cur)
    {
        if ((food->x == cur->x) && (food->y == cur->y))
        {
            CreatFood(snake);
            return;
        }
        cur = cur->_next;
    }
    snake->_Snakefood = food;
    Set_Pos(snake->_Snakefood->x,snake->_Snakefood->y);
    printf(FOOD);
}

//判断有没有吃到食物
int If_Food(Snakenode* food,Snakenode* new)
{
    if ((food->x == new->x)&&(food->y == new->y))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

//吃到食物后移动
void Eat_Food(Snake* snake, Snakenode* new)
{
    new->_next = snake->_Snakebody;
    snake->_Snakebody = new;
    Set_Pos(snake->_Snakebody->x, snake->_Snakebody->y);
    printf(SNAKE);
    CreatFood(snake);
}

void Not_Eatfood(Snake* snake, Snakenode* new)
{
    Snakenode*cur;
    new->_next = snake->_Snakebody;
    snake->_Snakebody = new;
    cur = snake->_Snakebody;
    while (cur->_next->_next)
    {
        Set_Pos(cur->x, cur->y);
        printf(SNAKE);
        cur = cur->_next;
    }
    Set_Pos(cur->x, cur->y);
    printf(SNAKE);
    Set_Pos(cur->_next->x, cur->_next->y);
    printf(" ");
    free(cur->_next);
    cur->_next = NULL;
}

//蛇开始移动
void Snake_Move(Snake* snake)
{
    Snakenode *new = Buy_Node();
    switch (snake->_Dir)
    {
    case _UP:
    {
                new->x = snake->_Snakebody->x;
                new->y = snake->_Snakebody->y-1;
                if (If_Food(snake->_Snakefood, new))
                {
                    Eat_Food(snake,new);
                    snake->_TotalScore += snake->_AddScore;
                    //system("cls");
                    ScoreAndTips(snake);
                }
                else
                {
                    Not_Eatfood(snake, new);
                }

    }
        break;
    case _DOWN :
    {
                   new->x = snake->_Snakebody->x;
                   new->y = snake->_Snakebody->y+1;
                   if (If_Food(snake->_Snakefood, new))
                   {
                       Eat_Food(snake, new);
                       snake->_TotalScore += snake->_AddScore;
                     //  system("cls");
                       ScoreAndTips(snake);
                   }
                   else
                   {
                       Not_Eatfood(snake, new);
                   }

    }
        break;
    case _LEFT:
    {
                  new->x = snake->_Snakebody->x-2;
                  new->y = snake->_Snakebody->y;
                  if (If_Food(snake->_Snakefood, new))
                  {
                      Eat_Food(snake, new);
                      snake->_TotalScore += snake->_AddScore;
                      //system("cls");
                      ScoreAndTips(snake);
                  }
                  else
                  {
                      Not_Eatfood(snake, new);
                  }

    }
        break;
    case _RIGHT:
    {
                   new->x = snake->_Snakebody->x+2;
                   new->y = snake->_Snakebody->y;
                   if (If_Food(snake->_Snakefood, new))
                   {
                       Eat_Food(snake, new);
                       snake->_TotalScore += snake->_AddScore;
                       //system("cls");
                       ScoreAndTips(snake);
                   }
                   else
                   {
                       Not_Eatfood(snake, new);
                   }

    }
        break;
    }
}


//按空格键暂停
void Pause()
{
    while (1)
    {
        Sleep(100);
        if (GetAsyncKeyState(VK_SPACE))
        {
            break;
        }
    }
}

//蛇撞到墙而死
void KillByWall(Snake* snake)
{
    int x = snake->_Snakebody->x;
    int y = snake->_Snakebody->y;
    if ((y == 0)||(y==29)||(x==0)||(x==58))
    {
        snake->Status = _KILLBYWALL;
    }

}

//蛇撞到自己而死
void KillBySelf(Snake* snake)
{
    Snakenode* cur = snake->_Snakebody->_next;
    int x = snake->_Snakebody->x;
    int y = snake->_Snakebody->y;
    while (cur)
    {
        if ((cur->x == x)&&(cur->y == y))
        {
            snake->Status = _KILLBYSELF;
            return;
        }
        cur = cur->_next;
    }

}

//加减分数
void ScoreAndTips(Snake* snake)
{
    Set_Pos(64,10); 
    printf("得分:%d ", snake->_TotalScore);
    Set_Pos(64, 11);
    printf("小 提 示");
    Set_Pos(64,12);
    printf("---------------------");
    Set_Pos(64, 13);
    printf("---------------------");
    Set_Pos(64, 14);
    printf("每个食物得分:%d分", snake->_AddScore);
    Set_Pos(64, 15);
    printf("不能穿墙,不能咬到自己");
    Set_Pos(64, 16);
    printf("用↑↓←→分别控制蛇的移动");
    Set_Pos(64, 17);
    printf("F1 为加速,F2 为减速");
    Set_Pos(64, 18);
    printf("space:暂停游戏");
    Set_Pos(64, 19);
    printf("ESC:退出游戏");
}

//游戏中...
void Game_Run(Snake* snake)
{
    do{
        Snake_Move(snake);
        Sleep(snake->_Time);
        KillByWall(snake);
        KillBySelf(snake);
        if (GetAsyncKeyState(VK_UP) && snake->_Dir != _DOWN){
            snake->_Dir = _UP;
        }
        else if (GetAsyncKeyState(VK_LEFT) && snake->_Dir != _RIGHT){
            snake->_Dir = _LEFT;
        }
        else if (GetAsyncKeyState(VK_RIGHT) && snake->_Dir != _LEFT){
            snake->_Dir = _RIGHT;
        }
        else if (GetAsyncKeyState(VK_DOWN) && snake->_Dir != _UP){
            snake->_Dir = _DOWN;
        }
        else if (GetAsyncKeyState(VK_SPACE)){
            Pause();
        }
        else if (GetAsyncKeyState(VK_F1)){
            if (snake->_Time <=1000 && snake->_TotalScore >= 0)
            {
                snake->_Time += 100;
                snake->_AddScore -= 1;
            }
        }
        else if (GetAsyncKeyState(VK_F2)){
            if (snake->_Time >=10 )
            {
                snake->_Time -= 100;
                snake->_AddScore += 1;
            }
        }
        else if (GetAsyncKeyState(VK_ESCAPE)){
            snake->Status = _OKEND;
        }
    } while (snake->Status == _OK);
}

//开始游戏
void Game_Start(Snake* snake)
{
    Welcom_To_Game();
    CreatMap();
    Init(snake);
    CreatFood(snake);
    //Set_Pos(62,15);
    snake->Status = _OK;
    snake->_AddScore = 10;
    snake->_Dir = _UP;
    snake->_Time = 500;
    snake->_TotalScore = 0;
    ScoreAndTips(snake);
}

//游戏结束
void Game_End()
{
    system("cls");
    Set_Pos(35, 15);
    printf("游戏结束\n");
    Set_Pos(35, 29);
    system("pause");
}

main.c

#define _CRT_SECURE_NO_WARNINGS 

#include"Snake.h"


void test() 
{

    Snake snake = { 0 };
    //设置食物的时间种子
    srand((unsigned)time(NULL));

    //开始游戏
    Game_Start(&snake);

    //游戏中....
    Game_Run(&snake);

    Game_End();
}
int main()
{
    test();

    //COORD pos = { 0 };
    //HANDLE handle = NULL;
    //system("mode con cols=100 lines=30");
    //handle = GetStdHandle(STD_OUTPUT_HANDLE);
    //pos.X = 50;
    //pos.Y = 15;
    //SetConsoleCursorPosition(handle, pos);//
    //printf("hehe\n");


    system("pause");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值