正文
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