CLION 基于Easyx的贪吃蛇小游戏(链表)

   

目录

一、定义

1.蛇的属性定义:

2.定义食物

3.定义全局变量——蛇头,食物(apple),屏幕尺寸,按键操作

二、蛇的函数编写

1.蛇初始化

2.画蛇

3.增加蛇的长度

4.蛇动

5.按键控制

6.蛇死判定(以及穿墙处理)

三、食物(apple)的函数编写

1.画食物

2.食物初始化

3.食物刷新

4.蛇吃食物增加长度

5.分数显示

四、完整代码

五、运行结果

六、小结


        填坑:之前写过用数组实现贪吃蛇,现在使用单链表实现贪吃蛇小游戏。

完整代码在末尾,直接复制即可运行

一、定义

1.蛇的属性定义:

typedef struct Snake{
    int x;
    int y;
    char dir;
    Snake* next;
}snake;

2.定义食物

typedef struct Food{
    int x;
    int y;
    int flag;
    int grade;
}food;

3.定义全局变量——蛇头,食物(apple),屏幕尺寸,按键操作

#define screen_long 640//x
#define screen_width 480//y

#define up 87//W
#define down 83//S
#define left 65//A
#define right 68//D

snake* head;
food apple;

二、蛇的函数编写

1.蛇初始化

void Snake_Init(void )
{
    snake *body1;
    snake *body2;
    snake *body3;

    head=(snake*) malloc (sizeof (snake));
    body1=(snake*) malloc(sizeof (snake));
    body2=(snake*) malloc(sizeof (snake));
    body3=(snake*) malloc(sizeof (snake));

    head->next=body1;
    body1->next=body2;
    body2->next=body3;
    body3->next=NULL;
    body1->dir=right;
    body2->dir=right;
    body3->dir=right;
    head->dir=up;
    body1->x=screen_long/2+20;
    body1->y=screen_width/2;
    body2->x=screen_long/2+10;
    body2->y=screen_width/2;
    body3->x=screen_long/2;
    body3->y=screen_width/2;
    head->x=screen_long/2+30;
    head->y=screen_width/2;
}

2.画蛇

void Snake_Draw(void )
{
    snake *p=head;
    setlinecolor(RGB(0 ,134 ,139));
    setfillcolor(RGB(0 ,250 ,0));
    fillrectangle(p->x,p->y,p->x+10,p->y+10);

    setlinecolor(RGB(0 ,134 ,139));
    setfillcolor(RGB(0 ,200 ,0));
    while(p->next!=NULL)
    {
        p=p->next;
        fillrectangle(p->x,p->y,p->x+10,p->y+10);
    }
}

3.增加蛇的长度

snake *Snake_Create(void )
{
    snake *p;
    p=(snake*) malloc(sizeof (snake));
    p->x=0;
    p->y=0;
    p->dir=0;
    p->next=NULL;
    return p;
}

4.蛇动

void Snake_Move(void )
{
    snake *p=head;
    snake *q=head;
    while (p->next!=NULL)
    {
        q=p;
        p=p->next;
    }
    free(p);
    q->next=NULL;
    snake *new_head=Snake_Create();
    switch (head->dir) {
        case up:
            new_head->x=head->x;
            new_head->y=head->y-10;
            break;
        case down:
            new_head->x=head->x;
            new_head->y=head->y+10;
            break;
        case right:
            new_head->x=head->x+10;
            new_head->y=head->y;
            break;
        case left:
            new_head->x=head->x-10;
            new_head->y=head->y;
            break;
    }
    new_head->dir=head->dir;
    new_head->next=head;
    head=new_head;
}

5.按键控制

void Key_Control(void )
{
    char KeyNum;
    KeyNum=getch();
    switch (head->dir)
    {
        case right:
            if (KeyNum==up)
                head->dir=up;
            else
                head->dir=down;
            break;
        case left:
            if (KeyNum==up)
                head->dir=up;
            else
                head->dir=down;
            break;
        case up:
            if (KeyNum==right)
                head->dir=right;
            else
                head->dir=left;
            break;
        case down:
            if (KeyNum==right)
                head->dir=right;
            else
                head->dir=left;
            break;
    }
}

6.蛇死判定(以及穿墙处理)

