#include <windows.h>
#include <stdlib.h>
#include <time.h>
#define D 1 //雪花下降速度
COLORREF snowcolor=0x2711EE; //雪花顏色
COLORREF snowcolor1=0x0000FF; //積雪顏色
int FENG; //風向風速值
int MINX; //屏幕X坐標最大值
int MINY; //屏幕Y坐標最大值
////////////////////////////////////////////////////////////////////////////////
//獲取屏幕分辨率
int getXY(int *MINX,int *MINY)
{
HDC hdc=GetDC(NULL);
int t=1;
int x=600;
int y=600;
for(;t;)
{
if(GetPixel(hdc,x,100)==CLR_INVALID) t=0;
x++;
}
t=1;
for(;t;)
{
if(GetPixel(hdc,100,y)==CLR_INVALID) t=0;
y++;
}
*MINX=x;
*MINY=y;
ReleaseDC(NULL, hdc);
return 0;
}
//雪花點屬性結構體
struct xue {
int x; //雪花的當前坐標點
int y;
COLORREF oldcolor; //當前雪花點的原始顏色值
int del; //是否刪除該節點標志值不等于0則刪除此節點
int nextx; //將要移動到的坐標點
int nexty;
int shudu; //下降速度
};
//雪花布局鏈表標準節點
struct xhbiao { //此結構體用于創建雪花的布局鏈表
struct xue xh;
struct xhbiao *next; //后繼
struct xhbiao *quet; //前驅
};
//初始化單點雪花
int huaxue (struct xue *xuehua) //函數功能是初始化一個新的雪花點
{
HDC hdc=GetDC(NULL);
xuehua->y=0;
xuehua->x=(int)(rand()%MINX);
xuehua->oldcolor=GetPixel(hdc,xuehua->x,xuehua->y);
xuehua->shudu=(int)((rand()%10)*D+1);
xuehua->del=0;
ReleaseDC(NULL,hdc);
return 0;
}
//創建鏈表
int link(struct xhbiao **tou,struct xhbiao **wei)
{
struct xhbiao *p;
p=(struct xhbiao*)malloc(sizeof(struct xhbiao));
huaxue(&p->xh);
p->next=NULL;
p->quet=NULL;
(*tou)=p;
(*wei)=p;
return 0;
}
//插入節點
int linkCHA(struct xhbiao **tou,struct xhbiao **wei)
{
if((*tou)!=NULL)
{
struct xhbiao *p;
p=(struct xhbiao*)malloc(sizeof(struct xhbiao));
huaxue(&p->xh);
p->next=NULL;
p->quet=(*wei);
(*wei)->next=p;
(*wei)=p;
}
return 0;
}
//刪除節點
int linkDEL(struct xhbiao *del)
{
del->quet->next=del->next;
del->next->quet=del->quet;
free(del);
return 0;
}
//維護雪堆鏈表清除需要刪除的雪粒節點
int linkWUI(struct xhbiao **tou,struct xhbiao **wei)
{
struct xhbiao *p;
p=(*tou);
for(;p!=NULL;)
{
if(p->xh.del!=0)
{
if(p==(*tou))
{
(*tou)=p->next;
p->next->quet=NULL;
free(p);
}else if(p==(*wei))
{
(*wei)=p->quet;
p->quet->next=NULL;
free(p);
}else {
linkDEL(p);
}
}
p=p->next;
}
return 0;
}
//物理信息處理
int luoxue(struct xhbiao *tou,struct xhbiao *wei)
{
struct xhbiao *p; //處理雪花的物理動作
p=tou;
for(;p!=NULL;)
{
p->xh.nexty=p->xh.y+p->xh.shudu; //下降
p->xh.nextx=p->xh.x+FENG; //(風向風速)
p=p->next;
}
return 0;
}
//雪堆更新到屏幕
int xuehuagdi(struct xhbiao *tou,struct xhbiao *wei)
{
HDC hdc=GetDC(NULL);
COLORREF color,color1;
int R,G,B,RGB;
struct xhbiao *p1; //顯示雪堆鏈表的數據
p1=tou;
for(;p1!=NULL;)
{
SetPixel(hdc,p1->xh.x,p1->xh.y,p1->xh.oldcolor);
if((p1->xh.nexty<=MINY)&&(p1->xh.nextx>=0)&&(p1->xh.nextx<=MINX)) //超出屏幕邊界則刪除節點
{
color=GetPixel(hdc,p1->xh.nextx,p1->xh.nexty);
if(color!=snowcolor) //如果雪點下一個顯示目標點與別的雪點重合則不處理等待維護函數刪除此節點
{
color1=GetPixel(hdc,p1->xh.nextx,(p1->xh.nexty-1));
B=abs((color>>16)&0xff-(color1>>16)&0xff);
G=abs((color>>8)&0xff-(color1>>8)&0xff);
R=abs((color)&0xff-(color1)&0xff);
RGB=(R+G+B)/3; //根據對比度判斷是否堆積雪花
if(RGB<50){
p1->xh.oldcolor=color;
SetPixel(hdc,p1->xh.nextx,p1->xh.nexty,snowcolor);
p1->xh.x=p1->xh.nextx;
p1->xh.y=p1->xh.nexty;
}else if(RGB>50){
SetPixel(hdc,p1->xh.nextx,(p1->xh.nexty-1),snowcolor1);
p1->xh.del=1;
}
}else if(color==snowcolor){
p1->xh.del=1;
}
} else if((p1->xh.nexty>MINY)||(p1->xh.nextx<0)||(p1->xh.nextx>MINX)){
p1->xh.del=1;
SetPixel(hdc,p1->xh.x,p1->xh.y,p1->xh.oldcolor);
}
p1=p1->next;
}
ReleaseDC(NULL,hdc);
return 0;
}
/////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
srand(time(NULL));
struct xhbiao *tou,*p,*wei; //tou為新建表的表頭wei為表尾p為新節點的指針
tou=NULL;
wei=NULL;
FENG=0;
int i,j,k;
k=0;
////////////////////////////////////////////////////////////////////////////////
MINY=1100;
MINX=1300;
link(&tou,&wei);
for(i=0;i<=8;)
{
for(j=0;j<=k;j++)
{
linkCHA(&tou,&wei);
}
luoxue(tou,wei);
xuehuagdi(tou,wei);
linkWUI(&tou,&wei);
Sleep(30);
k=rand()%22;
}
return 0;
}