日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

c语言sleep_编程代码:用C语言来实现下雪效果,这个冬天,雪花很美

發(fā)布時(shí)間:2025/4/16 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言sleep_编程代码:用C语言来实现下雪效果,这个冬天,雪花很美 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

1.本文主要圍繞 如何 在 控制臺(tái)上 下起 一場(chǎng) 只有自己能看見的雪

2.是個(gè)簡易跨平臺(tái)的,主要是C語言

3.動(dòng)畫 采用 1s 40幀, 雪花具有 x軸速度和y軸速度

4.比較簡單,可以給學(xué)生作為C語言結(jié)課作業(yè)吧.

正文

1.1 先簡單處理跨平臺(tái)

  本文寫作動(dòng)機(jī),還是感謝一下大學(xué)的啟蒙老師,讓我知道了有條路叫做程序員,可以作為工作生存下去.那就上代碼了.

首先代碼定位 是 面向 簡單跨平臺(tái),至少讓 gcc 和 vs 能夠跑起來.

其實(shí)跨平臺(tái)都是嚼頭, 說白了就是一些丑陋的宏. 真希望所有系統(tǒng)合二為一,采用統(tǒng)一的標(biāo)準(zhǔn)api 設(shè)計(jì),但這是不可能的,就相當(dāng)于很早之前的電視制式一樣.

那么我們先看 圍繞跨平臺(tái)的宏

#include #include #include #include /** 時(shí)間 : 2015年12月26日11:43:22 * 描述 : 應(yīng)該算過節(jié)吧,今天,寫了個(gè)雪花特效 代碼, * *//** 清除屏幕的shell 命令/控制臺(tái)命令,還有一些依賴平臺(tái)的實(shí)現(xiàn) * 如果定義了 __GNUC__ 就假定是 使用gcc 編譯器,為Linux平臺(tái) * 否則 認(rèn)為是 Window 平臺(tái)*/#ifdefined(__GNUC__)//下面是依賴 Linux 實(shí)現(xiàn)#include #definesleep_ms(m) usleep(m *1000)//向上移動(dòng)光標(biāo)函數(shù) Linuxstaticvoid__curup(int height) {inti = -1;while(++iprintf("033[1A");//先回到上一行 }#else// 創(chuàng)建等待函數(shù) 1s 60 幀 相當(dāng)于 16.7ms => 1幀, 我們?nèi)?6ms// 咱么的這屏幕 推薦 1s 25幀吧 40ms// 這里創(chuàng)建等待函數(shù) 以毫秒為單位 , 需要依賴操作系統(tǒng)實(shí)現(xiàn)#include #definesleep_ms(m) Sleep(m)//向上移動(dòng)光標(biāo)staticvoid__curup(int height) {COORD cr = {0,0};// GetStdHandle(STD_OUTPUT_HANDLE) 獲取屏幕對(duì)象, 設(shè)置光標(biāo) SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cr); }#endif/*__GNUC__ 跨平臺(tái)的代碼都很丑陋 */

首先是 sleep_ms 這個(gè)宏, 傳入一個(gè)毫秒數(shù),讓操作系統(tǒng)等待.

對(duì)于__curup 實(shí)現(xiàn)的不好. 功能是 讓 控制臺(tái)當(dāng)前光標(biāo)移動(dòng)到 上面的 height 位置,對(duì)于 window直接移動(dòng)到第一行(0,0)位置.

上面一共用了 5個(gè)頭文件 還是容易的代碼. string.h 主要用的是 memset 函數(shù), 讓一段內(nèi)存初始化,用0填充.

對(duì)于time.h 主要是為了 初始化時(shí)間種子,方便每次運(yùn)行都不一樣.

// 初始化隨機(jī)數(shù)種子,改變雪花軌跡srand((unsigned)time(NULL));

1.2 再說主業(yè)務(wù)代碼

這里程序員運(yùn)行的主業(yè)務(wù),先說一說這里用的數(shù)據(jù)結(jié)構(gòu) 如下

