C语言练习之贪吃蛇

本文介绍了使用C语言在clion环境下实现贪吃蛇游戏的过程,并提供了运行截图。

贪吃蛇C语言实现,clion版本。

#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>		// 引用图形库头文件
#include <conio.h>
#include <time.h> //随机函数种子
//定义坐标属性
typedef struct pointXY{
    int x;
    int y;
}MYPOINT;

struct Snake{
    int length; //蛇的长度
    MYPOINT xy[100]; //最多有100节
    char position; //蛇头的方向
}snake;

struct Food{
    MYPOINT fdxy; //食物的坐标
    int eatgrade;
    int flag;  //食物是否存在
}food;

HWND hwnd =NULL; //设置句柄,用来表示主窗口
//把方向枚举出来
//小键盘,键码值
enum movPosition{right=77,left=75,down=80,up=72};

/*
 * 初始化蛇:initSnake
 * 画蛇:drawSnake
 * 移动蛇:moveSnake
 * 按键处理:keyDown
 * 初始化食物:initFood
 * 画食物:drawFood
 * 吃食物:eatFood
 * 蛇什么时候挂掉:snakeDie
 */
void initSnake();
void drawSnake();
void moveSnake();
void keyDown();
void initFood();
void drawFood();
void eatFood();
int snakeDie();
void showGrade();
void pasueMoment();

int main()
{
    srand((unsigned int)time(NULL)); //随机函数种子
    hwnd = initgraph(640, 480);	// 创建绘图窗口,大小为 640x480 像素
    setbkcolor(WHITE); //窗口设置为白色

    initSnake();

    while (1){
        cleardevice(); //刷新窗口
        //由于食物初始化flag为1,表示存在,所以应该先画食物,再由于吃掉后,flag=0,而重新初始化
        drawFood();
        if (food.flag==0){
            initFood();
        }
        drawSnake();
        if(snakeDie()){
            break;
        }
        moveSnake();
        eatFood();
        showGrade();
        //只有按键的时候接收按键
        //才执行keyDown
        while (_kbhit()){
            pasueMoment();
            keyDown();
        }
        Sleep(100);
    }
    getchar();
    closegraph();
    return 0;
}

void initSnake(){
    //把前三节的属性写出来就可以-->初始化数据的过程
    snake.xy[2].x=0;  //第三节
    snake.xy[2].y=0;
    snake.xy[1].x=10; //第二节
    snake.xy[1].y=0;
    snake.xy[0].x=20; //蛇头位置
    snake.xy[0].y=0;

    snake.length=3; //初始化蛇长度
    snake.position =right; //初始化方向往右走

    //food.flag =0;
    food.eatgrade =0;
}

void drawSnake(){

    for (int i = 0; i < snake.length; ++i) {
        setlinecolor(BLACK); //设置线边框颜色
        setfillcolor(RGB(rand()%255,rand()%255,rand()%255)); //设置填充色
        //画矩形(设置左上角,设置右下角)
        fillrectangle(snake.xy[i].x,snake.xy[i].y,snake.xy[i].x+10,snake.xy[i].y+10);
    }
};

void moveSnake(){
    //出了第一节,后面的每一节都是前面一节的坐标
    for (int i = snake.length-1; i >0; --i) {
        snake.xy[i].x = snake.xy[i-1].x;
        snake.xy[i].y = snake.xy[i-1].y;
    }

    //第一节的处理
    switch (snake.position)
    {
        case right:
            snake.xy[0].x +=10;
            break;
        case left:
            snake.xy[0].x -=10;
            break;
        case down:
            snake.xy[0].y +=10;
            break;
        case up:
            snake.xy[0].y -=10;
            break;
        default:
            break;
    }
}

void keyDown(){
    char userKey = 0;

    userKey = _getch(); //获取用户的输入
    //蛇不能掉头走
    switch (userKey)
    {
        case right:
            if(snake.position!= left){
                snake.position = right;
            }
            break;
        case left:
            if(snake.position!= right){
                snake.position = left;
            }
            break;
        case down:
            if(snake.position!= up){
                snake.position = down;
            }
            break;
        case up:
            if(snake.position!= down){
                snake.position = up;
            }
            break;
        default:
            break;
    }
}

//食物随机产生
void initFood(){
    // 为什么要拆开写,防止蛇吃不到食物
    food.fdxy.x = rand()%65*10;
    food.fdxy.y = rand()%48*10;
    food.flag = 1 ; //表示食物存在
    //如果食物出现在蛇身上
    for (int i = 0; i < snake.length; ++i) {
        if(food.fdxy.x == snake.xy[i].x && food.fdxy.y == snake.xy[i].y){
            food.fdxy.x = rand()%65*10;
            food.fdxy.y = rand()%48*10;
        }
    }
}

void drawFood(){
    setlinecolor(BLACK); //设置线边框颜色
    setfillcolor(RGB(rand()%255,rand()%255,rand()%255)); //设置填充色
    fillrectangle(food.fdxy.x,food.fdxy.y,food.fdxy.x+10,food.fdxy.y+10);
}

void eatFood(){
    //1 蛇变长了
    //2 食物要重新生成
    //3 分数要增加
    if(food.fdxy.x == snake.xy[0].x && food.fdxy.y == snake.xy[0].y ){
        snake.length++;
        food.eatgrade+=10;
        food.flag = 0;
    }

}

void showGrade(){
    char grade[100] = "";
    sprintf(grade,"%d",food.eatgrade);
    setbkmode(TRANSPARENT);
    settextcolor(LIGHTBLUE);
    outtextxy(560,20,"分数: ");
    outtextxy(560+50,20,grade);
}

int snakeDie(){
    if(snake.xy[0].x > 640 || snake.xy[0].x<0 || snake.xy[0].y > 480 || snake.xy[0].y <0){
        outtextxy(200,200,"你撞南墙了!");
        MessageBox(hwnd,"game over!","撞墙警告",MB_OK);
        return 1;
    }

    for (int i = 1; i < snake.length; ++i) {
       if(snake.xy[i].x==snake.xy[0].x && snake.xy[i].y==snake.xy[0].y) {
           outtextxy(200,200,"你吃掉了自己");
           MessageBox(hwnd,"game over!","自己吃自己警告",MB_OK);
           return 1;
       }
    }
    return 0;
}

void pasueMoment(){
    //利用空格,暂停程序
    if(_getch() == 32){
        while (_getch()!=32);
    }
};

运行截图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值