贪吃蛇—C语言

本文介绍了一个使用C语言实现的贪吃蛇游戏源代码。该程序利用Windows API进行图形界面操作,通过键盘输入控制蛇的移动方向,并实现了碰撞检测、计分等功能。文章详细展示了如何初始化游戏界面、蛇的位置更新及食物生成等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

游戏运行时

游戏结束时

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<windows.h>
#include<time.h>
#define UP    72
#define DOWN  80        //上下左右
#define LEFT  75
#define RIGHT 77
#define SPACE 32
#define ESC 27  
#define KONG 0  
#define WALL 1  
#define FOOD 2  
#define BODY 3
#define SIZE_X 23   //围墙尺寸大小
#define SIZE_Y 30
void gotoxy(int x,int y);   //移动光标
void hidden_cursor();   //隐藏光标
int color(int c);   //颜色
void inter_face();  //初始化界面
void init_snake();  //初始化蛇
void draw_snake(int x);  //x=1画蛇 x=0空格
void rand_food();   //生成食物
void move_snake(int x,int y); //移动
void run(int x,int y,int *time_count);//运行
void pd();          //判断游戏结束,吃到食物
void game();
void MaxGrade();//最高纪录
int map[SIZE_X][SIZE_Y];
int speed=1000;  
int food;
int grade=0;
int max_grade=0;
const int snake_color=11;
const int wall_color=2;
const int food_color=12;
struct Snake    //蛇 
{   int len;    //长度
    int x;
    int y;      //蛇头坐标
}snake;
struct Body    //身体节点
{   int x;
    int y;
};
struct Body body[SIZE_X*SIZE_Y];
int main()
{   
    system("title 贪吃蛇");
    system("cls");
    system("mode con cols=84 lines=26"); //设置窗口尺寸
    srand(time(NULL));  //随机数
    hidden_cursor();
    grade=0;
    MaxGrade();
    inter_face();
    init_snake();
    rand_food();
    draw_snake(1);
    game();
    return 0;
}

