| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 771 人关注过本帖, 1 人收藏
标题:为了表示我的歉意(特发此贴(对新手很好哦,高手不要帕我哦,易碎啊))
只看楼主 加入收藏
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
结帖率:95.74%
收藏(1)
 问题点数:0 回复次数:8 
为了表示我的歉意(特发此贴(对新手很好哦,高手不要帕我哦,易碎啊))
这是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;
}

搜索更多相关主题的帖子: 雪花 
2011-07-23 11:02
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
收藏
得分:0 
也许没有看之前的帖子 所以突然看这贴感觉有点莫名其妙 楼主发此贴意在什么
2011-07-23 11:15
Alar30
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:10
帖 子:988
专家分:1627
注 册:2009-9-8
收藏
得分:0 
最近加班太多
看到代码就头晕。。
2011-07-23 11:44
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
收藏
得分:0 
代码还是很浅显易懂的

我就是真命天子,顺我者生,逆我者死!
2011-07-23 11:52
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
收藏
得分:0 
回复 4楼 BlueGuy
那是你牛B的版撒!这能是与我等菜鸟相比啊!

用心做一件事情就这么简单
2011-07-23 12:01
为我留住记忆
Rank: 4
来 自:北京
等 级:业余侠客
帖 子:130
专家分:226
注 册:2011-4-30
收藏
得分:0 

学习c是为了自己更强大。。。
2011-07-23 14:03
hellovfp
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:禁止访问
威 望:30
帖 子:2976
专家分:7697
注 册:2009-7-21
收藏
得分:0 
唉,注释问题,终于引起你重视了。
至于为什么GetDC(0),你读一下下面来自msdn中的这句你就知道为什么了。“If this value is NULL, GetDC retrieves the DC for the entire screen.”

[ 本帖最后由 hellovfp 于 2011-7-23 14:52 编辑 ]

我们都在路上。。。。。
2011-07-23 14:50
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
收藏
得分:0 
以下是引用hellovfp在2011-7-23 14:50:31的发言:

唉,注释问题,终于引起你重视了。
至于为什么GetDC(0),你读一下下面来自msdn中的这句你就知道为什么了。“If this value is NULL, GetDC retrieves the DC for the entire screen.”
呵呵,那是!!高手到来就是不一样啊!!!看来我是猜对了哦

用心做一件事情就这么简单
2011-07-23 15:31
hellovfp
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:禁止访问
威 望:30
帖 子:2976
专家分:7697
注 册:2009-7-21
收藏
得分:0 
回复 8楼 小鱼儿c
不得乱说哦,偶和你一样是初学者,你要相信自己有能力,肯定可以超越我和你自己的。
另外,关于代码格式问题,你可以使用CodeBlocks里的代码自动格式化功能,因为目前你还没有型成自己的固定代码书写习惯,暂时先用着吧。

[ 本帖最后由 hellovfp 于 2011-7-23 16:51 编辑 ]

我们都在路上。。。。。
2011-07-23 16:48
快速回复:为了表示我的歉意(特发此贴(对新手很好哦,高手不要帕我哦,易碎啊) ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.042516 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved