C语言小游戏:贪吃蛇

#include <graphics.h>  
#include <conio.h>
#include <stdio.h>
#define WIDTH 40        //设置宽
#define HEIGHT 30        //设置高
#define BLOCK_SIZE 20    //设置每个正方形格子边长

int Blocks[HEIGHT][WIDTH] = { 0 };    //我为什么要这个二维数组?是用来描述蛇身跟食物的!
int food_i, food_j;
char moveDirection;                   //用字符记录小蛇的移动方向
int isFailure = 0;

void test()
{
    //cleardevice();不能用清屏函数
    //如何绘画出一个背景板?
    initgraph(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE);
    //如何布格子?
    //尝试一下画线来布置格子
    setlinecolor(RGB(255,235,205));//并没有用处
    //是否还缺什么函数?
    BeginBatchDraw();
    FlushBatchDraw();
    //以上两个绘图函数并没有绘出格子效果!
}

//尝试一下童晶的start代码
//void startup()  //  初始化函数
//{
//    int i;
//    Blocks[HEIGHT / 2][WIDTH / 2] = 1; // 画面中间画蛇头,数字为1
//    for (i = 1; i <= 4; i++) //  向左依次4个蛇身,数值依次为2,3,4,5
//        Blocks[HEIGHT / 2][WIDTH / 2 - i] = i + 1;
//    //moveDirection = 'd';     //  初始向右移动
//    food_i = rand() % (HEIGHT - 5) + 2; //  初始化随机食物位置
//    food_j = rand() % (WIDTH - 5) + 2; //  
//    initgraph(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE); //  新开画面
//    setlinecolor(RGB(200, 200, 200)); // 设置线条颜色
//    BeginBatchDraw(); // 开始批量绘制
//    //以下是我写的
//
//}
//到底哪里出问题???????

//自己写一个定义蛇蛇移动方向的函数
//自己写一个定义蛇蛇移动方向的函数
void My_move()    //有大问题!蛇自己消失,不会往前移动的
{
    int i, j;
    for (i = 0; i < HEIGHT; i++)
    {
        for (j = 0; j < WIDTH; j++)
        {
            if (Blocks[i][j] > 0)
            {
                Blocks[i][j]++;        //让旧小蛇中的数组元素加1
            }
        }
    }
    int oldHead_i, oldHead_j, oldTail_i, oldTail_j;
    int max = 0;            //利用max来找到蛇尾
    for (i = 0; i < HEIGHT; i++)
    {
        for (j = 0; j < WIDTH; j++)
        {
            if (Blocks[i][j] > max)    //利用max来找到蛇尾
            {
                max = Blocks[i][j];     //更新max的大小
                oldTail_i = i;
                oldTail_j = j;
            }
            if (Blocks[i][j] == 2)    //记录蛇尾的位置
            {
                oldHead_i = i;
                oldHead_j = j;
            }
        }
    }

    int newHead_i = oldHead_i;
    int newHead_j = oldHead_j;

    //if (moveDirection == 'd')
    //{
    //    newHead_j = oldHead_j + 1;
    //}
    if (moveDirection == 'w')        //向上移动
        newHead_i = oldHead_i - 1;
    else if (moveDirection == 's')    //向下移动
        newHead_i = oldHead_i + 1;
    else if (moveDirection == 'a')    //向左移动
        newHead_j = oldHead_j - 1;
    else if (moveDirection == 'd')    //向右移动
        newHead_j = oldHead_j + 1;
    //这里原来自己手写的代码没有加上边界判断,现在自己手动加上
    if (newHead_i >= HEIGHT || newHead_i < 0 || newHead_j >= WIDTH || newHead_j < 0
        || Blocks[newHead_i][newHead_j] > 0)    //这里是判断头位置是否大于0,如果头元素大于0就
    {
        isFailure = 1;    //判断失败
        return;            //函数返回
    }

    //Blocks[newHead_i][newHead_j] = 1; // 新蛇头位置数值为1
    //判断没有游戏失败后
    //开始判断是否吃到食物
    Blocks[newHead_i][newHead_j] = 1;    //新蛇头的元素置为1
    if (newHead_i == food_i && newHead_j == food_j)    //判断新蛇头是否碰到食物
    {
        food_i = rand() % (HEIGHT - 3) + 2;
        food_j = rand() & (WIDTH - 3) + 2;
        //不用对旧蛇处理了,相当于蛇的长度+1
    }
    else
    {
        Blocks[oldTail_i][oldTail_j] = 0;    //旧蛇尾位置变空白,不吃食物时保持蛇的长度
    }

}


