解决方案

C语言实现贪吃蛇[内附详细步骤]

seo靠我 2023-09-24 07:28:44

C语言贪吃蛇项目

今天给分享一下使用C语言写个贪吃蛇小游戏,主要包含以下10部分内容:

1、windows光标定位与隐藏

2、欢迎界面

3、打印围墙

4、产生食物

5、初始化蛇身

6、响应按键

7、蛇身运动

8、碰撞检SEO靠我

9、结束界面

10、程序运行

windows光标定位与隐藏

COORD 是window API中定义的一种结构体,表示一个字符在控制台屏幕上的坐标。定义为:

typedef struct_COORD{

SHOSEO靠我RT X;  横坐标

SHORT Y;  纵坐标

}COORD;

定位函数gotoxy,gotoDelete

void gotoprint(int x, int y)

{

    gotoxy(x, y);

printf(SEO靠我"■");

}

// 删除蛇尾

void gotoDelete(int x, int y)

{

    gotoxy(x, y);

    printf("  ");

}

2. 欢迎界面

使用gotoxy函数将光标定义到页面相应的位置输SEO靠我出欢迎信息,页面左上角为(0,0)坐标。

将用户输入的姓名信息保存下来以便后面使用。

用户输入姓名后清屏,进入游戏界面。

void welcome()

{

    gotoxy(10, 5);

printf("/****SEO靠我******************************************/");

    gotoxy(14, 8);

printf("WELCOME TO THE GAME OF RETRO SNASEO靠我KE");

    gotoxy(14, 12);

    printf("wasd控制蛇身上下左右运动,反向移动等同于吃到自己导致游戏结束,除了wasd任意键暂停");

    gotoxy(10, 20);

printf("/*SEO靠我*********************************************/");

    gotoxy(14, 16);

    printf("请输入姓名:");

scanf("%s",usernameSEO靠我);

    system("cls");        

}

​​​​​​​3.打印围墙

贪吃蛇围墙只需要定位到相应位置输出"■"即可,本次游戏的围墙为57*27

坐标图如下图所示:

void creatgraph()

{

int i;

/SEO靠我/ 横向围墙 58 / 2 == 29列

for (i = 0; i < 58; i += 2)

    {

        gotoprint(i, 0);

        gotoprint(i, 26);

    }

// 竖向围墙  1-25中间有25SEO靠我行 + 头尾两行  27行

    for (i = 1; i < 26; i++)

    {

        gotoprint(0, i);

        gotoprint(56, i);

    }

    // 游戏信息

gotoxy(60,5);

printf("SEO靠我hello,%s",username);

gotoxy(60,15);

printf("您当前的得分为:");

gotoxy(76,15);

printf("%d",score);

}

打印完后显示一下游戏信息。SEO靠我

注意:

汉字宽度是字符宽度的两倍,高度相等。即一个汉字占两个字节,一个英文字母占一个字节。

因此,"■"输出一次占两个字节,纵向上占一个字节,底部自身携带一些空隙。

​​​​​​​4.产生食物

1、构造食物

sSEO靠我truct Food

{

    int x;

    int y;

}food;

2、定位食物

保证食物必须在围墙内:

x坐标范围: [2,54] -- 并且只要偶数部分,不是偶数部分需要转化为接近的偶数

y坐标范围: [1,25SEO靠我]

保证食物和蛇身没有重合,如果重合需要再次生成新的位置。

3、输出食物

void creatfood()

{

// 随机产生一个食物的位置

int flag = 0;

while(!flag)

{

srand((unSEO靠我signed int)time(NULL));

food.y = rand() % 25 + 1; // [1,25]

food.x = rand() % 53 + 2; // [2,54] -- 只要偶SEO靠我数部分

if(food.x % 2 != 0)

{

food.x = food.x+1; // 不是偶数部分转化为接近的偶数

}

// 不能与蛇身重复

snake *p = head;

while(p)

{

if(p-SEO靠我>x == food.x && p->y == food.y)

{

// 重复 -- 重新生成坐标

break;

}

p = p->next;

}

flag = 1;  

}

gotoxy(food.x, food.y);SEO靠我

    printf("吃");

}

​​​​​​​5.初始化蛇身

蛇身构造

typedef struct Snakes

{

    int x;

    int y;

    struct Snakes* next;

}snake;

snake* hSEO靠我ead;    // 声明蛇头指针

绘制初始化的蛇身

void initSnake()

