Easy Game----Snake Snake

Design ideas:

  1. Interface settings: use the system() function to adjust the size and background color of the interface
  2. Draw a map: use library functions to obtain coordinates (detailed below)
  3. Snake Design: Implementing a Snake with a Chained Structure
  4. Food design: rand() randomly generates food coordinates
  5. The movement of snakes: The implementation of snake movement adopts linked list related operations, which are described in detail below.
  6. Direction control: Use the GetAsyncKeyState() function to operate the direction of the snake's movement through the keyboard
  7. Snake moving speed: Use the Sleep() function to control the snake moving speed

Specific functions:

  1. Increase own speed: Accelerate for every 5 points increase in score
  2. Artificial acceleration: press the shift key to accelerate
  3. Artificial deceleration: Press the Ctrl key to decelerate
  4. Pause: Press the space bar to pause the game, press it once to resume the game
  5. Exit: Press the Esc key during the game to exit the game

Several functions:

1.system
(only the commands used in the game are described here, for details, please click the link http://blog.csdn.net/s200820212/article/details/32695369 )

Function: Issue a DOS
command Usage: int system(char *command);
The system function has been included in the standard c library and can be called directly
Program example:

 #include <stdlib.h>   
 #include <stdio.h>   
 int main(void)   
 {
  printf("About to spawn command.com and run a DOS command\n");   system("dir");   
  return 0;   
  }

system("pause")
freezes the screen, which is convenient for observing the execution result of the program;
system("CLS")
realizes the screen-clearing operation.
The system calls the color function to change the foreground color and background of the console. The specific parameters are described below.
For example, use system("color 0A"); where 0 after color is the background color code, and A is the foreground color code. The color codes are as follows:

0=black1      
=blue2      
=green3      
=lake blue4   
=   
red5 =purple6=
yellow7 =
white8 =
grey9
=light blue
A=light green
B=light green
C=light red
D= Lavender
E=Light yellow
F=Bright white

2.SetConsoleCursorPosition

write picture description here

Explanation: Set the console cursor coordinates, the parameters are the device handle, coordinates, then pass the standard output handle to the function, you can position the cursor at the corresponding position (the upper left corner position is 0,0 and then extends left and down)

CROOD:

typedef struct _COORD {
SHORT X;
SHORT Y;
} COORD, *PCOORD;

Obviously this structure can be used to record the coordinate
HANDLE:

A handle to receive the handle returned by GetHandle()

3.GetStdHandle

The function declaration is as follows:

  HANDLE GetStdHandle(
  DWORD nStdHandle
  );

  GetStdHandle() returns the handle of the standard input, output or error device, that is, the handle of the screen buffer for getting input, output/error.
  The value of its parameter nStdHandle is one of the following types:

   Value Meaning
  STD_INPUT_HANDLE Standard input handle
  STD_OUTPUT_HANDLE Standard output handle
  STD_ERROR_HANDLE Standard error handle

4. GetAsyncKeyState()
click the link below
http://blog.csdn.net/fengfengfengmy/article/details/5570330

Game code:

Snake.h

#ifndef __SNAKE_H__
#define __SNAKE_H__

#define FOOD "■"
#define INIT_X  24//蛇的初始位置
#define INIT_Y   4

#define STARTSPEED  500//开始速度
#define SPEDGRADE   5//加速分数  
#define  STARTLENTH  5//开始蛇的长度


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




//蛇走的方向
enum DIRECTION
{
    UP = 1,//上
    DOWN,//下
    LEFT,//左
    RIGHT,//右

};


//蛇的状态

enum Status
{
    OK,//活的
    KILL_BY_WALL,//撞墙
    KILL_BY_SELF,//自己咬死
};

//蛇身节点
typedef struct Node
{
    int x;
    int y;
    struct Node* next;
}SnakeNode;



//蛇本身
typedef struct snake
{
    SnakeNode* _pSnake;//蛇头指针
    SnakeNode* _food;//蛇的食物
    enum DIRECTION _Dir;//行走方向
    enum Status _Status;//当前状态
    int _SleepTime;//每走一步停留的时间
    int _Length;//蛇的长度
}Snake;





void StartMenu();//开始界面
void DrawMap();//地图
void SetPos(int x, int y);//设置光标
void InitSnake(Snake* ps);//初始化蛇结构体
void InitFood(Snake*  ps);//初始化食物
int IsFood(SnakeNode* ps, SnakeNode* NewSnake);//判断是否有食物
void SnakeMove(Snake* ps);//蛇的移动
void EatFood(Snake* ps, SnakeNode* NewSnake);//吃食物
void NoFood(Snake* ps, SnakeNode* NewSnake);//没食物
void SnakeRun(Snake* ps);//方向选择
int KillBySelf(Snake* ps);//判断是否撞到自己身上
int KillByWALL(Snake* ps);//判断是否撞墙

#endif   //__SNAKE_H__

Snake.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"snake.h"


//设置光标位置
void SetPos(int x, int y)
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);


    COORD pos = { 0 };
    pos.X = x;
    pos.Y = y;

    SetConsoleCursorPosition(handle, pos);
}