void Snake_Die(void )
{

    snake *p=head->next;
   while(p->next!=NULL)
   {
       if((head->x==p->x)&&(head->y==p->y))
       {
           outtextxy(200,200,"eat yourself!");
           MessageBox(hwnd,"Game Over!","eat yourself",MB_OK);
           Snake_Init();
           apple.grade=0;
       } else{
           p=p->next;
       }
   }

    if(head->x>screen_long)
    {
        head->x=head->x-screen_long-10;
    } else if (head->y>screen_width)
    {
        head->y=head->y-screen_width-10;
    }else if (head->x<0)
    {
        head->x=head->x+screen_long;
    }else if (head->y<0)
    {
        head->y=head->y+screen_width;
    }

}

三、食物(apple)的函数编写

1.画食物

void Apple_Draw(void )
{
    setlinecolor(RGB(250 ,0 ,0));
    setfillcolor(RGB(255 ,0 ,0));
    fillrectangle(apple.x,apple.y,apple.x+10,apple.y+10);
}

2.食物初始化

void Apple_Init(void)
{
    apple.x=rand()%(screen_long/10)*10;
    apple.y=rand()%(screen_width/10)*10;
    apple.flag=1;
    apple.grade=0;
    Apple_Draw();
}

3.食物刷新

void Apple_Refresh(void)
{

    Apple_Draw();
    if(apple.flag==0)
    {
        apple.grade+=10;
        apple.x=rand()%(screen_long/10)*10;
        apple.y=rand()%(screen_width/10)*10;
        apple.flag=1;
    }
}

4.蛇吃食物增加长度

void Food_Eat(void)
{
    if((head->x==apple.x)&&(head->y==apple.y))
    {
        snake *q=Snake_Create();
        apple.flag=0;
        snake *p=head;
        while (p->next!=NULL)
        {
            p=p->next;
        }
//        switch (head->dir) {
//            case up:
//                q->x=p->x;
//                q->y=p->y+10;
//                break;
//            case down:
//                q->x=p->x;
//                q->y=p->y-10;
//                break;
//            case right:
//                q->x=p->x-10;
//                q->y=p->y;
//                break;
//            case left:
//                q->x=p->x+10;
//                q->y=p->y;
//                break;
//        }
        p->next=q;
    }
}

5.分数显示

void Grade_Show(void )
{
    char grade[100]="";
    sprintf(grade,"%d",apple.grade);
    settextcolor(RGB(0 ,150 ,150));
    outtextxy(screen_long-100,20,"Grade:");
    outtextxy(screen_long-40,20,grade);
}

四、完整代码

#include 		// 引用图形库头文件
#include 
#include "stdio.h"
#include "time.h"
#include "stdlib.h"

#define screen_long 640//x
#define screen_width 480//y

#define up 87//W
#define down 83//S
#define left 65//A
#define right 68//D

HWND hwnd=NULL;
typedef struct Food{
    int x;
    int y;
    int flag;
    int grade;
}food;
typedef struct Snake{
    int x;
    int y;
    char dir;
    Snake* next;
}snake;
snake* head;
food apple;
void Snake_Init(void )
{
    snake *body1;
    snake *body2;
    snake *body3;

    head=(snake*) malloc (sizeof (snake));
    body1=(snake*) malloc(sizeof (snake));
    body2=(snake*) malloc(sizeof (snake));
    body3=(snake*) malloc(sizeof (snake));

    head->next=body1;
    body1->next=body2;
    body2->next=body3;
    body3->next=NULL;
    body1->dir=right;
    body2->dir=right;
    body3->dir=right;
    head->dir=up;
    body1->x=screen_long/2+20;
    body1->y=screen_width/2;
    body2->x=screen_long/2+10;
    body2->y=screen_width/2;
    body3->x=screen_long/2;
    body3->y=screen_width/2;
    head->x=screen_long/2+30;
    head->y=screen_width/2;
}
void Snake_Draw(void )
{
    snake *p=head;
    setlinecolor(RGB(0 ,134 ,139));
    setfillcolor(RGB(0 ,250 ,0));
    fillrectangle(p->x,p->y,p->x+10,p->y+10);

    setlinecolor(RGB(0 ,134 ,139));
    setfillcolor(RGB(0 ,200 ,0));
    while(p->next!=NULL)
    {
        p=p->next;
        fillrectangle(p->x,p->y,p->x+10,p->y+10);
    }
}
snake *Snake_Create(void )
{
    snake *p;
    p=(snake*) malloc(sizeof (snake));
    p->x=0;
    p->y=0;
    p->dir=0;
    p->next=NULL;
    return p;
}
void Snake_Move(void )
{
    snake *p=head;
    snake *q=head;
    while (p->next!=NULL)
    {
        q=p;
        p=p->next;
    }
    free(p);
    q->next=NULL;
    snake *new_head=Snake_Create();
    switch (head->dir) {
        case up:
            new_head->x=head->x;
            new_head->y=head->y-10;
            break;
        case down:
            new_head->x=head->x;
            new_head->y=head->y+10;
            break;
        case right:
            new_head->x=head->x+10;
            new_head->y=head->y;
            break;
        case left:
            new_head->x=head->x-10;
            new_head->y=head->y;
            break;
    }
    new_head->dir=head->dir;
    new_head->next=head;
    head=new_head;
}
void Key_Control(void )
{
    char KeyNum;
    KeyNum=getch();
    switch (head->dir)
    {
        case right:
            if (KeyNum==up)
                head->dir=up;
            else
                head->dir=down;
            break;
        case left:
            if (KeyNum==up)
                head->dir=up;
            else
                head->dir=down;
            break;
        case up:
            if (KeyNum==right)
                head->dir=right;
            else
                head->dir=left;
            break;
        case down:
            if (KeyNum==right)
                head->dir=right;
            else
                head->dir=left;
            break;
    }
}