{

head = (snake*)malloc(sizeof(snake));

snake* p = (snake*)maSEO靠我lloc(sizeof(snake));

    snake* q = (snake*)malloc(sizeof(snake));

    head->x = 16;

    head->y = 15;    

    p->x = 16;

p->SEO靠我y = 16;

    q->x = 16;

    q->y = 17;

    head->next = p;

    p->next = q;

    q->next = NULL;

    //绘制初始蛇身

gotoprint(16,15);

gotoprSEO靠我int(16,16);

gotoprint(16,17);    

}

​​​​​​​6.响应按键

getch()为输入字符函数,但是是阻塞的,如果用户不输入进步向下进行,不满足蛇身自动向前运动的需求,因此替换为_kSEO靠我bhit()进行非阻塞的输入监听,监听到键盘输入后,使用_getch从缓冲区中将输入的字符读出来放入全局变量ch中。

另外,当程序执行时,循环一次需要进行一次碰撞检测,没有碰撞时,还需要进行蛇身的移动。SEO靠我

int clickControl()

{

while(1)

{

// 检测是否碰撞边界

if(collisionDetect() == 1) return 0;

// _kbhit监听键盘有输入-非阻塞

if(_kSEO靠我bhit())

{

ch = _getch();  

}

// 移动身体

movingBody();  

}

return 1;

}

​​​​​​​7.蛇身运动

蛇身运动即:消除蛇尾节点,根据按键方向确定好新节点坐标,将新节点添SEO靠我加到蛇头位置即可。

移动后可以加一些延迟,使用Sleep(xx); xx以ms为单位。

void movingBody()

{

// 坐标修改

int x = head->x;

int y = head->y;

sSEO靠我witch(ch)

{

case UP:

y-=1;

break;

case DOWN:

y+=1;

break;

case LEFT:

x-=2;

break;

case RIGHT:

x+=2;

break;

defaultSEO靠我:

ch = 0;

break;

}

if(ch)

{

// 消除尾节点

snake *p = head;

while(p->next->next != NULL)

{

p = p->next;

}

snake *q = pSEO靠我->next;

gotoDelete(q->x,q->y);

free(q);

p->next = NULL;

// 新坐标结点置为头结点

snake* newNode = (snake*)malloc(sizSEO靠我eof(snake));

newNode->x = x;

newNode->y = y;

newNode->next = head;

head = newNode;

// 绘制蛇头

gotoprint(x,y);SEO靠我

// 延迟

Sleep(500);

}

}

注意:如果用户输入的是除了 wasd以外的按键则暂停游戏。

​​​​​​​8.碰撞检测

碰撞检测主要有三种:

蛇身和边界蛇头和蛇身蛇头碰到食物

                重新生成一个食物

在蛇身后面添SEO靠我加一个尾巴,可以不给x,y,因为下次移动的时候会直接将它释放掉。

                加分

                在分值位置更新分数

int collisionDetect()

{

// 检测蛇头和边界

if(head->x == 0 || head->SEO靠我x == 56 || head->y == 0 || head->y == 26)

{

Finish();

return 1;

}

// 蛇头和蛇身

snake *p = head->next;

while(p !SEO靠我= NULL)

{

if(head->x == p->x && head->y == p->y)

{

// 碰撞-结束

Finish();

return 1;

}

p = p->next;

}

// 碰到食物

if(heaSEO靠我d->x == food.x && head->y == food.y)

{

creatfood();

// 添加一个尾巴

snake* newNode = (snake*)malloc(sizeof(snaSEO靠我ke));

newNode->next = NULL;

snake *p = head;

while(p->next != NULL)

{

p = p->next;

}

p->next = newNode;

scorSEO靠我e += 10;

gotoxy(76,15);

printf("%d",score);

}

return 0;

}

​​​​​​​9.结束界面

清屏

显示用户名和得分

void Finish()

{

system("clsSEO靠我");

    gotoxy(10, 10);

    printf("/**********************************************/");

    gotoxy(10, 20);

printf("SEO靠我/**********************************************/");

    gotoxy(15, 14);

printf("GAME   OVER      o(* ̄▽ ̄*)oSEO靠我");

    gotoxy(18, 16);

    printf("%s,    你的得分 %d ",username, score);

    gotoxy(15, 18);

printf("还不错哦,     继续努力O(∩SEO靠我_∩)O");

    gotoxy(0, 27);

    // 释放空间

    snake* p = head, *q;

    while (p != NULL) {

        q = p->next;

        free(p);

        p = q;

    }

systemSEO靠我("pause");

}

​​​​​​​10.运行程序

int main()

{

welcome();

creatgraph();

creatfood();

initSnake();

clickControl();

reSEO靠我turn 0;

}

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2