void My_startup()
{
    Blocks[HEIGHT / 2][WIDTH / 2] = 1; //将整个方块的中间格子设置为蛇头,为1
    for (int i = 1; i <= 4; i++)
    {
        Blocks[HEIGHT / 2][WIDTH / 2 - i] = i + 1; //从左向右以此画四个蛇身
    }
    moveDirection = 'd';     //  初始向右移动,忘记加默认方向了!!
    //开始画方向
    food_i = rand() % (HEIGHT - 3) + 2;    //应该会出现在角落的位置
    food_j = rand() % (WIDTH - 3) + 2;    //应该会出现在角落的位置
    initgraph(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE);//  新开画面
    setlinecolor(RGB(200, 150, 100));// 设置线条颜色
    BeginBatchDraw();// 开始批量绘制
}

//自己写一个展示背景格子的函数
void My_Show()
{
    cleardevice();
    int i, j;
    for (int i = 0; i < HEIGHT; i++)
    {
        for (int j = 0; j < WIDTH; j++)
        {
            //现在添加回显示蛇身的代码
            if (Blocks[i][j] > 0)    // 元素大于0表示是蛇,这里让蛇的身体颜色色调渐变
            {
                setfillcolor(HSVtoRGB(Blocks[i][j] * 9, 0.9, 1));
            }
            else
                setfillcolor(RGB(255,193,193));    // 元素为0表示为空,颜色为灰色
            fillrectangle(BLOCK_SIZE *j, BLOCK_SIZE * i, BLOCK_SIZE * (j+1), BLOCK_SIZE * (i+1));// 在对应位置处,以对应颜色绘制小方格
        }
    }
    setfillcolor(RGB(0, 255, 0)); //  食物为绿色
    //  绘制食物小方块
    fillrectangle(food_j * BLOCK_SIZE, food_i * BLOCK_SIZE,
        (food_j + 1) * BLOCK_SIZE, (food_i + 1) * BLOCK_SIZE);

    if (isFailure) //  如果游戏失败
    {
        setbkmode(TRANSPARENT); // 文字字体透明    
        settextcolor(RGB(255, 0, 0));// 设定文字颜色
        settextstyle(80, 0, _T("宋体")); //  设定文字大小、样式
        outtextxy(240, 220, _T("游戏失败")); //  输出文字内容
    }
    FlushBatchDraw();
}

//自己定义一个在不按键的情况下蛇蛇自己移动的函数
void My_movewithNothing()
{
    if (isFailure) //  如果游戏失败,函数返回
        return;
    //尝试定义一个静态变量来用while 1 循环去驱动
    static int move = 1;
    move++;
    if (move == 10)
    {
        My_move();
        //moveSnake();
        move = 1;
    }
}

//添加了按键后蛇会根据方向进行移动的函数
void My_movewithTouch()
{
    if (kbhit() && isFailure == 0) //如果有按键输入并且没有出错的话
    {
        char input = getch();
        if (input == 'w' || input == 's' || input == 'a' || input == 'd')
        {
            moveDirection = input;
            My_move();
        }
    }
}

int main() //  主函数
{
    //test();
    //startup();//直接用这个初始化函数后,界面完全是黑色的,没有格子出现
    My_startup();
    
    //可以尝试一下用while 1 不断show出画面
    while (1)
    {
        //show();
        My_Show();//调用了这个函数后就出现背景格子了
        My_movewithNothing();
        My_movewithTouch();
    }
    return 0;
}

 

posted @ 2020-11-07 10:42  青团青  阅读(150)  评论(1编辑  收藏  举报