C语言小游戏--贪吃蛇

Python实现VIP电影的解析播放

依然是非常传统的贪吃蛇小游戏,网上很多教程,配置好ege图形库就好,不然没有grapics.h另外,还需要添加snakes.h,直接上代码吧,注释很详细了。觉得难度有一部分来源于配置图形库。。
snakes.h

void welcome();
void initSnake();
void createPoint();
void drawSnake();
void drawRandomPoint();
void view();
void sMove();
void changeHead();
void keyControl(int key);
void drawScore(int x, int y, int score_size);
int isGetPoint();
void againGame();
int isGameOver();
#define WINWIDTH  800   //窗口的宽度
#define WINHIGH  544    //窗口的高度

#define S_POOLX   30    //游戏池开始的横坐标
#define S_POOLY   30    //游戏池开始的纵坐标

#define POINT_W     10  //构成蛇的小方块的宽度

#define E_POOLX  (S_POOLX+(POINT_W+2)*43-2)     //游戏池结束的横坐标
#define E_POOLY  (S_POOLY+(POINT_W+2)*33-2)     //游戏池结束的纵坐标

#define MAX_SNAKE   100     //蛇最大的长度

// 定义一个枚举类型,表示蛇运动的方向
enum  dire
{
    LEFT=1,
    RIGHT,
    UP,
    DOWN,
};

struct point
{
    int x;              //点的横坐标
    int y;              //点的纵坐标
    color_t coler;      //点的颜色
}snake[MAX_SNAKE];     //定义一个点的结构体,包括横纵坐标,以及点的颜色。并定义一个名为snake的点的数组作为蛇的数据存放

main.c

#include <graphics.h>
#include "snake.h"
#include <stdio.h>

int s_length = 0;   //存放蛇的长度
int score =0;       //存放获得的分数
enum dire s_direction = RIGHT;  //初始化蛇的方向是向右运动

struct point  r_point;          //定义一个point结构体来存放随机出现点的数据,即蛇的食物


/**********************************************
 * 游戏结束时显示函数
 * 名称:void AgainGame()
 * 功能:绘制游戏开始界面
 *********************************************/
void againGame()
{
    //声明一个img图片对象
	PIMAGE img;

    cleardevice();              //清屏

    //用newimage在initgraph后创建这个对象。但记得要在不使用的时候delimage
	img = newimage();
	getimage(img, "C://Users//Administrator//Desktop//图片//snake.end!.jpg");        //加载游戏结束的图片
    putimage(0, 0, img);                            //显示游戏结束的图片

    drawScore(360, 250, 60);     //绘制显示得分

    while(getch() != 'r')        //等待用户按键,若等于'r'键,则跳出结束界面,即重新开始程序
    {
        if(!is_run())
        {
            break;       //防止无法关闭窗口
        }
    }
    delimage(img);       //销毁img变量
}

/************************************************
 *判断游戏是否结束函数
 *名称:int isGameOver()
 *功能:通过检查蛇是否出界或者碰到自身身体来判断是否游戏结束
 *返回值:为1则表示游戏结束,为0则游戏进行中。
 ***********************************************/
int isGameOver()
{
    int i;

    //判断蛇头是否超出边界
    if((snake[s_length-1].x < S_POOLX) || (snake[s_length-1].x > E_POOLX-POINT_W) ||(snake[s_length-1].y < S_POOLY) ||(snake[s_length-1].y > E_POOLY-POINT_W))
    {
        return 1;
    }
    else
    {
        for(i=0; i< s_length-1; i++)  //通过for循环来判断蛇头是否与蛇神碰撞
        {
            if((snake[i].x==snake[s_length-1].x) && (snake[i].y==snake[s_length-1].y))
            {
                return 1;
            }
        }
        return 0;
    }
}

/************************************************
 *判断蛇是否迟到食物函数
 *名称:int isGetPoint()
 *功能:通过检查蛇头是否和食物重合来判断是否吃到食物
 *返回值:为1则表示吃到食物,为0则表示还未吃到。
 ***********************************************/
int isGetPoint()
{
    if((snake[s_length-1].x==r_point.x) && (snake[s_length-1].y == r_point.y)) //判断舌头是否和食物坐标重合
    {
        s_length++;             //更新蛇的长度

        snake[s_length-1].x=r_point.x;
        snake[s_length-1].y=r_point.y;                //将食物的坐标添加到蛇snake的数组中,并将食物坐标填充进去
        snake[s_length-1].coler = r_point.coler;

        score += 10;            //得分加10
        changeHead();           //改变蛇头的坐标为运动方向的下一个点的坐标

        return 1;               //若吃到食物则返回1
    }

    return 0;                   //若没吃到食物则返回0
}


/**********************************************
 * 得分的显示函数
 * 名称:void drawScore(int x, int y, int score_size)
 * 功能:按照参数中的坐标和大小显示 蛇的得分
 *********************************************/
void drawScore(int x, int y, int score_size)
{
    char s[10];
    setcolor(EGERGB(0x00, 0x0, 0x0));       //设置字体颜色
    setfont(score_size, 0, "幼圆");         //设置字体
    setbkmode(TRANSPARENT);                 //设置字体背景为透明

    sprintf(s,"%d",score);                  //将整型的score 转换成字符串
    outtextxy(x, y, s);                     //显示字体
}

/************************************************
 *按键控制函数
 *名称:void keyControl(int key)
 *参数:int key ,表示按键的键值。
 *功能:处理蛇的左转、右转、上转和下转,以及游戏的暂停/启动
 ***********************************************/
void keyControl(int key)
{
    switch(key)
    {
        case VK_SPACE:      //暂停设置
            getch();
            getch();
            break;
        case 38:            //按方向上键,改变蛇向上运动
            if(s_direction != DOWN)
            {
                s_direction = UP;
            }

            break;

        case 40:            //按方向下键, 改变蛇向下运动
            if(s_direction != UP)
            {
                s_direction = DOWN;
            }
            break;

        case 37:            //按下方向左键,改变蛇向左运动
            if(s_direction != RIGHT)
            {
                s_direction = LEFT;
            }
            break;

        case 39:            //按下方向右键,改变蛇向右运动
            if(s_direction != LEFT)
            {
                s_direction = RIGHT;
            }
            break;
    }
}

/************************************************
 *更新蛇的运动函数
 *名称:void sMove()
 *功能:根据运动方向,更新蛇的坐标
 ***********************************************/
void sMove()
{
    int n;

    //依次改变蛇身体的坐标,规则为,前一个点的坐标传递给下一个点。
    for(n=1; n<s_length; n++)
    {
        snake[n-1].x = snake[n].x;
        snake[n-1].y = snake[n].y;
    }
    changeHead();       //根据蛇的运动方向,改变蛇头的坐标
}

/************************************************
 *改变蛇头的坐标函数
 *名称:void changeHead()
 *功能:根据运动方向,更新蛇头的坐标
 ***********************************************/
void changeHead()
{
    switch(s_direction)         //根据方向,改变相应的坐标更新
    {
        case RIGHT:
            snake[s_length-1].x += (POINT_W+2);
            break;

        case LEFT:
            snake[s_length-1].x -= (POINT_W+2);
            break;

        case UP:
            snake[s_length-1].y -= (POINT_W+2);
            break;

        case DOWN:
            snake[s_length-1].y += (POINT_W+2);
            break;

        default :
            break;

    }
}

/**************************
//初始化函数
//名称:void initSanke()
//功能:初始化蛇身体、运动方向、蛇的长度变量、得分变量
// ************************/

/**************************
//初始化函数
//名称:void initSanke()
//功能:初始化蛇身体、运动方向、蛇的长度变量、得分变量
// ************************/
void initSnake()
{
    snake[0].coler = 0x00ff00;
    snake[0].x = 10*(POINT_W+2) + S_POOLX;
    snake[0].y = 13*(POINT_W+2) + S_POOLY;

    snake[1].coler = 0x00ff00;
    snake[1].x = snake[0].x + POINT_W+2;
    snake[1].y = snake[0].y ;

    snake[2].coler = 0x00ff00;
    snake[2].x = snake[1].x + POINT_W+2;
    snake[2].y = snake[1].y;                //设置蛇的初始长度为3个方格

    s_length =3;                //初始化蛇的长度为3
    s_direction = RIGHT;        //初始化蛇运动方向为向右
    score =0;                   //初始化得分为0
}


/************************************************
 *蛇的食物生成函数
 *名称:void createPoint()
 *功能:通过随机数产生食物所在点的坐标,并设置食物的颜色
 ***********************************************/
void createPoint()
{
    //随机生成食物所在点的坐标。POINT_W 表示食物的宽度,+2的目的是让方块之间留有空隙
    r_point.x = random(29)*(POINT_W+2) + S_POOLX;
    r_point.y = random(26)*(POINT_W+2) + S_POOLY;

    //设置食物的颜色
    r_point.coler = 0x00ff00;
}

/**********************************************
 *贪吃蛇体的显示函数
 * 名称:void drawSnake()
 * 功能:画出蛇体的形状和颜色
 * 即将结构体数组snake中的已有数据,全部展现在屏幕上。
 *********************************************/
void drawSnake()
{
    int n;

    for(n=0; n<s_length; n++)
    {
        if(n==s_length-1)           //若是蛇头,则绘制形状为空心圆,颜色为白色
        {
            setfillcolor(0xffffff);
            fillellipse(snake[n].x +POINT_W/2, snake[n].y+POINT_W/2,POINT_W,POINT_W);
        }
        else                        //若是蛇身体,则绘制形状为实心正方形,宽度为POINT_W,
        {
            setfillcolor(snake[n].coler);
            bar(snake[n].x, snake[n].y, snake[n].x + POINT_W, snake[n].y + POINT_W);
        }
    }
}


/**********************************************
 *随机产生的蛇食物的显示函数
 * 名称:void drawRandomPoint()
 * 功能:画出蛇食物的形状和颜色
 * 即将结构体r_point中的已有数据,展现在屏幕上。
 *********************************************/
void drawRandomPoint()
{
    setfillcolor(r_point.coler);        //设置填充颜色
    bar(r_point.x, r_point.y, r_point.x+POINT_W, r_point.y+POINT_W); //绘制实心矩形
}

/**********************************************
 * 游戏进行时的显示函数
 * 名称:void view()
 * 功能:根据蛇的数据,不断更新绘制,蛇、食物、得分、背景显示
 *********************************************/
void view()
{
    // 清屏
    cleardevice();

     //加载背景图片
    PIMAGE img;
    img = newimage();
    getimage(img, "C://Users//Administrator//Desktop//图片//snake.mid!.jpg");
    putimage(0,0,img);

    setcolor(0x00ff00);
    rectangle(S_POOLX,S_POOLY,E_POOLX,E_POOLY);

    drawSnake();
    drawRandomPoint();
    drawScore(600, 100, 80);
    delimage(img);
}

/**********************************************
 * 游戏开始前的界面显示函数
 * 名称:void welcome()
 * 功能:绘制游戏开始界面
 *********************************************/
void welcome()
{
    //加载背景图片
    PIMAGE img;
    img = newimage();
    getimage(img, "C://Users//Administrator//Desktop//图片//snake.end!.jpg");
    putimage(0,0,img);

    //打印文字
    char s[] = "press any key to start!";
    setcolor(0x000000);
    setfont(20, 0, "幼圆");
    setbkmode(TRANSPARENT);
    outtextxy(250, 350, s);

    getch();
    delimage(img);

}

/****************************************************
//主循环函数
//名称:void mainloop()
//功能:本函数是程序的核心框架和核心流程
// **************************************************/
void mainloop()
{
   double timeNow = 0, timeBefor = 0;  //定义两个double变量来计算程序运行时间s
    key_msg k = {0};

    welcome();      //程序欢迎界面

    while(is_run()) //is_run() 判断窗口是否关闭
    {
        initSnake();    //初始化
        createPoint();  //创建蛇的食物,即一个点

        for ( ; is_run(); delay_fps(60) )
        {
            if(isGameOver())
            {
                break;  //判断是否超过边界或碰到自身
            }

            //处理按键操作
            while(kbmsg())
            {
                k = getkey();
                if(k.msg == key_msg_down)
                {
                    keyControl(k.key);    //根据按键值,来变换蛇的运动方向
                }

            }

            timeNow = fclock();                 //获取当前时间
            if((timeNow - timeBefor) >= 0.2 )   //用当前的时间减去上一次记录的时间如果超过0.2秒则,移动一格。
            {
                sMove();
                timeBefor = timeNow;
            }

            if(isGetPoint())               //判断蛇是否迟到食物
            {
                createPoint();             //创建一个新的食物
            }

            view();                              //显示
        }

        againGame();      //是否再来一局
    }
}



int main(void)
{
    //1、点击右上角X的时候,程序不主动结束,只是将窗口关闭
	//2、绘图更新模式改为手动跟新,仅当调用delay_ms、delay_fps 等这种函数时候,才去更新画面,避免闪烁
	//3、ege 图形库的默认设置

	setinitmode(INIT_ANIMATION);
	// 图形初始化,窗口尺寸800x544
	initgraph(WINWIDTH, WINHIGH);

	//设置窗口的标题
	setcaption("贪吃蛇游戏");

    // 随机数初始化,如果需要使用随机数的话
	randomize();

	// 程序主循环
	mainloop();

	// 关闭绘图设备
	closegraph();

	return 0;
}

素材截图
(1)welcome.png
在这里插入图片描述

(2)game.png
在这里插入图片描述
(3)gameover.png在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45619006/article/details/108463557