C 游戏block源代码


C 游戏block源代码


正文

block.h:

/***
 * 功能描述: 方块碰撞项目的头文件,这里包括了:
 * 项目所用到的宏定义,方法函数的定义,
 * 枚举,以及结构体定义;
 */
#ifndef  _BLOCK_H_
#define  _BLOCK_H_

/* 宏定义 */
#define   ROW    15  // 界面行数
#define   COL    32  // 界面列数
#define   NR     6   // 方块个数
#define   WIDTH  4   // 方块宽
#define   HEIGHT 2   // 方块高
#define   MOVE   1   // 移动幅度

/* 颜色枚举 */
enum e_color {
    Bg,              // 背景色
    Frame,           // 边框色
    Red,             // 红
    Grean,           // 绿
    Blue,            // 蓝
};

/* 方块结构体封装 */
typedef struct Block {
    int width, height; // 方块的宽高
    int x, y;          // 方块的坐标
    int vx, vy;        // 方块的移动方向
    int vtx, vty;        // 方块的暂定移动方向
    int color;         // 方块的颜色
} Block_t;

/* 初始化背景接口函数 */
void initBg(int bg[ROW][COL]);

/* 显示背景接口函数 */
void showBg(int bg[ROW][COL]);

/* 绘画方块接口函数 */
void drawBlock(int bg[ROW][COL], Block_t *bl);

/* 清除方块接口函数 */
void cleanBlock(int bg[ROW][COL], Block_t *bl);

/* 判断是否碰撞 */
int judgeImpact(Block_t *bl1, Block_t *bl2);

#endif  // _BLOCK_H_ 

block.c:

/*************************************
 * 文件名: block.c
 * 文件描述: 所有方块碰撞用到的方法函数的实现
**************************************/

#include <stdio.h>
#include "block.h"

/*
 * 函数名: initBg()
 * 功能: 初始化所有数据
 * 参数: 需要初始化的背景数组数据
 * 返回值: 无
*/
void initBg(int bg[ROW][COL])
{
    int i, j;

    /* 清屏 */
    fprintf(stdout, "\033[2J");

    /* 初始化数据 */
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
        {
            if (i == 0 || i == ROW-1)      // 上下两行
            {
                bg[i][j] = Frame;
            }
            else if (j <= 1 || j >= COL-2) // 左右两列
            {
                bg[i][j] = Frame;
            }
            else                           // 中间空白数据
            {
                bg[i][j] = Bg;
            }
        }
    }
}

/*
 * 函数名: drawBlock()
 * 功能: 在游戏界面内绘画一个方块
 * 参数: 1.界面数组数据 2.需要绘画的方块
 * 返回值:无
*/
void drawBlock(int bg[ROW][COL], Block_t *bl)
{
    int i, j;

    /* 填充方块对应的颜色数据 */
    for (i = 0; i < bl->height; i++)
    {
       for (j = 0; j < bl->width; j++)
       {
           bg[bl->y+i][bl->x+j] = bl->color;
       }
    }
}

/*
 * 函数名: cleanBlock()
 * 功能: 在游戏界面内清除一个方块
 * 参数: 1.界面数组数据 2.方块x坐标 3.方块y坐标
 *       4.方块宽度 5.方块高度
 * 返回值:无
*/
void cleanBlock(int bg[ROW][COL], Block_t *bl)
{
    int i, j;

    /* 清除方块对应的数据 */
    for (i = 0; i < bl->height; i++)
    {
       for (j = 0; j < bl->width; j++)
       {
           bg[bl->y+i][bl->x+j] = Bg;
       }
    }
}

/*
 * 函数名: showBg()
 * 功能: 显示游戏背景
 * 参数: 需要显示的背景数组数据
 * 返回值: 无
*/
void showBg(int bg[ROW][COL])
{
    int i, j;

    /* 定位到第一行第一列 */
    fprintf(stdout, "\033[1;1H");
    fflush(stdout);

    /* 打印所有数据 */
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
        {
            switch (bg[i][j])   // 不同数据打印不同颜色
            {
                case Frame:
                     fprintf(stdout, "\033[43m \033[0m"); break;
                case Bg:
                     fprintf(stdout, " "); break;
                case Red:
                     fprintf(stdout, "\033[1;41m \033[0m"); break;
                case Grean:
                     fprintf(stdout, "\033[1;42m \033[0m"); break;
                case Blue:
                     fprintf(stdout, "\033[1;44m \033[0m"); break;
            }
        }
        putchar('\n');
    }
}