//开始界面
void StartMenu()
{

    system("COLOR f3");//设置背景颜色
    system("mode con cols=120 lines=35");//设置显示框大小

    SetPos(33, 10);
    printf("******************************");
    SetPos(33, 12);
    printf("*   欢迎来到贪吃蛇游戏!     *");
    SetPos(33, 14);
    printf("******************************");

    SetPos(33, 18);
    system("pause");
    system("cls");


    SetPos(33, 10);
    printf("************************************");
    SetPos(33, 12);
    printf("*  选项:1->开始游戏    0->退出    *");
    SetPos(33, 14);
    printf("*  操作:↑ ↓ ← →控制方向       *");
    SetPos(33, 16);
    printf("*   按空格暂停/继续,ESC退出       *");
    SetPos(33, 18);
    printf("*   按shift加速,Ctrl减速          *");
    SetPos(33, 20);
    printf("************************************");

    SetPos(33, 22);
    system("pause");
    system("cls");



}



//地图
void DrawMap()
{
    int i;
    //上面边框
    for (i = 0; i < 70; i += 2)
    {
        SetPos(i, 0);
        printf(FOOD);
    }


    //下面边框
    for (i = 0; i < 70; i += 2)
    {
        SetPos(i, 30);
        printf(FOOD);
    }

    //左边边框
    for (i = 0; i < 30; i++)
    {
        SetPos(0, i);
        printf(FOOD);
    }

    //右边边框
    for (i = 0; i <= 30; i++)
    {
        SetPos(70, i);
        printf(FOOD);
    }
    printf("\n");

    SetPos(76, 5);
    printf("   计分:");
    SetPos(85, 5);
    printf("%d ", 0);//每次吃完食物更新分数
}



//初始化蛇结构体
void InitSnake(Snake* ps)
{
    SnakeNode* cur = NULL;
    int i = 0;

    cur = (SnakeNode*)malloc(sizeof(SnakeNode));
    memset(cur, 0, sizeof(SnakeNode));

    cur->x = INIT_X;
    cur->y = INIT_Y;

    for (i = 1; i <= 4; i++)
    {
        ps->_pSnake = malloc(sizeof(SnakeNode));
        ps->_pSnake->next = cur;
        ps->_pSnake->x = INIT_X + i * 2;
        ps->_pSnake->y = INIT_Y;
        cur = ps->_pSnake;
    }

    while (cur != NULL)
    {
        SetPos(cur->x, cur->y);
        printf(FOOD);
        cur = cur->next;
    }


    ps->_Status = OK;
    ps->_SleepTime = STARTSPEED;
    ps->_Dir = RIGHT;
    ps->_Length = STARTLENTH;
}

//初始化食物
void InitFood(Snake*  ps)
{
    SnakeNode* food = NULL;
    food = (SnakeNode*)malloc(sizeof(SnakeNode));

flag:
    memset(food, 0, sizeof(SnakeNode));
    do
    {
        food->x = rand() % 70 + 2;
    } while (food->x % 2 != 0);

    food->y = rand() % 29 + 1;

    SnakeNode* cur = ps->_pSnake;

    while (cur != NULL)
    {
        if (cur->x == food->x&&cur->y == food->y)
        {
            goto flag;
        }

        cur = cur->next;
    }

    ps->_food = food;
    SetPos(food->x, food->y);
    printf(FOOD);

}




//蛇的移动
int IsFood(SnakeNode* food, SnakeNode* NewSnake)
{
    if (food->x == NewSnake->x && food->y == NewSnake->y)
        return 1;

    return 0;
}

//吃食物
void EatFood(Snake* ps, SnakeNode* NewSnake)
{


    int sum = SPEDGRADE;//加速分数,每增加5加速
    //头插
    SnakeNode* cur = ps->_pSnake;
    NewSnake->next = cur;
    cur = NewSnake;

    ps->_pSnake = NewSnake;

    while (cur != NULL)
    {
        SetPos(cur->x, cur->y);

        printf(FOOD);
        cur = cur->next;
    }


    ++ps->_Length;

        int grade = ps->_Length-STARTLENTH;//分数
        SetPos(85, 5);
        printf("%d ", grade);//每次吃完食物更新分数


    if (grade == sum)
    {
        //分数每增加5分,加速
        ps->_SleepTime -= 100;
        sum += SPEDGRADE;

    }

    InitFood(ps);
}

