为了表示我的歉意(特发此贴(对新手很好哦,高手不要帕我哦,易碎啊))
这是c贴吧高手写的,开始没有注释。不然很难看懂。发现没有注释别人要看懂你的想法还是很难了哦。我以后要学会呀。。。我是从他VB注释改过来的哦。好多人想要注释,都要自己找,这下你们就方便了啊。。
程序代码:
//基本原理是:先随机取的一个屏幕的坐标值(放在pData[i]),再取得屏幕上对应点的原来的颜色值存储在pcolor[i] //中然后将其设置成雪花的颜色值&HFEFFFE(就是画出雪花), //到下一个Timerde事件时先根据原来存储的pDate[i],恢复原来点的颜色,再随机取新的坐标值,重复····从而形成雪花飘动的效果 //在此基础上加上判断图像边缘(用自定义的对比度函数GetContrast,它返回与点pDate[i]下面相邻的点的颜色值各RGB分量之差的和 //当这个差大于某一个值,比喻程序用50是认为此处达到边缘)随机,风向等。 //雪花颜色值是snowcol=&HFEFFFE,之所以取这一个值是因为开始时发现有时候会出现2个雪花重叠从而造成混乱 //(也即上下2个雪花相邻,这样下一个雪花会干扰上一个雪花取得屏幕原来的颜色), //所以将雪花设置成这种接近白色当不如白色FFFFFF常见颜色, //当遇到取得的屏幕原始值是SnowCol就认为出现重叠,就跳过这一个Timer事件不进行屏幕操作。 #include <windows.h> #include <time.h> const int ScrnWidth=1024; const int ScrnHight=800; const long SnowCol =0xFEFFFE; //雪花颜色 const long SnowColDown =0xFFFFFF; //积雪雪花颜色 const long SnowColDuck =0xFFDDDD; //深色积雪颜色 const int SnowNum = 500; //雪花数量为500 const int ID_TIMER = 1; //定时器标识符 const char g_szClassName[] = "myWindowClass"; typedef struct POINTAPI { long x; long y; }a; //存取雪花的结构信息. static HDC hDC1; static struct POINTAPI pData[500]; static long pColor[500]; //存取原来坐标的颜色值 static int Vx,Vy,PVx,PVy,timecont; //vx 雪花整体水平漂移速度 //vy雪花总体垂直下落速度 //pvx单个雪花实际水平速度 //pvy单个雪花实际垂直速度 long Abs(long num) { if(num>=0)return(num); else return(-num); } int Random(int max) { return(rand()%max); } int InitP(int i) { pData[i].x=Random(ScrnWidth); pData[i].y = Random(5); pColor[i] = GetPixel(hDC1, pData[i].x, pData[i].y); //检索指定位置的点的像素的RGB颜色值(返回值) //取得屏幕原来的颜色值 return 1; } //取得一点与周围点的对比度,确定是不是在这一点堆积雪花 long GetContrast(int i) { long ColorCmp; //存取作对比点的颜色值 long tempR; //存取ColorCmp的红色值 long tempG; //同理 long tempB; //同理 int Slope; //存取雪花飘落的方向 if(PVy!=0) Slope = PVx / PVy; //若pvx/pvy在-1和1之间则slope=0;就取正下方的的像素点。 //若pvx/pvy>1,取右下方的点,pvx/pvy<-1则取左下方 else Slope = 2; //根据雪花飘落方向决定取哪一点做对比点 if(Slope==0) ColorCmp = GetPixel(hDC1, pData[i].x, pData[i].y + 1); else if(Slope > 1) ColorCmp = GetPixel(hDC1, pData[i].x + 1, pData[i].y + 1); else ColorCmp = GetPixel(hDC1, pData[i].x - 1, pData[i].y + 1); //确定当前位置没有与另一个雪花重叠,重叠就返回0;用于防止由于不同雪花重叠造成雪花乱堆。 if(ColorCmp==SnowCol)return 0; //分别获取ColorCmp与对比点的蓝,绿,红的差值。 tempB = Abs((ColorCmp>>16)&0xff - (pColor[i]>>16)&0xff); tempG = Abs((ColorCmp>>8)&0xff - (pColor[i]>>8)&0xff); tempR = Abs((ColorCmp)&0xff - (pColor[i])&0xff); //return(tempR * 0.114 + tempG * 0.587 + tempB * 0.299); return((tempR + tempG + tempB) / 3); //返回对比度 } //画出一帧,即重画所有雪花位置一次。 void DrawP(void) { int i; // srand(time(0)); for(i=0;i<SnowNum;i++) //防止雪花重叠造成干扰 { if(pColor[i]!=SnowCol&&pColor[i]!=-1) SetPixel(hDC1, pData[i].x, pData[i].y, pColor[i]); //还原上一个位置的颜色 //设置新的位置,i%3用于将雪花分为3类采用不同的速度,以便形成参次感。 PVx = Random(2) - 1 + Vx * (i % 3); PVy = Vy * (i % 3 + 1); pData[i].x = pData[i].x + PVx; //+pvx与前一点形成的距离差,形成速度的差别 pData[i].y = pData[i].y + PVy; //同理 //取的新位置的原始点的颜色值,用于下一步雪花飘过时恢复此处的颜色 pColor[i] = GetPixel(hDC1, pData[i].x, pData[i].y); //如果获取颜色值失败,表明雪花已经飘出屏幕,重新初始化,GetPixel如果获取失败就返回-1. if(pColor[i] ==-1) InitP(i); else //如果雪花没有重叠,若对比度较小(即不能堆积)就画出雪花 //Random(16)>5用于防止某些连续而明显的边界截获所有的雪花 if(pColor[i]!=SnowCol) if (Random(16) > 5 || GetContrast(i) < 50)//GetContrast(i)<50判断是否超出对比度50这个值就认为是边缘就会堆积雪花 SetPixel(hDC1, pData[i].x, pData[i].y, SnowCol); //否者表明找到明显的边界,画出堆积的学,并初始化以便画新的的雪花 else { SetPixel(hDC1, pData[i].x, pData[i].y - 1, SnowColDuck); SetPixel(hDC1, pData[i].x - 1, pData[i].y, SnowColDuck); SetPixel(hDC1, pData[i].x + 1, pData[i].y, SnowColDown); InitP(i); } } } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_TIMER: //时钟 { if(timecont>200) { timecont=0; Vx = Random(4) - 2; Vy = Random(2) + 2; } else timecont+=1; DrawP(); } break; case WM_CREATE: { int j; srand(time(0)); Vx = Random(4) - 2; Vy = Random(2) + 2; for(j = 0;j<SnowNum;j++) { pData[j].x = Random(ScrnWidth); pData[j].y = Random(ScrnHight); pColor[j] = GetPixel(hDC1, pData[j].x, pData[j].y); } SetTimer(hwnd, ID_TIMER, 10, NULL); hDC1 = GetDC(0); timecont=0; } break; case WM_CLOSE: ReleaseDC(0, hDC1); DestroyWindow(hwnd); break; case WM_DESTROY: KillTimer(hwnd, ID_TIMER); PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) { MessageBox(NULL, "窗体注册失败!", "错误!", MB_ICONEXCLAMATION | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "屏幕飘雪", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL); if(hwnd == NULL) { MessageBox(NULL, "窗体创建失败!", "错误!", MB_ICONEXCLAMATION | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; }我的小雪花,呵呵,这个是我写的,写的超简单哦!但也有到图标留雪功能。呵呵,因为哪里是白色的啊!!!!我的没有层次感,没有写代码。这个给新手学西更容易一点,代码简单。。。嘻嘻。写的不好,不要拍我
程序代码:
#include <windows.h> #include <time.h> #include <stdio.h> int win32_init(HINSTANCE hinst); HWND win32_create(HINSTANCE hinst); void win32_show(HWND hwnd); void win32_run(); void draw_snow(); void init(); HWND hwnd; int scrwidth=1280; int scrheight=800; int n; char str[20]; HDC hdc; typedef struct _Snow {int x; int y; }Snow; Snow snow[500]; long int color[500]; LRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wparam ,LPARAM lparam); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) { if(win32_init(hInstance)) {if(hwnd=win32_create(hInstance)) { win32_show(hwnd); win32_run(); } else return false; } else { MessageBox(0,"注册窗口失败",0,0); return false; } return true; } int win32_init(HINSTANCE hinst) { WNDCLASS wc; memset(&wc,0,sizeof(wc)); wc.hInstance=hinst; wc.lpszClassName="snow"; wc.hbrBackground=(HBRUSH) 1; wc.lpfnWndProc=WinProc; return RegisterClass(&wc); } HWND win32_create(HINSTANCE hinst) { return CreateWindow("snow", "snow", WS_OVERLAPPEDWINDOW, 200, 200, 200, 150, 0, 0, hinst, 0); } void win32_show(HWND hwnd) { ShowWindow(hwnd,SW_SHOW); UpdateWindow(hwnd); } void win32_run() {MSG msg; while(GetMessage(&msg,0,0,0)>0) { DispatchMessage(&msg); } } void init(int n) {snow[n].x=rand()%scrwidth; snow[n].y=rand()%300; color[n]=GetPixel(hdc,snow[n].x,snow[n].y); } LRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wparam ,LPARAM lparam) { switch(msg) {case WM_CREATE: srand(time(0)); for(n=0;n<500;n++) { snow[n].x=rand()%scrwidth; snow[n].y=rand()%scrheight; color[n]=GetPixel(hdc,snow[n].x,snow[n].y); } hdc=GetDC(0);//这里,我开始觉的不写一样的,我hwnd为0以为可以,结果什么都没有.我想这里的0难道是expoloere.exe的句柄吗!!! SetTimer(hwnd,1,50,0); break; case WM_TIMER: for(n=0;n<500;n++) { SetPixel(hdc,snow[n].x,snow[n].y,color[n]); } for(n=0;n<500;n++) {if((snow[n].y=snow[n].y+5)<=800&&(color[n]=GetPixel(hdc,snow[n].x,snow[n].y))!=RGB(255,255,255)) { SetPixel(hdc,snow[n].x,snow[n].y,RGB(255,255,255)); } else {SetPixel(hdc,snow[n].x,snow[n].y-1,RGB(255,255,255)); SetPixel(hdc,snow[n].x,snow[n].y-2,RGB(255,255,255)); SetPixel(hdc,snow[n].x,snow[n].y-3,RGB(255,255,255)); SetPixel(hdc,snow[n].x,snow[n].y-4,RGB(255,255,255)); SetPixel(hdc,snow[n].x-1,snow[n].y-1,RGB(255,255,255)); SetPixel(hdc,snow[n].x+1,snow[n].y-1,RGB(255,255,255)); init(n); } } break; case WM_CLOSE:PostQuitMessage(0); exit(0); break; default: return DefWindowProc(hwnd,msg,wparam,lparam); } return false; }。