void Apple_Draw(void )
{
    setlinecolor(RGB(250 ,0 ,0));
    setfillcolor(RGB(255 ,0 ,0));
    fillrectangle(apple.x,apple.y,apple.x+10,apple.y+10);
}
void Apple_Init(void)
{
    apple.x=rand()%(screen_long/10)*10;
    apple.y=rand()%(screen_width/10)*10;
    apple.flag=1;
    apple.grade=0;
    Apple_Draw();
}
void Apple_Refresh(void)
{

    Apple_Draw();
    if(apple.flag==0)
    {
        apple.grade+=10;
        apple.x=rand()%(screen_long/10)*10;
        apple.y=rand()%(screen_width/10)*10;
        apple.flag=1;
    }
}

void Food_Eat(void)
{
    if((head->x==apple.x)&&(head->y==apple.y))
    {
        snake *q=Snake_Create();
        apple.flag=0;
        snake *p=head;
        while (p->next!=NULL)
        {
            p=p->next;
        }
//        switch (head->dir) {
//            case up:
//                q->x=p->x;
//                q->y=p->y+10;
//                break;
//            case down:
//                q->x=p->x;
//                q->y=p->y-10;
//                break;
//            case right:
//                q->x=p->x-10;
//                q->y=p->y;
//                break;
//            case left:
//                q->x=p->x+10;
//                q->y=p->y;
//                break;
//        }
        p->next=q;
    }
}
void Grade_Show(void )
{
    char grade[100]="";
    sprintf(grade,"%d",apple.grade);
    settextcolor(RGB(0 ,150 ,150));
    outtextxy(screen_long-100,20,"Grade:");
    outtextxy(screen_long-40,20,grade);
}
void Snake_Die(void )
{

    snake *p=head->next;
   while(p->next!=NULL)
   {
       if((head->x==p->x)&&(head->y==p->y))
       {
           outtextxy(200,200,"eat yourself!");
           MessageBox(hwnd,"Game Over!","eat yourself",MB_OK);
           Snake_Init();
       } else{
           p=p->next;
       }
   }

    if(head->x>screen_long)
    {
        head->x=head->x-screen_long-10;
    } else if (head->y>screen_width)
    {
        head->y=head->y-screen_width-10;
    }else if (head->x<0)
    {
        head->x=head->x+screen_long;
    }else if (head->y<0)
    {
        head->y=head->y+screen_width;
    }

}
int main(void )
{
    hwnd = initgraph(screen_long, screen_width);
    srand((unsigned int) time(NULL));
    setbkcolor(WHITE);
    cleardevice();
    Snake_Init();
    Apple_Init();
    while(1)
    {
        while (kbhit())
        {
            Key_Control();
        }
        Snake_Die();
        Grade_Show();
        Food_Eat();
        Apple_Refresh();
        Snake_Draw();
        Snake_Move();
        Sleep(100);
        cleardevice();
    }

    getch();
}

五、运行结果

六、小结

        链表比直接使用数组进行开发难度高一点,但顺便复习了数据结构的知识,尤其是在蛇运动的时候,将最后一个节点删除,并新加一个节点在蛇头,并把新加的节点变成蛇头的操作是最困难的。这也是本次小项目所学习到的点。

源码自取:

链接:https://pan.baidu.com/s/1N5PeeNeQ68MbHPYZqyoSEQ 
提取码:3947

你可能感兴趣的:(链表,数据结构)