前言
1.本文主要围绕 如何 在 控制台上 下起 一场 只有自己能看见的雪
2.是个简易跨平台的,主要是C语言
3.动画 采用 1s 40帧, 雪花具有 x轴速度和y轴速度
4.比较简单,可以给学生作为C语言结课作业吧.
正文
1.1 先简单处理跨平台
本文写作动机,还是感谢一下大学的启蒙老师,让我知道了有条路叫做程序员,可以作为工作生存下去.那就上代码了.
首先代码定位 是 面向 简单跨平台,至少让 gcc 和 vs 能够跑起来.
其实跨平台都是嚼頭, 说白了就是一些丑陋的宏. 真希望所有系统合二为一,采用统一的标准api 设计,但这是不可能的,就相当于很早之前的电视制式一样.
那么我们先看 围绕跨平台的宏
#include #include #include #include /** 时间 : 2015年12月26日11:43:22
* 描述 : 应该算过节吧,今天,写了个雪花特效 代码,
* *//** 清除屏幕的shell 命令/控制台命令,还有一些依赖平台的实现
* 如果定义了 __GNUC__ 就假定是 使用gcc 编译器,为Linux平台
* 否则 认为是 Window 平台*/#ifdefined(__GNUC__)//下面是依赖 Linux 实现#include #definesleep_ms(m) \ usleep(m *1000)//向上移动光标函数 Linuxstaticvoid__curup(int height)
{
inti = -1;
while(++i
printf("\033[1A");//先回到上一行 }#else// 创建等待函数 1s 60 帧 相当于 16.7ms => 1帧, 我们取16ms// 咱么的这屏幕 推荐 1s 25帧吧 40ms// 这里创建等待函数 以毫秒为单位 , 需要依赖操作系统实现#include #definesleep_ms(m) \ Sleep(m)//向上移动光标staticvoid__curup(int height)
{
COORD cr = {0,0};
// GetStdHandle(STD_OUTPUT_HANDLE) 获取屏幕对象, 设置光标 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cr);
}#endif/*__GNUC__ 跨平台的代码都很丑陋 */
首先是 sleep_ms 这个宏, 传入一个毫秒数,让操作系统等待.
对于__curup 实现的不好. 功能是 让 控制台当前光标移动到 上面的 height 位置,对于 window直接移动到第一行(0,0)位置.
上面一共用了 5个头文件 还是容易的代码. string.h 主要用的是 memset 函数, 让一段内存初始化,用0填充.
对于time.h 主要是为了 初始化时间种子,方便每次运行都不一样.
// 初始化随机数种子,改变雪花轨迹srand((unsigned)time(NULL));
1.2 再说主业务代码
这里程序员运行的主业务,先说一说这里用的数据结构 如下
// 定义初始屏幕的宽高像素宏#define_INT_WIDTH (100)#define_INT_HEIGHT (50)// 屏幕刷新帧的速率#define_INT_FRATE (40)// 雪花飘落的速率,相对于 屏幕刷新帧 的倍数#define_INT_VSNOW (10)/** 错误处理宏,msg必须是""括起来的字符串常量
* __FILE__ : 文件全路径
* __func__ : 函数名
* __LINE__ : 行数行
* __VA_ARGS__ : 可变参数宏,
* ##表示直接连接, 例如 a##b <=> ab*/#definecerr(msg,...) \ fprintf(stderr, "[%s:%s:%d]"msg"\n",__FILE__,__func__,__LINE__,##__VA_ARGS__);/** 屏幕结构体, 具有 宽高
* frate : 绘制一帧的周期, 单位是 毫秒
* width : 屏幕的宽,基于窗口的左上角(0,0)
* height : 屏幕的高
* pix : 用一维模拟二维 主要结构如下
* 0 0 0 1 0 0 1 0 1 0
* 0 1 0 1 0 1 0 1 2 0
* . . .
* => 0表示没像素, 1表示1个像素,2表示2个像素....*/struct screen {
intfrate;// 也可以用 unsigned 结构int width;
int height;
char*pix;
};
创建了一个绘图对象 struct screen 这里 构建这个结构体的时候用了下面一个技巧
//后面是 为 scr->pix 分配的内存 width*heightscr =malloc(sizeof(structscreen) +sizeof(char)*width*height);
一次分配两个内存空间.下面是主要实现的api 对象
/** 创建一个 屏幕结构指针 返回
*
* int frate : 绘制一帧的周期
* int width : 屏幕宽度
* int height : 屏幕高度
* return : 指向屏幕结构的指针
* */structscreen* screen_create(intfrate,intwidth,int height);/** 销毁一个 屏幕结构指针, 并为其置空
* struct screen** : 指向 屏幕结构指针的指针, 二级销毁一级的
* */voidscreen_destory(structscreen** pscr);/**
* 屏幕绘制函数,主要生成一个雪花效果
*
* struct screen* : 屏幕数据
* return : 0表示可以绘制了,1表示图案不变*/intscreen_draw_snow(structscreen* scr);/**
* 屏幕绘制动画效果, 绘制雪花动