// 定義初始屏幕的寬高像素宏#define_INT_WIDTH (100)#define_INT_HEIGHT (50)// 屏幕刷新幀的速率#define_INT_FRATE (40)// 雪花飄落的速率,相對(duì)于 屏幕刷新幀 的倍數(shù)#define_INT_VSNOW (10)/** 錯(cuò)誤處理宏,msg必須是""括起來的字符串常量 * __FILE__ : 文件全路徑 * __func__ : 函數(shù)名 * __LINE__ : 行數(shù)行 * __VA_ARGS__ : 可變參數(shù)宏, * ##表示直接連接, 例如 a##b <=> ab*/#definecerr(msg,...) fprintf(stderr, "[%s:%s:%d]"msg"n",__FILE__,__func__,__LINE__,##__VA_ARGS__);/** 屏幕結(jié)構(gòu)體, 具有 寬高 * frate : 繪制一幀的周期, 單位是 毫秒 * width : 屏幕的寬,基于窗口的左上角(0,0) * height : 屏幕的高 * pix : 用一維模擬二維 主要結(jié)構(gòu)如下 * 0 0 0 1 0 0 1 0 1 0 * 0 1 0 1 0 1 0 1 2 0 * . . . * => 0表示沒像素, 1表示1個(gè)像素,2表示2個(gè)像素....*/struct screen {intfrate;// 也可以用 unsigned 結(jié)構(gòu)int width;int height;char*pix; };

創(chuàng)建了一個(gè)繪圖對(duì)象 struct screen 這里 構(gòu)建這個(gè)結(jié)構(gòu)體的時(shí)候用了下面一個(gè)技巧

//后面是 為 scr->pix 分配的內(nèi)存 width*heightscr =malloc(sizeof(structscreen) +sizeof(char)*width*height);

一次分配兩個(gè)內(nèi)存空間.下面是主要實(shí)現(xiàn)的api 對(duì)象

/** 創(chuàng)建一個(gè) 屏幕結(jié)構(gòu)指針 返回 * * int frate : 繪制一幀的周期 * int width : 屏幕寬度 * int height : 屏幕高度 * return : 指向屏幕結(jié)構(gòu)的指針 * */structscreen* screen_create(intfrate,intwidth,int height);/** 銷毀一個(gè) 屏幕結(jié)構(gòu)指針, 并為其置空 * struct screen** : 指向 屏幕結(jié)構(gòu)指針的指針, 二級(jí)銷毀一級(jí)的 * */voidscreen_destory(structscreen** pscr);/** * 屏幕繪制函數(shù),主要生成一個(gè)雪花效果 * * struct screen* : 屏幕數(shù)據(jù) * return : 0表示可以繪制了,1表示圖案不變*/intscreen_draw_snow(structscreen* scr);/** * 屏幕繪制動(dòng)畫效果, 繪制雪花動(dòng)畫 * * struct screen* : 屏幕結(jié)構(gòu)指針*/voidscreen_flash_snow(structscreen* scr);

創(chuàng)建銷毀, 繪制一個(gè)雪花界面, 繪制雪花動(dòng)畫效果的api. 其實(shí)都很相似,用opengl 庫, 主要讓我們省略了需要單獨(dú)和操作系統(tǒng)顯示層打交道工作.

這里介紹一下,個(gè)人 一個(gè) 簡單避免 野指針的 的方法, 具體看下面實(shí)現(xiàn)

/** 銷毀一個(gè) 屏幕結(jié)構(gòu)指針, 并為其置空 * struct screen** : 指向 屏幕結(jié)構(gòu)指針的指針, 二級(jí)銷毀一級(jí)的 * */voidscreen_destory(structscreen** pscr) {if(NULL == pscr || NULL == *pscr)return;free(*pscr);// 避免野指針*pscr = NULL; }

在執(zhí)行之后置空,因?yàn)镃程序員對(duì)NULL一定要敏感,形成條件反射. 和大家開個(gè)玩笑 ,

請(qǐng)問 :

C 語言中, NULL , 0,'0',"0",false有什么異同 ?

歡迎同行,在招聘的時(shí)候問問,應(yīng)聘初級(jí)開發(fā)工作者. 為什么C需要扣的那么細(xì). 因?yàn)槠渌Z言.你不明白是什么,

你可以用的很好. 但是C你寫的代碼,如果不知道會(huì)有怎樣的結(jié)果,那么 線上就一大片服務(wù)器直接崩掉.而且還很難找出