///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
void game()         //移动控制
{   
    int n=RIGHT,time_count=0,n_tmp;
    goto loop;
    while(1)
    {
        n=getch();
        switch(n)
        {
        case UP:    
        case DOWN:  if(n_tmp!=LEFT && n_tmp!=RIGHT) n=n_tmp;break;
        case LEFT:  
        case RIGHT: if(n_tmp!=UP && n_tmp!=DOWN) n=n_tmp;break;
        case 'r':
        case 'R':
        case SPACE:
        case ESC: break;
        default: n=n_tmp;break;    //其他键无效
        }
        loop:
        switch(n)
        {
         case UP:if(snake.x-1!=body[0].x)
                 {      run(-1,0,&time_count);
                        n_tmp=UP;
                 }
                break;
         case DOWN: if(snake.x+1!=body[0].x)
                    {   run(1,0,&time_count);
                        n_tmp=DOWN;
                    }
                  break;
         case LEFT: if(snake.y-1!=body[0].y)
                    {
                        run(0,-1,&time_count);
                        n_tmp=LEFT;
                    }
                 break;
         case RIGHT: if(snake.y+1!=body[0].y)
                     {
                        run(0,1,&time_count);
                        n_tmp=RIGHT;
                     }
                 break;
         case  SPACE: while(1)
                      {
                        if(kbhit!=0)
                            break;
                      }
                      break;
         case ESC:  gotoxy(SIZE_X+1,0);
                    printf("按任意键退出游戏!");
                    getch();
                    exit(0);
                    break;
         case 'r':
         case 'R': main();break;
        }
    }
}
void run(int x,int y,int *time_count)
{
    int t=0;
    while(1)
    {
        if(*time_count==0)
            *time_count=speed;
        while(--(*time_count))
        {
            if(t==0)
                t=50000;
            while(--t);
            if(kbhit()!=0)
                break;
        }
        if(*time_count==0)
        {
            move_snake(x,y);
            pd();
        }
        else
          break;
    }
}
void pd()//判断是否撞墙或者撞到身体
{
    if(map[snake.x][snake.y]==WALL || map[snake.x][snake.y]==BODY)
    {
        char n;
        Sleep(2000); //延时
        system("cls");
        gotoxy(SIZE_X/2-2,2*(SIZE_Y/3));
        if(grade>max_grade)
            printf("恭喜您打破记录,目前最高纪录为:%d",grade);
        else if(grade==max_grade)
            printf("与纪录持平,请突破你的极限!");
        else
            printf("请继续努力,你与最高记录只差:%d",max_grade-grade);
        gotoxy(SIZE_X/2,2*(SIZE_Y/3));
        printf("GAME OVER!\n");
        MaxGrade();
        do
        {
            gotoxy(SIZE_X/2+2,2*(SIZE_Y/3));
            printf("是否重新开始游戏(y/n): ");
            scanf("%c",&n);
            gotoxy(SIZE_X/2+4,2*(SIZE_Y/3));
            if(n!='n' && n!='N' && n!='y' && n!='Y')
                printf("输入错误,请重新输入!");
            else
                break;
        }while(1);
        if(n=='n' || n=='N')
        {
            gotoxy(SIZE_X/2+4,2*(SIZE_Y/3));
            printf("按任意键退出游戏!");
            exit(0);
        }
        else if(n=='y' || n=='Y')
            main();
    }
    else if(map[snake.x][snake.y]==FOOD)
    {
        snake.len++;
        grade+=100;
        if(speed>400)
            speed-=20;
        gotoxy(7,2*(SIZE_Y+2));
        printf("分数: %d",grade); //更新显示分数
        map[food/SIZE_Y][food%SIZE_Y]=KONG; //原本的食物位置设置为KONG
        rand_food();
    }
}
void rand_food()//重新刷新食物
{
    do
    {
        food=rand()%(SIZE_X*SIZE_Y);
    }while(map[food/SIZE_Y][food%SIZE_Y]!=KONG);
    map[food/SIZE_Y][food%SIZE_Y]=FOOD;
    color(food_color);
    gotoxy(food/SIZE_Y,2*(food%SIZE_Y));
    printf("★");
}
void move_snake(int x,int y)//移动蛇时的赋值
{
    int i;
    draw_snake(0);  //原来的位置画上空格
    map[body[snake.len-1].x][body[snake.len-1].y]=KONG; //最后一节蛇尾设置为KONG
    map[snake.x][snake.y]=BODY; //原来的蛇头设置为BODY
    for(i=snake.len-1;i>0;i--)
    {
        body[i].x=body[i-1].x;
        body[i].y=body[i-1].y;
    }
    body[0].x=snake.x;
    body[0].y=snake.y;
    snake.x=snake.x+x;
    snake.y=snake.y+y;
    draw_snake(1);  //画出新的蛇形
}
void draw_snake(int x)//打印蛇
{
    int i;
    if(x!=0)
    {   color(snake_color);
        gotoxy(snake.x,2*snake.y);
        printf("■");
        for(i=0;i<snake.len;i++)
        {
            gotoxy(body[i].x,2*body[i].y);
            printf("□");
        }
    }
    else
    {
        if(body[snake.len-1].x!=0)
        {   gotoxy(body[snake.len-1].x,2*body[snake.len-1].y);
            printf("  ");
        }
    }
}
void inter_face()//界面
{   
    int i,j;
    for(i=0;i<SIZE_X;i++)
    {
        for(j=0;j<SIZE_Y+12;j++)
        {
            if(i==0 || j==0 || i==SIZE_X-1 || j==SIZE_Y-1 || j==SIZE_Y+11)
            {
                color(wall_color);
                gotoxy(i,2*j);
                printf("■");
                map[i][j]=WALL;
            }
            else if((i==SIZE_X/3 || i==SIZE_X*2/3) && j>SIZE_Y/3 && j<SIZE_Y*2/3)
            {
                gotoxy(i,2*j);
                printf("■");
                map[i][j]=WALL;
            }
            else
            {
                gotoxy(i,2*j);
                printf(" ");
                map[i][j]=KONG;
            }
        }
        printf("\n");
    }
    color(snake_color);

    gotoxy(5,2*(SIZE_Y+2));
    printf("最高纪录: %d",max_grade);

    gotoxy(7,2*(SIZE_Y+2));
    printf("分数: %d",grade);

    gotoxy(9,2*(SIZE_Y+2));
    printf("重新开始: R");

    gotoxy(11,2*(SIZE_Y+2));
    printf("暂停: space");

    gotoxy(13,2*(SIZE_Y+2));
    printf("退出游戏: ESC");


}
void init_snake()//初始化蛇
{
    snake.len=2;
    snake.x=SIZE_X/2;
    snake.y=SIZE_Y/2;
    body[0].x=SIZE_X/2;
    body[0].y=SIZE_Y/2-1;
    body[1].x=SIZE_X/2;
    body[1].y=SIZE_Y/2-2;
    map[body[0].x][body[0].y]=BODY;
    map[body[1].x][body[1].y]=BODY;
}
void MaxGrade()//最高记录
{
    FILE *fp;
    fp=fopen("贪吃蛇最高记录.txt","r+");
    if(fp==NULL)
    {
        fp=fopen("贪吃蛇最高记录.txt","w+");
        fwrite(&max_grade,sizeof(int),1,fp);
    }
    fseek(fp,0,SEEK_SET);
    fread(&max_grade,sizeof(int),1,fp);
    fseek(fp,0,SEEK_SET);
    if(max_grade<grade)
    {
        fwrite(&grade,sizeof(int),1,fp);
    }
}
void gotoxy(int x,int y) //移动坐标 
{

COORD coord;

coord.X=y;

coord.Y=x;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);

}
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
void hidden_cursor()//隐藏光标