/*
 * 判断是否碰撞
 * 返回值:
 * 0 不会碰撞
 * 1 x方向碰撞
 * 2 y方向碰撞
 * 3 xy方向碰撞
 * 
*/ 
int judgeImpact(Block_t *bl1, Block_t *bl2) 
{
    int x1, x2, y1, y2;
    int w1 = bl1->width, w2 = bl2->width;
    int h1 = bl1->height, h2 = bl2->height;

    x1 = bl1->x + bl1->vx;
    x2 = bl2->x + bl2->vx;
    y1 = bl1->y + bl1->vy;
    y2 = bl2->y + bl2->vy;

    if (
        // (bl1->y == bl2->y) && (y1 == y2)
        (y1 == y2)
    ) {
        if (
            ((x1 > x2) && (x1 - WIDTH < x2))
            || ((x1 < x2) && (x1 + WIDTH > x2))
        ) {
            return 1;
        }
    }

    if (
        // ((bl1->x == bl2->x) && (x1 == x2))
        (x1 == x2)
        // || ((x2 < x1) && ((x2 + WIDTH) > x1))
        // || ((x1 < x2) && ((x1 + WIDTH) > x2))
    ) {
        if (
            ((y1 > y2) && (y1 - HEIGHT < y2))
            || ((y1 < y2) && (y1 + HEIGHT > y2)
            )
        ) {
            return 2;
        }
    }

    if ( 
        // (bl1->x < bl2->x) && (x1 + WIDTH > x2)
        (x1 < x2) && (x1 + WIDTH > x2)
    ) {
        if (
            ( (y1 < y2) && (y1 + HEIGHT > y2))
            || ((y1 > y2) && (y1 - HEIGHT < y2))
        ) {
            return 3;
        }
    }

    if (
        // (bl1->x > bl2->x) && (x2 + WIDTH > x1)
        (x2 < x1) && (x2 + WIDTH > x1)
    ) {
        if (
            ((y1 < y2) && (y1 + HEIGHT > y2))
            || ((y1 > y2) && (y1 - HEIGHT < y2))
        ) {
            return 3;
        }
    }

    return 0;
}

main.c:

#include <unistd.h>
#include <stdio.h>
#include "block.c"