問題所在. 因?yàn)镃很簡單,越簡單就是越復(fù)雜.就越需要專業(yè)的維護(hù)人員.導(dǎo)致它成了'玩具'.

最后看一下 主業(yè)務(wù)

// 主函數(shù),主業(yè)務(wù)在此運(yùn)行intmain(intargc,char*argv[]) {structscreen* scr = NULL;//創(chuàng)建一個(gè)屏幕對(duì)象scr = screen_create(_INT_FRATE, _INT_WIDTH, _INT_HEIGHT);if(NULL == scr)exit(EXIT_FAILURE);//繪制雪花動(dòng)畫 screen_flash_snow(scr);//銷毀這個(gè)屏幕對(duì)象screen_destory(&scr);return0; }

還是非常容易看懂的, 創(chuàng)建一個(gè)屏幕對(duì)象,繪制雪花效果.銷毀屏幕對(duì)象.

1.3 說一寫 接口的實(shí)現(xiàn)細(xì)節(jié)

先看幾個(gè)簡單的api 實(shí)現(xiàn),創(chuàng)建和銷魂代碼如下,很直白.

/** 創(chuàng)建一個(gè) 屏幕結(jié)構(gòu)指針 返回 * * int frate : 繪制一幀的周期 * int width : 屏幕寬度 * int height : 屏幕高度 * return : 指向屏幕結(jié)構(gòu)的指針 * */structscreen* screen_create(intfrate,intwidth,int height) {structscreen *scr = NULL;if(frate<0|| width <=0|| height <=0) {cerr("[WARNING]check is frate<0 || width<=0 || height<=0 err!");return NULL;}//后面是 為 scr->pix 分配的內(nèi)存 width*heightscr =malloc(sizeof(structscreen) +sizeof(char)*width*height);if(NULL == scr) {cerr("[FATALG]Out of memory!");return NULL;}scr->frate = frate;scr->width = width;scr->height = height;//減少malloc次數(shù),malloc消耗很大,內(nèi)存泄露呀,內(nèi)存碎片呀scr->pix = ((char*)scr) +sizeof(struct screen);return scr; }/** 銷毀一個(gè) 屏幕結(jié)構(gòu)指針, 并為其置空 * struct screen** : 指向 屏幕結(jié)構(gòu)指針的指針, 二級(jí)銷毀一級(jí)的 * */voidscreen_destory(structscreen** pscr) {if(NULL == pscr || NULL == *pscr)return;free(*pscr);// 避免野指針*pscr = NULL; }

后面說一下 如何 繪制 屏幕中雪花

主要算法 是

a.有個(gè)屏幕 w x h

b.屏幕從上面第一行 出雪花 , 出雪花 位置是隨機(jī)的[0,w], 但是有個(gè)距離,這個(gè)距離內(nèi)只有一個(gè)雪花

c.下一行 雪花 依賴上一行雪花的生成, 每個(gè)雪花在可以飄動(dòng)的時(shí)候, 只能 在[-1,1] 范圍內(nèi)

d.實(shí)現(xiàn)動(dòng)畫 效果 就是 每畫一幀就等待 一段時(shí)間

下面看具體一點(diǎn)的 a

//創(chuàng)建一個(gè)屏幕對(duì)象scr = screen_create(_INT_FRATE, _INT_WIDTH, _INT_HEIGHT);

scr對(duì)象就是我們的創(chuàng)建屏幕. _INT_WIDTH 和 _INT_HEIGHT 就是屏幕大小. 對(duì)于_INT_FRATE 表示繪制一幀時(shí)間.

b實(shí)現(xiàn) 代碼如下:

//構(gòu)建開頭 的雪花,下面宏表示每 _INT_SHEAD 個(gè)步長,一個(gè)雪花,需要是2的冪//static 可以理解為 private, 宏,位操作代碼多了確實(shí)難讀#define_INT_SHEAD (1<<2)staticvoid__snow_head(char* snow,int len) {intr =0;//數(shù)據(jù)需要清空memset(snow,0, len);for (;;) {//取余一個(gè)技巧 2^3 - 1 = 7 => 111 , 并就是取余數(shù)intt = rand() & (_INT_SHEAD -1);if(r + t >= len)break;snow[r + t] =1;r += _INT_SHEAD;} }#undef_INT_SHEAD

技巧如上,可以看說明. 這里 科普一下, 對(duì)于 for(;;) {} 和 while(true) {} 異同.

for(;;) {} 和 while(true) {} 這兩段代碼轉(zhuǎn)成匯編是一樣的, 不一樣 的是 強(qiáng)加的意愿. 第一個(gè) 希望 跳過 檢測(cè)步驟 速度更快一點(diǎn).

再擴(kuò)展一點(diǎn).

//另一種 循環(huán)語句, goto 還是 很強(qiáng)大實(shí)用的__for_loop:if(false)goto __for_break; goto __for_loop; __for_break:

可以再擴(kuò)展深一點(diǎn), 還有一種 api 比 這個(gè)goto 還NB. 有機(jī)會(huì)分享. 特別強(qiáng)大, 是異常處理程序本質(zhì).

對(duì)于c.

//通過 上一個(gè) scr->pix[scr->width*(idx-1)] => scr->pix[scr->width*idx]//下面的宏 規(guī)定 雪花左右搖擺 0 向左一個(gè)像素, 1 表示 不變, 2表示向右一個(gè)像素#define_INT_SWING (3)staticvoid__snow_next(structscreen* scr,int idx) {intwidth = scr->width;char* psnow = scr->pix + width*(idx -1);char* snow = psnow + width;inti, j, t;// i索引, j保存下一個(gè)瞬間雪花的位置,t 臨時(shí)補(bǔ)得,解決雪花重疊問題//為當(dāng)前行重置memset(snow,0, width);//通過上一次雪花位置 計(jì)算下一次雪花位置for(i =0; ifor(t = psnow[i]; t>0; --t) {// 雪花可以重疊// rand()%_INT_SWING - 1 表示 雪花 橫軸的偏移量,相對(duì)上一次位置j = i + rand() % _INT_SWING -1;j = j<0? width -1: j >= width ?0: j;// j如果越界了,左邊越界讓它到右邊,右邊越界到左邊++snow[j];}} }

下一行雪花 依賴 上一行雪花, 這里 有點(diǎn)像插入排序.

整體的繪制代碼 如下

/** * 屏幕繪制函數(shù),主要生成一個(gè)雪花效果 * * struct screen* : 屏幕數(shù)據(jù) * return : 0表示可以繪制了,1表示圖案不變*/intscreen_draw_snow(structscreen* scr) {// 靜態(tài)變量,默認(rèn)初始化為0,每次都共用staticint__speed =0;int idx;if(++__speed != _INT_VSNOW)return1;//下面 就是 到了雪花飄落的時(shí)刻了 既 __speed == _INT_VSNOW__speed =0;//這里重新構(gòu)建雪花界面,先構(gòu)建頭部,再從尾部開始構(gòu)建for(idx = scr->height -1; idx >0; --idx)__snow_next(scr, idx);//構(gòu)建頭部__snow_head(scr->pix, scr->width);return0; }

繪制了一個(gè)屏幕對(duì)象的雪花. __speed 記錄 繪制次數(shù), _INT_VSNOW 控制繪制速率

d 的實(shí)現(xiàn)代碼 如下

首先實(shí)現(xiàn)一個(gè) 銷毀屏幕代碼和 繪制代碼

//buf 保存scr 中pix 數(shù)據(jù),構(gòu)建后為 (width+1)*height, 后面宏是雪花圖案#define_CHAR_SNOW '*'staticvoid__flash_snow_buffer(structscreen* scr,char* buf) {int i, j, rt;intheight = scr->height, width = scr->width;intfrate = scr->frate;//刷新的幀頻率 //每次都等一下for (;;sleep_ms(frate)) {//開始繪制屏幕rt = screen_draw_snow(scr);if (rt)continue;for(i =0;ichar* snow = scr->pix + i*width;for(j =0; jbuf[rt++] = snow[j] ? _CHAR_SNOW :'';buf[rt++] ='n';}buf[rt -1] ='0';//正式繪制到屏幕上 puts(buf);//清空老屏幕,屏幕光標(biāo)回到最上面 __curup(height);} }#undef_CHAR_SNOW

這里 sleep_ms(frate); 是等待時(shí)間,否則太快, 人眼看不見.

繪制原理是 讓屏幕轉(zhuǎn)成控制臺(tái)能夠認(rèn)識(shí)的字符. 塞入到buf 中.

__curup(height); 讓繪制光標(biāo)回到開頭.

后面還有一段 代碼實(shí)現(xiàn)

/** * 屏幕繪制動(dòng)畫效果, 繪制雪花動(dòng)畫 * * struct screen* : 屏幕結(jié)構(gòu)指針*/voidscreen_flash_snow(structscreen* scr) {char* buf = NULL;// 初始化隨機(jī)數(shù)種子,改變雪花軌跡 srand((unsigned)time(NULL));buf =malloc(sizeof(char)*(scr->width +1)*scr->height);if(NULL == buf) {cerr("[FATAL]Out of memory!");exit(EXIT_FAILURE);}__flash_snow_buffer(scr, buf);//1.這里理論上不會(huì)執(zhí)行到這,沒加控制器. 2.對(duì)于buf=NULL,這種代碼 可以省掉,看編程習(xí)慣free(buf);buf = NULL; }

這種雙函數(shù)實(shí)現(xiàn)一個(gè)功能技巧用的也很多. 例如寫快速排序代碼, 就是這樣.

到這里 我們 設(shè)計(jì)和實(shí)現(xiàn)都完成了.

2.代碼效果展示

2.1 window 上展示

使用VS新建一個(gè)控制臺(tái)項(xiàng)目,F5就可以了效果如下

是動(dòng)態(tài)的.

2.2 對(duì)于Linux

直接使用

gcc -g -Wall snow.c -o snow.out./snow.out

運(yùn)行效果如下

到這里, C語言實(shí)現(xiàn)雪花效果就如上了.

2.3 完整的代碼展示. 感謝 有你,一路同行.

#include #include #include #include /** 時(shí)間 : 2015年12月26日11:43:22 * 描述 : 應(yīng)該算過節(jié)吧,今天,寫了個(gè)雪花特效 代碼, * 送給 大學(xué)啟蒙 蘆老師 * 學(xué)生王志 祝福上 * *//** 清除屏幕的shell 命令/控制臺(tái)命令,還有一些依賴平臺(tái)的實(shí)現(xiàn) * 如果定義了 __GNUC__ 就假定是 使用gcc 編譯器,為Linux平臺(tái) * 否則 認(rèn)為是 Window 平臺(tái)*/#ifdefined(__GNUC__)//下面是依賴 Linux 實(shí)現(xiàn)#include #definesleep_ms(m) usleep(m *1000)//向上移動(dòng)光標(biāo)函數(shù) Linuxstaticvoid__curup(int height) {inti = -1;while(++iprintf("033[1A");//先回到上一行 }#else// 創(chuàng)建等待函數(shù) 1s 60 幀 相當(dāng)于 16.7ms => 1幀, 我們?nèi)?6ms// 咱么的這屏幕 推薦 1s 25幀吧 40ms// 這里創(chuàng)建等待函數(shù) 以毫秒為單位 , 需要依賴操作系統(tǒng)實(shí)現(xiàn)#include #definesleep_ms(m) Sleep(m)//向上移動(dòng)光標(biāo)staticvoid__curup(int height) {COORD cr = {0,0};// GetStdHandle(STD_OUTPUT_HANDLE) 獲取屏幕對(duì)象, 設(shè)置光標(biāo) SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cr); }#endif/*__GNUC__ 跨平臺(tái)的代碼都很丑陋 */// 定義初始屏幕的寬高像素宏#define_INT_WIDTH (100)#define_INT_HEIGHT (50)// 屏幕刷新幀的速率#define_INT_FRATE (40)// 雪花飄落的速率,相對(duì)于 屏幕刷新幀 的倍數(shù)#define_INT_VSNOW (10)/** 錯(cuò)誤處理宏,msg必須是""括起來的字符串常量 * __FILE__ : 文件全路徑 * __func__ : 函數(shù)名 * __LINE__ : 行數(shù)行 * __VA_ARGS__ : 可變參數(shù)宏, * ##表示直接連接, 例如 a##b <=> ab*/#definecerr(msg,...) fprintf(stderr, "[%s:%s:%d]"msg"n",__FILE__,__func__,__LINE__,##__VA_ARGS__);/** 屏幕結(jié)構(gòu)體, 具有 寬高 * frate : 繪制一幀的周期, 單位是 毫秒 * width : 屏幕的寬,基于窗口的左上角(0,0) * height : 屏幕的高 * pix : 用一維模擬二維 主要結(jié)構(gòu)如下 * 0 0 0 1 0 0 1 0 1 0 * 0 1 0 1 0 1 0 1 2 0 * . . . * => 0表示沒像素, 1表示1個(gè)像素,2表示2個(gè)像素....*/struct screen {intfrate;// 也可以用 unsigned 結(jié)構(gòu)int width;int height;char*pix; };/** 創(chuàng)建一個(gè) 屏幕結(jié)構(gòu)指針 返回 * * int frate : 繪制一幀的周期 * int width : 屏幕寬度 * int height : 屏幕高度 * return : 指向屏幕結(jié)構(gòu)的指針 * */structscreen* screen_create(intfrate,intwidth,int height);/** 銷毀一個(gè) 屏幕結(jié)構(gòu)指針, 并為其置空 * struct screen** : 指向 屏幕結(jié)構(gòu)指針的指針, 二級(jí)銷毀一級(jí)的 * */voidscreen_destory(structscreen** pscr);/** * 屏幕繪制函數(shù),主要生成一個(gè)雪花效果 * * struct screen* : 屏幕數(shù)據(jù) * return : 0表示可以繪制了,1表示圖案不變*/intscreen_draw_snow(structscreen* scr);/** * 屏幕繪制動(dòng)畫效果, 繪制雪花動(dòng)畫 * * struct screen* : 屏幕結(jié)構(gòu)指針*/voidscreen_flash_snow(structscreen* scr);// 主函數(shù),主業(yè)務(wù)在此運(yùn)行intmain(intargc,char*argv[]) {structscreen* scr = NULL;//創(chuàng)建一個(gè)屏幕對(duì)象scr = screen_create(_INT_FRATE, _INT_WIDTH, _INT_HEIGHT);if(NULL == scr)exit(EXIT_FAILURE);//繪制雪花動(dòng)畫 screen_flash_snow(scr);//銷毀這個(gè)屏幕對(duì)象screen_destory(&scr);return0; }/** 創(chuàng)建一個(gè) 屏幕結(jié)構(gòu)指針 返回 * * int frate : 繪制一幀的周期 * int width : 屏幕寬度 * int height : 屏幕高度 * return : 指向屏幕結(jié)構(gòu)的指針 * */structscreen* screen_create(intfrate,intwidth,int height) {structscreen *scr = NULL;if(frate<0|| width <=0|| height <=0) {cerr("[WARNING]check is frate<0 || width<=0 || height<=0 err!");return NULL;}//后面是 為 scr->pix 分配的內(nèi)存 width*heightscr =malloc(sizeof(structscreen) +sizeof(char)*width*height);if(NULL == scr) {cerr("[FATALG]Out of memory!");return NULL;}scr->frate = frate;scr->width = width;scr->height = height;//減少malloc次數(shù),malloc消耗很大,內(nèi)存泄露呀,內(nèi)存碎片呀scr->pix = ((char*)scr) +sizeof(struct screen);return scr; }/** 銷毀一個(gè) 屏幕結(jié)構(gòu)指針, 并為其置空 * struct screen** : 指向 屏幕結(jié)構(gòu)指針的指針, 二級(jí)銷毀一級(jí)的 * */voidscreen_destory(structscreen** pscr) {if(NULL == pscr || NULL == *pscr)return;free(*pscr);// 避免野指針*pscr = NULL; }//構(gòu)建開頭 的雪花,下面宏表示每 _INT_SHEAD 個(gè)步長,一個(gè)雪花,需要是2的冪//static 可以理解為 private, 宏,位操作代碼多了確實(shí)難讀#define_INT_SHEAD (1<<2)staticvoid__snow_head(char* snow,int len) {intr =0;//數(shù)據(jù)需要清空memset(snow,0, len);for (;;) {//取余一個(gè)技巧 2^3 - 1 = 7 => 111 , 并就是取余數(shù)intt = rand() & (_INT_SHEAD -1);if(r + t >= len)break;snow[r + t] =1;r += _INT_SHEAD;} }#undef_INT_SHEAD//通過 上一個(gè) scr->pix[scr->width*(idx-1)] => scr->pix[scr->width*idx]//下面的宏 規(guī)定 雪花左右搖擺 0 向左一個(gè)像素, 1 表示 不變, 2表示向右一個(gè)像素#define_INT_SWING (3)staticvoid__snow_next(structscreen* scr,int idx) {intwidth = scr->width;char* psnow = scr->pix + width*(idx -1);char* snow = psnow + width;inti, j, t;// i索引, j保存下一個(gè)瞬間雪花的位置,t 臨時(shí)補(bǔ)得,解決雪花重疊問題//為當(dāng)前行重置memset(snow,0, width);//通過上一次雪花位置 計(jì)算下一次雪花位置for(i =0; ifor(t = psnow[i]; t>0; --t) {// 雪花可以重疊// rand()%_INT_SWING - 1 表示 雪花 橫軸的偏移量,相對(duì)上一次位置j = i + rand() % _INT_SWING -1;j = j<0? width -1: j >= width ?0: j;// j如果越界了,左邊越界讓它到右邊,右邊越界到左邊++snow[j];}} }/** * 屏幕繪制函數(shù),主要生成一個(gè)雪花效果 * * struct screen* : 屏幕數(shù)據(jù) * return : 0表示可以繪制了,1表示圖案不變*/intscreen_draw_snow(structscreen* scr) {// 靜態(tài)變量,默認(rèn)初始化為0,每次都共用staticint__speed =0;int idx;if(++__speed != _INT_VSNOW)return1;//下面 就是 到了雪花飄落的時(shí)刻了 既 __speed == _INT_VSNOW__speed =0;//這里重新構(gòu)建雪花界面,先構(gòu)建頭部,再從尾部開始構(gòu)建for(idx = scr->height -1; idx >0; --idx)__snow_next(scr, idx);//構(gòu)建頭部__snow_head(scr->pix, scr->width);return0; }//buf 保存scr 中pix 數(shù)據(jù),構(gòu)建后為 (width+1)*height, 后面宏是雪花圖案#define_CHAR_SNOW '*'staticvoid__flash_snow_buffer(structscreen* scr,char* buf) {int i, j, rt;intheight = scr->height, width = scr->width;intfrate = scr->frate;//刷新的幀頻率 //每次都等一下for (;;sleep_ms(frate)) {//開始繪制屏幕rt = screen_draw_snow(scr);if (rt)continue;for(i =0;ichar* snow = scr->pix + i*width;for(j =0; jbuf[rt++] = snow[j] ? _CHAR_SNOW :'';buf[rt++] ='n';}buf[rt -1] ='0';//正式繪制到屏幕上 puts(buf);//清空老屏幕,屏幕光標(biāo)回到最上面 __curup(height);} }#undef_CHAR_SNOW/** * 屏幕繪制動(dòng)畫效果, 繪制雪花動(dòng)畫 * * struct screen* : 屏幕結(jié)構(gòu)指針*/voidscreen_flash_snow(structscreen* scr) {char* buf = NULL;// 初始化隨機(jī)數(shù)種子,改變雪花軌跡 srand((unsigned)time(NULL));buf =malloc(sizeof(char)*(scr->width +1)*scr->height);if(NULL == buf) {cerr("[FATAL]Out of memory!");exit(EXIT_FAILURE);}__flash_snow_buffer(scr, buf);//1.這里理論上不會(huì)執(zhí)行到這,沒加控制器. 2.對(duì)于buf=NULL,這種代碼 可以省掉,看編程習(xí)慣free(buf);buf = NULL; }

后記

到這里就結(jié)束了,這次分享的比較簡單,有興趣的同學(xué)可以 看看, 推薦寫一遍. 代碼看不懂的時(shí)候,多歇歇,看得懂的時(shí)候,多寫寫,

就有套路了. 歡迎吐槽. 錯(cuò)誤是在所難免的.

這個(gè)冬天,雪花很美,(。⌒?⌒)

總結(jié)

以上是生活随笔為你收集整理的c语言sleep_编程代码:用C语言来实现下雪效果,这个冬天,雪花很美的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。