{

  HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

  CONSOLE_CURSOR_INFO cci;

  GetConsoleCursorInfo(hOut,&cci);

   cci.bVisible=0;//赋1为显示,赋0为隐藏

  SetConsoleCursorInfo(hOut,&cci);

}
int color(int c)//设置颜色
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); 
    return 0;
}
### 贪吃蛇游戏的C语言实现源码 以下是基于提供的引用内容和专业知识,整理出的一个完整的贪吃蛇游戏 C 语言实现代码示例。此代码包含初始化、运行逻辑、用户交互等功能。 ```c #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> #include <time.h> #define WIDTH 20 #define HEIGHT 10 // 定义蛇的结构体 typedef struct { int x, y; } SnakeNode; SnakeNode snake[100]; int length = 1; // 蛇的长度 int foodX, foodY; // 食物的位置 int dir = 0; // 方向:0-右,1-下,2-左,3-上 int gameOver = 0; // 游戏结束标志 // 初始化游戏 void initGame() { snake[0].x = WIDTH / 2; snake[0].y = HEIGHT / 2; srand((unsigned)time(NULL)); foodX = rand() % WIDTH; foodY = rand() % HEIGHT; } // 绘制游戏界面 void draw() { system("cls"); for (int i = 0; i <= WIDTH + 1; i++) printf("#"); // 上边界 printf("\n"); for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) { if (j == 0 || j == WIDTH - 1) printf("#"); // 左右边界 else if (i == snake[0].y && j == snake[0].x) printf("O"); // 蛇头 else { int printed = 0; for (int k = 1; k < length; k++) { if (snake[k].x == j && snake[k].y == i) { printf("o"); // 蛇身 printed = 1; } } if (!printed) { if (i == foodY && j == foodX) printf("*"); // 食物 else printf(" "); // 空白 } } } printf("\n"); } for (int i = 0; i <= WIDTH + 1; i++) printf("#"); // 下边界 printf("\nScore: %d\n", length - 1); } // 检查是否吃到食物 void checkFood() { if (snake[0].x == foodX && snake[0].y == foodY) { length++; foodX = rand() % WIDTH; foodY = rand() % HEIGHT; } } // 检查碰撞 void checkCollision() { if (snake[0].x <= 0 || snake[0].x >= WIDTH - 1 || snake[0].y <= 0 || snake[0].y >= HEIGHT - 1) { gameOver = 1; } for (int i = 1; i < length; i++) { if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) { gameOver = 1; } } } // 更新蛇的位置 void updateSnake() { for (int i = length - 1; i > 0; i--) { snake[i].x = snake[i - 1].x; snake[i].y = snake[i - 1].y; } switch (dir) { case 0: snake[0].x++; break; case 1: snake[0].y++; break; case 2: snake[0].x--; break; case 3: snake[0].y--; break; } } // 主函数 int main() { initGame(); while (!gameOver) { draw(); checkCollision(); if (gameOver) break; checkFood(); if (_kbhit()) { // 获取用户输入 switch (_getch()) { case 'w': if (dir != 1) dir = 3; break; case 's': if (dir != 3) dir = 1; break; case 'a': if (dir != 0) dir = 2; break; case 'd': if (dir != 2) dir = 0; break; } } updateSnake(); Sleep(100); // 控制游戏速度 } printf("Game Over!\n"); return 0; } ``` ### 代码说明 1. **初始化**:`initGame()` 函数用于初始化蛇的位置和生成食物[^1]。 2. **绘制界面**:`draw()` 函数负责绘制游戏的边界、蛇、食物等元素[^2]。 3. **食物检测**:`checkFood()` 函数检查蛇是否吃到食物,并在需要时生成新的食物位置[^3]。 4. **碰撞检测**:`checkCollision()` 函数检测蛇是否撞墙或撞到自身[^3]。 5. **更新蛇位置**:`updateSnake()` 函数根据当前方向更新蛇的位置[^1]。 6. **主循环**:通过 `while` 循环实现游戏的持续运行,直到游戏结束[^2]。 ### 注意事项 - 此代码适用于 Windows 平台,使用了 `<conio.h>` 和 `<windows.h>` 库中的功能。 - 用户可以通过键盘输入 `w`、`a`、`s`、`d` 来控制蛇的方向。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值