/*
 * 原理:
 *   根据数组的不同数据打印出不同的颜色;
 *   通过延时达到移动的效果
*/
int main(void)
{
    int i, j;
    int direction;

    /* 背景数据 */
    int bg[ROW][COL];
    
    /* 方块结构体:三个方块 */
    Block_t bl[NR] = {
        {WIDTH,HEIGHT,5,5,   MOVE, MOVE,  MOVE, MOVE, Red  },
        {WIDTH,HEIGHT,10,5,  MOVE,-MOVE,  MOVE,-MOVE, Red  },
        {WIDTH,HEIGHT,20,5, -MOVE,-MOVE, -MOVE,-MOVE, Grean},
        {WIDTH,HEIGHT,10,10,-MOVE, MOVE, -MOVE, MOVE, Blue },
        {WIDTH,HEIGHT,20,10, MOVE, MOVE,  MOVE, MOVE, Blue },
        {WIDTH,HEIGHT,25,5,  MOVE,-MOVE,  MOVE,-MOVE, Blue },
    };

    /* 初始化界面 */
    initBg(bg);

    /* 进入游戏 */
    while (1) { 
        /* 画方块 */ 
        for (i = 0; i < NR; i++ ) 
        { 
            drawBlock(bg, &bl[i]); 
        } 

        /* 显示界面 */ 
        showBg(bg); 
        
        /* 清除方块:只是清除数据而已不影响显示 */ 
        for (i = 0; i < NR; i++) 
        { 
            cleanBlock(bg,&bl[i]); 
        } 
        
        /* 延时一段时间 */ 
        usleep(100000);   // usleep单位是微秒,sleep单位是秒

        /* 边界判断 */ 
        for (i = 0; i < NR; i++) 
        { 
            /* 水平方向 */ 
            if (bl[i].x == 2 || (bl[i].x + bl[i].width) == COL-2) 
            { 
                bl[i].vtx = -bl[i].vtx; 
            }
            
            /* 垂直方向 */ 
            if (bl[i].y == 1 || (bl[i].y + bl[i].height) == ROW-1) 
            { 
                bl[i].vty = -bl[i].vty; 
            } 
        } 

        /* 碰撞判断 */
        for (i = 0; i < NR; i++) 
        {
            for (j = 0; j < NR; j++) 
            {
                if (i != j) {
                    direction = judgeImpact(&bl[i], &bl[j]);
                    switch(direction)
                    {
                        case 1:
                            bl[i].vtx = -bl[i].vx; 
                            break;
                        case 2:
                            bl[i].vty = -bl[i].vy; 
                            break;
                        case 3:
                            bl[i].vtx = -bl[i].vx; 
                            bl[i].vty = -bl[i].vy; 
                            break;
                        default:
                            break;
                    }

                    // if (bl[i].x == bl[j].x) {
                    //     if (
                    //         (bl[i].y < bl[j].y)
                    //         && ((bl[i].y + HEIGHT + MOVE) >= bl[j].y)
                    //     ) {
                    //         bl[i].vty = -bl[i].vy; 
                    //     }
                    //     if (
                    //         (bl[i].y > bl[j].y)
                    //         && ((bl[j].y + HEIGHT + MOVE) >= bl[i].y)
                    //     ) {
                    //         bl[i].vty = -bl[i].vy; 
                    //     }
                    // }
                    // if (bl[i].y == bl[j].y) {
                    //     if (
                    //         (bl[i].x < bl[j].x)
                    //         && ((bl[i].x + WIDTH + MOVE) >= bl[j].x)
                    //     ) {
                    //         bl[i].vtx = -bl[i].vx; 
                    //     }
                    //     if (
                    //         (bl[i].x > bl[j].x)
                    //         && ((bl[j].x + WIDTH + MOVE) >= bl[i].x)
                    //     ) {
                    //         bl[i].vtx = -bl[i].vx; 
                    //     }
                    // }
                    
                    // if (
                    //     (bl[i].x < bl[j].x) 
                    //     && ((bl[i].x + WIDTH) >= bl[j].x)
                    // ) {
                    //     if (
                    //         (bl[i].y <= bl[j].y && (bl[i].y + HEIGHT) >= bl[j].y) 
                    //         || (bl[i].y >= bl[j].y && (bl[i].y - HEIGHT) <= bl[j].y)
                    //     ) {
                    //         bl[i].vtx = -bl[i].vx; 
                    //     }
                    // } else if (
                    //     (bl[i].x > bl[j].x)
                    //     && ((bl[i].x - WIDTH) <= bl[j].x)
                    // ) {
                    //     if (
                    //         (bl[i].y <= bl[j].y && (bl[i].y + HEIGHT) >= bl[j].y) 
                    //         || (bl[i].y >= bl[j].y && (bl[i].y - HEIGHT) <= bl[j].y)
                    //     ) {
                    //         bl[i].vtx = -bl[i].vx; 
                    //     }
                    // } 
                    // if ((bl[i].y + HEIGHT) == bl[j].y) {
                    //     if (
                    //         (bl[i].x <= bl[j].x && (bl[i].x + WIDTH) >= bl[j].x) 
                    //         || (bl[i].x >= bl[j].x && (bl[i].x - WIDTH) <= bl[j].x)
                    //     ) {
                    //         bl[i].vty = -bl[i].vy; 
                    //     }
                    // } else if ((bl[i].y - HEIGHT) == bl[j].y) {
                    //     if (
                    //         (bl[i].x <= bl[j].x && (bl[i].x + WIDTH) >= bl[j].x) 
                    //         || (bl[i].x >= bl[j].x && (bl[i].x - WIDTH) <= bl[j].x)
                    //     ) {
                    //         bl[i].vty = -bl[i].vy; 
                    //     }
                    // }
                }
            }
        }

        /* 移动方向确定 */
        for (i = 0; i < NR; i++) 
        { 
            bl[i].vx = bl[i].vtx; 
            bl[i].vy = bl[i].vty; 
        } 
        
        /* 移动方块 */ 
        for (i = 0; i < NR; i++) 
        { 
            bl[i].x += bl[i].vx; 
            bl[i].y += bl[i].vy; 
        } 
    } 

    return 0; 
}

编译:

gcc main.c -o block






参考资料


返回