//没食物
void NoFood(Snake* ps, SnakeNode* NewSnake)
{


    //先头插,后尾删
    SnakeNode* cur = ps->_pSnake;
    NewSnake->next = cur;
    ps->_pSnake = NewSnake;

    cur = NewSnake;

    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(Snake* ps)
{
    Sleep(ps->_SleepTime);

    SnakeNode* NewSnake = (SnakeNode*)malloc(sizeof(SnakeNode));
    memset(NewSnake, 0, sizeof(SnakeNode));

    NewSnake->x = ps->_pSnake->x;
    NewSnake->y = ps->_pSnake->y;


    switch (ps->_Dir)
    {
    case UP:
        NewSnake->y--;
        break;
    case DOWN:
        NewSnake->y++;
        break;
    case LEFT:
        NewSnake->x -= 2;
        break;
    case RIGHT:
        NewSnake->x += 2;
        break;
    default:
        break;
    }
    int ret = IsFood(ps->_food, NewSnake);

    if (ret == 1)
    {
        //有食物
        EatFood(ps, NewSnake);
    }
    else
    {
        NoFood(ps, NewSnake);
    }


}


//控制方向
void SnakeRun(Snake* ps)
{

    do
    {
        if (GetAsyncKeyState(VK_LEFT) && ps->_Dir != LEFT)
        {
            ps->_Dir = LEFT;
        }
        else if (GetAsyncKeyState(VK_RIGHT) && ps->_Dir != RIGHT)
        {
            ps->_Dir = RIGHT;
        }
        else if (GetAsyncKeyState(VK_UP) && ps->_Dir != UP)
        {
            ps->_Dir = UP;
        }
        else if (GetAsyncKeyState(VK_DOWN) && ps->_Dir != DOWN)
        {
            ps->_Dir = DOWN;
        }
        else if (GetAsyncKeyState(VK_ESCAPE))//esc键正常退出
        {
            exit(0);
        }
        else if (GetAsyncKeyState(VK_SPACE))//空格暂停或继续
        {
            while (1)
            {
                Sleep(300);
                if (GetAsyncKeyState(VK_SPACE)) //按空格键继续
                {
                    break;
                }

            }
        }
        else if (GetAsyncKeyState(VK_CONTROL))//Ctrl键减速
        {
            ps->_SleepTime += 100;
        }
        else if (GetAsyncKeyState(VK_SHIFT))//shift键加速
        {
            ps->_SleepTime -= 100;
        }

        SnakeMove(ps);

        if (KillBySelf(ps) == 1)
        {
            ps->_Status = KILL_BY_SELF;
        }

        if (KillByWALL(ps) == 2)
        {
            ps->_Status = KILL_BY_WALL;
        }
    } while (ps->_Status == OK);




}

//判断是否撞到自己身上
int KillBySelf(Snake* ps)
{
    SnakeNode* cur = ps->_pSnake->next;

    while (cur != NULL)
    {
        if (ps->_pSnake->x == cur->x&&ps->_pSnake->y == cur->y)
        {
            return 1;
        }
        cur = cur->next;
    }
    return 0;
}

//判断是否撞墙
int KillByWALL(Snake* ps)
{
    SnakeNode* cur = ps->_pSnake;

    if (cur->x == 0 || cur->x == 70 || cur->y == 0 || cur->y == 30)
        return 2;

    return 0;
}

test.c

#include<stdio.h>

#include"snake.h"


void play()
{
    Snake snake = { 0 };
    DrawMap();//地图
    InitSnake(&snake);//初始化蛇
    InitFood(&snake);//初始化食物
    while (snake._Status == OK)
    {

        SnakeMove(&snake);
        SnakeRun(&snake);
    }
    int grade = snake._Length - STARTLENTH;//获取游戏结束后的分数

    if (snake._Status == KILL_BY_SELF)
    {

            SetPos(34, 10);
            printf("Game Over\n");
            SetPos(34, 12);
            printf("本次得分为:%d\n",grade);
            SetPos(34, 14);
            system("pause");
    }

    if (snake._Status == KILL_BY_WALL)
    {

        SetPos(34, 10);
        printf("Game Over\n");

        SetPos(34, 12);
        printf("本次得分为:%d\n", grade);

        SetPos(34, 14);
        system("pause");
    }
}

void game()
{


    while (1)
    {
        StartMenu();
        int input = 0;
        SetPos(77, 5);
        printf("请选择:");
        scanf("%d", &input);
        system("cls");
        if (1 == input)
        {
            play();
        }
        else if (0 == input)
        {
            exit(0);
        }

    }
}


int main()
{
    game();
    return 0;
}

Show results:

Start interface:

write picture description here

Hit the wall and die, the game is over:

write picture description here

Bump yourself, game over:

write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325805546&siteId=291194637