C++游戏基础物理建模之粒子系统模拟

合集下载

物理模拟中的粒子动力学模型构建与仿真实现

物理模拟中的粒子动力学模型构建与仿真实现

物理模拟中的粒子动力学模型构建与仿真实现粒子动力学模型是物理模拟中常用的一种模拟方法,可以用于模拟物质的运动、相互作用和变化过程。

在物理学、工程学、计算机图形学等领域中,粒子动力学模型被广泛应用于模拟和预测各种复杂的物理现象,如流体动力学、布料仿真、弹性体模拟等。

本文将介绍粒子动力学模型的构建和仿真实现的基本流程和方法。

一、粒子动力学模型构建的基本原理粒子动力学模型基于牛顿力学和某种形式的势函数,通过计算粒子间的相互作用力和动力学方程来模拟和描述物体的运动。

在粒子动力学模型中,每个粒子被赋予一定的质量、位置和速度,并受到外力和粒子间力的作用。

粒子的位置和速度随时间的推移而改变,通过数值积分方法求解粒子的运动方程,从而得到粒子的轨迹和状态变化。

1. 粒子模型的构建粒子模型的构建主要包括以下几个方面:(1)确定系统中粒子的数目和性质。

根据模拟对象的特点和需求,确定粒子的数量和性质,如质量、电荷、形状、初始位置和速度等。

(2)确定粒子间相互作用力的形式。

根据实际问题,选择适合的相互作用力模型,如弹簧力、电磁力、引力等。

(3)建立势函数。

根据粒子间的相互作用力,建立势函数,用于描述粒子间的相互作用能。

(4)确定边界条件。

根据模拟环境的特点,确定边界条件,如周期性边界条件或固定边界条件。

2. 粒子模型的动力学方程粒子模型的动力学方程起着决定性的作用,在模拟物体的运动轨迹和状态变化中起到关键作用。

根据牛顿第二定律,可以得到单个粒子的动力学方程:m * a = F (1)其中,m表示粒子的质量,a表示粒子的加速度,F表示作用在粒子上的合力。

对于一个多粒子的系统,动力学方程可以表示为:m_i * a_i = Σ_j F_ij (2)其中,m_i和a_i分别表示第i个粒子的质量和加速度,F_ij表示第i个粒子和第j个粒子之间的相互作用力。

3. 数值积分方法为了求解粒子的运动方程,需要使用数值积分方法将微分方程转化为离散的差分方程。

粒子系统PPT

粒子系统PPT

粒子系统建模方法
以主流的建模工具3DS Max为例。
单击“粒子系统”创建面板的 “喷射”按钮,然后在视图中 单击并拖动鼠标,到适当位置 后释放鼠标左键即可
粒子系统建模的需求
粒子系统表达的物体越真实,粒子的数量就 越多,其代价就越大。 寻求效果与技术平衡的方法。
谢谢大家的聆听!
粒子系统的实现
通常粒子系统在三维空间中的位置与运 动是由发射器控制的。 粒子拥有自己的属性,包括位置、速度、 颜色和生命期等。 使用大概值而不是绝对值的模糊参数内部就可以创建、 修改粒子系统,如 3DS Max、Maya以 及 Blender 等。这些编辑程序使艺术家能 够立即看到他们设定的特性或者规则下粒子 系统的表现。 另外还有一些插件能够提供增强的粒子系统 效果,例如 AfterBurn 以及用于流体 的 RealFlow。
三维真实物理建模技术 ——粒子系统
讲授人:
什么是粒子系统
物理建模指的是虚拟对象的质量、重量、惯 性、表面纹理(光滑或粗糙)、硬度、变形模 式(弹性或可塑性)等特征的建模,形成更具 有真实感的虚拟环境。 粒子系统是一种典型的物理建模系统。 粒子系统由大量称为粒子的简单体素构成。
粒子系统的作用
在虚拟现实中,粒子系统常用于描述火 焰、水流、雨雪、旋风、喷泉等现象。

使用Blender进行粒子模拟教程

使用Blender进行粒子模拟教程

使用Blender进行粒子模拟教程Blender是一款功能强大的三维建模和动画软件,其中的粒子系统是其独特而重要的功能之一。

通过使用粒子系统,用户可以模拟各种物体的效果,如火焰、雨水、尘埃等等。

在本教程中,我们将学习如何使用Blender进行粒子模拟。

首先,打开Blender并创建一个新的场景。

在默认的布局中,我们可以看到一个立方体已经存在于场景中。

我们可以在场景中任何一个位置添加粒子系统。

选择立方体并切换到“粒子”选项卡。

在“粒子系统”面板中,点击“+”按钮来添加一个新的粒子系统。

默认情况下,粒子系统将被命名为“ParticleSystem”。

接下来,我们需要设置粒子的基本属性。

在“基本”选项卡中,我们可以调整粒子的数量、生命周期以及粒子的初始速度和方向。

通过调整这些参数,我们可以改变粒子的行为。

在“物理”选项卡中,我们可以对粒子的物理模拟进行更详细的设置。

例如,我们可以模拟重力、风力和碰撞等效果。

通过调整这些参数,我们可以实现更真实的效果。

现在,我们需要选择粒子的外观。

在“渲染”选项卡中,我们可以选择粒子的形状和材质。

默认情况下,粒子将被渲染为点,但我们也可以选择其他形状,如圆柱体或球体。

通过调整材质设置,我们还可以改变粒子的颜色、透明度和反射等效果。

在这里,我们可以实现各种各样的视觉效果,使粒子看起来更加真实。

除了基本的粒子设置,Blender还提供了许多高级的粒子功能。

例如,我们可以使用力场来控制粒子的移动路径。

我们可以选择一个“力”对象并将其应用于粒子系统,使粒子围绕力场或在其周围运动。

另外,我们还可以使用纹理来影响粒子的分布和行为。

通过选择一个纹理,并将其应用于粒子系统,我们可以实现诸如颗粒随机分布或根据纹理图像进行粒子发射的效果。

当我们完成了粒子系统的设置后,我们可以在场景中预览粒子的效果。

通过点击“模拟”选项卡中的“播放”按钮,我们可以看到粒子如何随时间变化。

如果我们满意结果,我们可以在渲染前进行一些其他的调整。

unity使用粒子系统的基本步骤及应用(一)

unity使用粒子系统的基本步骤及应用(一)

unity使用粒子系统的基本步骤及应用(一)Unity使用粒子系统的基本步骤及应用1. 什么是Unity粒子系统?Unity粒子系统是一种用于创建和模拟粒子效果的工具。

它可以模拟各种物理现象和特效,如火焰、爆炸、烟雾、雨水等。

使用粒子系统,可以轻松地实现令人赏心悦目的动画效果。

2. Unity粒子系统的基本步骤创建粒子系统对象在Unity中,创建粒子系统需要进行以下步骤:•在Hierarchy面板中点击右键,选择“Effects” ->“Particle System”;•在Scene面板中,调整粒子发射器的位置、旋转和缩放。

调整粒子系统属性在Inspector面板中,可以调整粒子系统的各种属性来达到特定的效果。

以下是一些常见的属性:•Start Lifetime:粒子的生命周期,即粒子从出现到消失的时间;•Start Speed:粒子的初始速度;•Start Size:粒子的初始大小;•Gravity Modifier:粒子受到的重力影响程度;•Color over Lifetime:粒子颜色随时间变化的规律。

添加粒子效果Unity提供了丰富的内置粒子效果,可以直接在Inspector面板中进行选择和调整。

例如:•Smoke:烟雾效果,可用于模拟爆炸、火焰等情景;•Sparks:火花效果,可用于模拟火焰、电击等特效;•Rain:雨水效果,可用于模拟下雨天气。

自定义粒子效果除了使用内置的粒子效果外,还可以自定义粒子系统的外观和行为。

以下是一些常见的自定义方法:•Texture Sheet Animation:使用动画纹理来控制粒子的外观,可以创建流动的火焰、螺旋的烟雾等效果;•Noise Module:添加噪声模块,可以使粒子系统的移动和外观更加随机和自然;•Sub Emitters:添加子发射器,可以在父粒子的基础上再次发射新的粒子,产生更复杂的效果。

3. Unity粒子系统的应用游戏特效Unity粒子系统在游戏中广泛应用于创造炫目的特效,如爆炸、火焰、魔法等。

C++游戏基础物理建模之粒子系统模拟

C++游戏基础物理建模之粒子系统模拟

本节内容主要讲解了在GDI中粒子的运用,为后续DirectX中粒子系统的讲解提供一个初步的认识。

一.基础知识讲解1.基本概念粒子是一种微小的物体,在数学上通常用点来表示其模型。

我们可以把粒子想象成颗粒状的物体,如雪花,雨滴,沙尘,烟雾等特殊的事物。

又比如游戏中的怪物,晶体,材料,在需要的时候,也可以通过粒子来实现。

俗话说“不积跬步,无以至千里,不积小流,何以成江海”,单个的粒子是比较平凡的存在,但是如果将大量的粒子聚到一起,就可以实现很多神奇的效果了。

在C/C++中想要定义一个粒子是非常容易的。

基本功扎实的朋友们肯定马上就可以想到,“结构体“是用来定义粒子类型的绝佳武器。

原则上用“类”也可以实现,但是在这里采用“结构体”将更加合适。

2.实现方法如下面的这个结构体snow便是用来定义“雪花”粒子的:1.struct snow2.{3.int x; //雪花的 X坐标4.int y; //雪花的 Y坐标5.BOOL exist; //雪花是否存在6.};可以看出,上述结构体中有3个成员,分别是代表X坐标的x,代表Y坐标的y,与表示雪花是否存在的布尔型变量exist。

定义完粒子的结构体后,便可以实例化一个粒子数组了。

如果我们需要一个大小为50的snowfly数组,则可用一下两种方法来进行:<1>在结构体的尾部加上我们需要实例化的对象1.struct snow2.{3.int x; //雪花的 X坐标4.int y; //雪花的 Y坐标5.BOOL exist; //雪花是否存在6.}snowfly[50];<2>单独定义1.snow snowfly[50];定义完之后,就可以在这个粒子数组的基础上,用代码进行相关功能的实现了。

以上就是粒子系统概念的一个简明扼要的讲解。

而下面我们依旧是通过一个实例来巩固本节所学。

二、详细注释的源代码欣赏在贴出全部的源代码之前,我们先把最关键的部分提出来先剖析一下,下面是本节实例的核心代码:1.//全局变量声明2.HINSTANCE hInst;3.HBITMAP bg,snow,mask; //用于贴图的三个HBITMAP变量4.HDC hdc,mdc,bufdc;5.HWND hWnd;6.RECT rect;7.int i,count; //定义count用于计数8.9.//****自定义绘图函数*********************************10.// 1.窗口贴图11.// 2.实现雪花纷飞的效果12.void MyPaint(HDC hdc)13.{14.15.//创建粒子16.if(count<50) //当粒子数小于50时,产生新的粒子,设定每个粒子的属性值17. {18. drop[count].x = rand()%rect.right; //将粒子的X坐标设为窗口中水平方向上的任意位置19. drop[count].y = 0; //将每个粒子的Y坐标都设为"0",即从窗口上沿往下落20. drop[count].exist = true; //设定粒子存在21. count++; //每产生一个粒子后进行累加计数22. }23.24.25.//贴上背景图到mdc中26. SelectObject(bufdc,bg);27. BitBlt(mdc,0,0,640,480,bufdc,0,0,SRCCOPY);28.29.//首先判断粒子是否存在,若存在,进行透明贴图操作30.for(i=0;i<50;i++)31. {32.33. Sleep(1);34.if(drop[i].exist)35. {36. SelectObject(bufdc,mask);37. BitBlt(mdc,drop[i].x,drop[i].y,20,20,bufdc,0,0,SRCAND);38.39. SelectObject(bufdc,snow);40. BitBlt(mdc,drop[i].x,drop[i].y,20,20,bufdc,0,0,SRCPAINT);41.if(rand()%2==0)42. drop[i].x+=5;43.else44. drop[i].x-=5;45. drop[i].y+=10;46.if(drop[i].y > rect.bottom)47. {48. drop[i].x = rand()%rect.right;49. drop[i].y = 0;50. }51. }52.53. }54.55.56.//将mdc中的全部内容贴到hdc中57. BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);58.59.}MyPaint函数的书写思路是,先初始化每个粒子,这里是共50个粒子。

3DS Max中的粒子模拟教程:打造震撼的粒子效果

3DS Max中的粒子模拟教程:打造震撼的粒子效果

3DS Max中的粒子模拟教程:打造震撼的粒子效果3DS Max是一款常用于三维建模和动画制作的软件。

其中的粒子模拟功能可以创建出震撼人心的粒子效果。

本文将详细介绍如何使用3DS Max中的粒子模拟功能来打造出令人惊艳的粒子效果。

步骤一:准备工作1. 在3DS Max中创建一个新的场景。

2. 在场景中创建一个对象,作为粒子的发射器。

可以选择球体、盒子或其他几何体作为发射器。

3. 在发射器上应用一个粒子系统。

选择“粒子系统”选项,并在属性编辑器中进行设置。

可以调整粒子的发射速度、数量和角度等参数。

步骤二:创建基础粒子效果1. 在属性编辑器中,选择“发射器”选项,然后在“初始速度”下拉菜单中选择“颗粒”。

2. 调整“速度”参数,以控制粒子的初始速度。

3. 在“生命周期”选项中,调整粒子的寿命。

可以设定粒子在场景中存在的时间长度。

4. 在“粒子外观”选项中,可以选择粒子的大小、形状和颜色。

可以通过更改材质或应用纹理来改变粒子的外观。

步骤三:添加物理效果1. 在属性编辑器中,选择“动力学”选项。

这将允许你为粒子添加物理效果。

2. 在“重力”选项中,可以调整粒子受到的重力大小和方向。

这将影响粒子下落的速度和路径。

3. 调整“空气阻力”参数,以模拟空气对粒子的阻力效应。

这将改变粒子飞行的路径和速度。

4. 可以通过调整“碰撞”选项来为粒子添加碰撞效果。

选择一个或多个对象作为碰撞物体,并设置碰撞的反弹力度和摩擦力。

步骤四:使用力场1. 在属性编辑器中,选择“力场”选项。

2. 在场景中添加一个力场对象。

可以选择不同类型的力场,如吸引力场、斥力场或涡旋力场。

3. 调整力场的参数,以控制其影响范围和强度。

4. 将力场应用到粒子系统中,可以使粒子受到力场的作用而改变方向和速度。

步骤五:调整参数和效果1. 在属性编辑器中,不断调整粒子系统的参数,直到获得满意的效果。

可以尝试改变速度、寿命、大小和颜色等属性,以及添加更多的粒子效果。

快速学会使用Blender进行粒子模拟

快速学会使用Blender进行粒子模拟

快速学会使用Blender进行粒子模拟Blender是一款功能强大的开源三维建模软件,被广泛应用于动画制作、游戏开发以及虚拟现实等领域。

其中,粒子模拟是Blender的重要功能之一,它可以让用户模拟各种自然现象,比如火焰、烟雾、雨滴等,使作品更加逼真生动。

本文将介绍如何快速学会使用Blender进行粒子模拟。

首先,打开Blender软件并创建一个新的场景。

在3D视图窗口中,选择"粒子"选项卡,即可开始进行粒子模拟。

接下来,我们需要为物体添加粒子系统。

在属性编辑器中选择"粒子"选项卡,在"粒子系统"面板中点击"+New"按钮,即可创建一个新的粒子系统。

然后,我们可以根据需要对粒子系统进行调整。

在"粒子系统"面板中,可以设置粒子的发射器类型、发射速度、方向等属性。

可以通过调整这些属性来实现不同的效果。

例如,如果我们想模拟火焰效果,可以选择"火焰"发射器类型。

然后,调整发射速度和方向,使粒子呈现出火焰扩散的形状。

在"粒子系统"面板中,还可以设置粒子的寿命、大小、颜色等属性。

通过调整这些属性,可以使粒子在模拟过程中呈现出符合预期的效果。

除了基本属性调整,Blender还提供了一系列高级功能,用于进一步优化粒子模拟效果。

例如,可以使用力场模拟器来模拟粒子受到的力的影响,可以使用碰撞模拟器来模拟粒子与其他物体之间的碰撞效果等等。

在进行粒子模拟之前,我们还可以在属性编辑器中选择"物理"选项卡,进行粒子预览。

通过预览,可以实时查看粒子模拟的效果,并根据需要调整各种参数,以达到理想的效果。

在进行粒子模拟之后,还可以对模拟结果进行进一步的渲染。

在属性编辑器中选择"渲染"选项卡,可以对粒子的材质、阴影、光照等进行设置。

渲染完成后,可以将结果保存为图片或视频,以供后续使用或分享。

游戏设计之粒子系统

游戏设计之粒子系统
M
粒子系统
粒子系统是粒子的集合,用来保存和显示这些粒子。粒子系 统维护所有粒子的全部属性,影响系统中的所有粒子:粒子 的尺寸,起始的位置及应用在粒子上的纹理等。 粒子系统主要负责更新(updating)、显示(displaying)、杀死 (kill)和创建(creating)粒子。 把粒子系统公共的属性放到一个抽象的cParticleSystem基类
M
粒子和点精灵


粒子及其属性
一个粒子系统是由除了位置、颜色以外的更多的属性组成,例如, 一个粒子可具有速度。然而,这些额外的属性对于渲染粒子来说 不是必须的。因此,在单独的结构中保存渲染粒子所必须的数据 和属性。当创建、显示或更新粒子时,使用属性来工作。当准备 渲染时,从sParticle(粒子)结构中COPY位置和颜色。 对于模拟的具体粒子系统,粒子的属性也是不同的 ,因此能够归
纳一些通用的属性

M

struct sParticleAttribute { sParticleAttribute() { life_time = 0.0f; age = 0.0f; is_alive = true; }
粒子和点精灵
D3DXVECTOR3 position; //粒子在世界空间中的位置 D3DXVECTOR3 velocity; //粒子的速度,每秒多少个单位 D3DXVECTOR3 acceleration; //粒子的加速度 float life_time; // how long the particle lives for before dying float age; // current age of the particle D3DXCOLOR color; // current color of the particle D3DXCOLOR color_fade; // how the color fades with respect to time bool is_alive; };
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

本节内容主要讲解了在GDI中粒子的运用,为后续DirectX中粒子系统的讲解提供一个初步的认识。

一.基础知识讲解1.基本概念粒子是一种微小的物体,在数学上通常用点来表示其模型。

我们可以把粒子想象成颗粒状的物体,如雪花,雨滴,沙尘,烟雾等特殊的事物。

又比如游戏中的怪物,晶体,材料,在需要的时候,也可以通过粒子来实现。

俗话说“不积跬步,无以至千里,不积小流,何以成江海”,单个的粒子是比较平凡的存在,但是如果将大量的粒子聚到一起,就可以实现很多神奇的效果了。

在C/C++中想要定义一个粒子是非常容易的。

基本功扎实的朋友们肯定马上就可以想到,“结构体“是用来定义粒子类型的绝佳武器。

原则上用“类”也可以实现,但是在这里采用“结构体”将更加合适。

2.实现方法如下面的这个结构体snow便是用来定义“雪花”粒子的:1.struct snow2.{3.int x; //雪花的 X坐标4.int y; //雪花的 Y坐标5.BOOL exist; //雪花是否存在6.};可以看出,上述结构体中有3个成员,分别是代表X坐标的x,代表Y坐标的y,与表示雪花是否存在的布尔型变量exist。

定义完粒子的结构体后,便可以实例化一个粒子数组了。

如果我们需要一个大小为50的snowfly数组,则可用一下两种方法来进行:<1>在结构体的尾部加上我们需要实例化的对象1.struct snow2.{3.int x; //雪花的 X坐标4.int y; //雪花的 Y坐标5.BOOL exist; //雪花是否存在6.}snowfly[50];<2>单独定义1.snow snowfly[50];定义完之后,就可以在这个粒子数组的基础上,用代码进行相关功能的实现了。

以上就是粒子系统概念的一个简明扼要的讲解。

而下面我们依旧是通过一个实例来巩固本节所学。

二、详细注释的源代码欣赏在贴出全部的源代码之前,我们先把最关键的部分提出来先剖析一下,下面是本节实例的核心代码:1.//全局变量声明2.HINSTANCE hInst;3.HBITMAP bg,snow,mask; //用于贴图的三个HBITMAP变量4.HDC hdc,mdc,bufdc;5.HWND hWnd;6.RECT rect;7.int i,count; //定义count用于计数8.9.//****自定义绘图函数*********************************10.// 1.窗口贴图11.// 2.实现雪花纷飞的效果12.void MyPaint(HDC hdc)13.{14.15.//创建粒子16.if(count<50) //当粒子数小于50时,产生新的粒子,设定每个粒子的属性值17. {18. drop[count].x = rand()%rect.right; //将粒子的X坐标设为窗口中水平方向上的任意位置19. drop[count].y = 0; //将每个粒子的Y坐标都设为"0",即从窗口上沿往下落20. drop[count].exist = true; //设定粒子存在21. count++; //每产生一个粒子后进行累加计数22. }23.24.25.//贴上背景图到mdc中26. SelectObject(bufdc,bg);27. BitBlt(mdc,0,0,640,480,bufdc,0,0,SRCCOPY);28.29.//首先判断粒子是否存在,若存在,进行透明贴图操作30.for(i=0;i<50;i++)31. {32.33. Sleep(1);34.if(drop[i].exist)35. {36. SelectObject(bufdc,mask);37. BitBlt(mdc,drop[i].x,drop[i].y,20,20,bufdc,0,0,SRCAND);38.39. SelectObject(bufdc,snow);40. BitBlt(mdc,drop[i].x,drop[i].y,20,20,bufdc,0,0,SRCPAINT);41.if(rand()%2==0)42. drop[i].x+=5;43.else44. drop[i].x-=5;45. drop[i].y+=10;46.if(drop[i].y > rect.bottom)47. {48. drop[i].x = rand()%rect.right;49. drop[i].y = 0;50. }51. }52.53. }54.55.56.//将mdc中的全部内容贴到hdc中57. BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);58.59.}MyPaint函数的书写思路是,先初始化每个粒子,这里是共50个粒子。

然后贴上背景图到mdc中,再用循环将各个粒子也贴到mdc中,循环完成之后,再统一将mdc中的内容直接贴到hdc中。

这样做的优点是比较直观,提高了贴图的效率。

下面就贴出全部详细注释的源代码,供大家学习,需要在自己机器上运行并学习提高的朋友,请点击文章末尾处贴出的地址进行下载。

源代码依旧是分为VC6.0和VS2010两个版本。

这里贴出的是VC6.0版的:1.#include "stdafx.h"2.#include <stdio.h>3.4.//全局变量声明5.HINSTANCE hInst;6.HBITMAP bg,snow,mask; //用于贴图的三个HBITMAP变量7.HDC hdc,mdc,bufdc;8.HWND hWnd;9.RECT rect;10.int i,count; //定义count用于计数11.12.13.14.15.struct snow16.{17.int x;18.int y;19.BOOL exist;20.}drop[50];21.22.23.//全局函数声明24.ATOM MyRegisterClass(HINSTANCE hInstance);25.BOOL InitInstance(HINSTANCE, int);26.LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);27.void MyPaint(HDC hdc);28.29.//****WinMain函数,程序入口点函数**************************************30.int APIENTRY WinMain(HINSTANCE hInstance,31.HINSTANCE hPrevInstance,32.LPSTR lpCmdLine,33.int nCmdShow)34.{35. MSG msg;36.37. MyRegisterClass(hInstance);38.39.//初始化40.if (!InitInstance (hInstance, nCmdShow))41. {42.return FALSE;43. }44.45.46.//消息循环47.while (GetMessage(&msg, NULL, 0, 0))48. {49. TranslateMessage(&msg);50. DispatchMessage(&msg);51. }52.53.return msg.wParam;54.}55.56.//****设计一个窗口类,类似填空题,使用窗口结构体*********************57.ATOM MyRegisterClass(HINSTANCE hInstance)58.{59. WNDCLASSEX wcex;60.61. wcex.cbSize = sizeof(WNDCLASSEX);62. wcex.style = CS_HREDRAW | CS_VREDRAW;63. wcex.lpfnWndProc = (WNDPROC)WndProc;64. wcex.cbClsExtra = 0;65. wcex.cbWndExtra = 0;66. wcex.hInstance = hInstance;67. wcex.hIcon = NULL;68. wcex.hCursor = NULL;69. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);70. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);71. wcex.lpszMenuName = NULL;72. wcex.lpszClassName = "maple";73. wcex.hIconSm = NULL;74.75.return RegisterClassEx(&wcex);76.}77.78.//****初始化函数*************************************79.// 1.加载位图资源80.// 2.取得内部窗口区域信息81.BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)82.{83.HBITMAP bmp;84. hInst = hInstance;85.86. hWnd = CreateWindow("maple", "浅墨的绘图窗口" , WS_OVERLAPPEDWINDOW,87. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);88.89.if (!hWnd)90. {91.return FALSE;92. }93.94. MoveWindow(hWnd,10,10,600,450,true);95. ShowWindow(hWnd, nCmdShow);96. UpdateWindow(hWnd);97.98. hdc = GetDC(hWnd);99. mdc = CreateCompatibleDC(hdc);100.101. bufdc = CreateCompatibleDC(hdc);102. bmp = CreateCompatibleBitmap(hdc,640,480);103.104. SelectObject(mdc,bmp);105.106.107.108.109. bg = (HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,rect.right,rect.bott om,LR_LOADFROMFILE);110. snow = (HBITMAP)LoadImage(NULL,"snow.bmp",IMAGE_BITMAP,20,20,LR_LOADFRO MFILE);111. mask = (HBITMAP)LoadImage(NULL,"mask.bmp",IMAGE_BITMAP,20,20,LR_LOADFRO MFILE);112. GetClientRect(hWnd,&rect);113.114.115.116. SetTimer(hWnd,1,0,NULL);117.118. MyPaint(hdc);119.120.return TRUE;121.}122.123.//****自定义绘图函数*********************************124.// 1.窗口贴图125.// 2.实现雪花纷飞的效果126.void MyPaint(HDC hdc)127.{128.129.//创建粒子130.if(count<50) //当粒子数小于50时,产生新的粒子,设定每个粒子的属性值131. {132. drop[count].x = rand()%rect.right; //将粒子的X坐标设为窗口中水平方向上的任意位置133. drop[count].y = 0; //将每个粒子的Y坐标都设为"0",即从窗口上沿往下落134. drop[count].exist = true; //设定粒子存在135. count++; //每产生一个粒子后进行累加计数136. }137.138.139.//贴上背景图到mdc中140. SelectObject(bufdc,bg);141. BitBlt(mdc,0,0,640,480,bufdc,0,0,SRCCOPY);142.143.//首先判断粒子是否存在,若存在,进行透明贴图操作144.for(i=0;i<50;i++)145. {146.147. Sleep(1);148.if(drop[i].exist)149. {150. SelectObject(bufdc,mask);151. BitBlt(mdc,drop[i].x,drop[i].y,20,20,bufdc,0,0,SRCAND); 152.153. SelectObject(bufdc,snow);154. BitBlt(mdc,drop[i].x,drop[i].y,20,20,bufdc,0,0,SRCPAINT); 155.if(rand()%2==0)156. drop[i].x+=5;157.else158. drop[i].x-=5;159. drop[i].y+=10;160.if(drop[i].y > rect.bottom)161. {162. drop[i].x = rand()%rect.right;163. drop[i].y = 0;164. }165. }166.167. }168.169.170.//将mdc中的全部内容贴到hdc中171. BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);172.173.}174.175.176.177.//****消息处理函数***********************************178.LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa ram)179.{180.switch (message)181. {182.case WM_TIMER: //时间消息183. MyPaint(hdc); //在消息循环中加入处理WM_TIMER消息,当接收到此消息时便调用MyPaint()函数进行窗口绘图184.break;185.case WM_KEYDOWN: //按键消息186.if(wParam==VK_ESCAPE) //按下【Esc】键187. PostQuitMessage(0);188.break;189.case WM_DESTROY: //窗口结束消息190. DeleteDC(mdc);191. DeleteDC(bufdc);192. DeleteObject(bg);193. DeleteObject(snow);194. DeleteObject(mask);195. KillTimer(hWnd,1); //窗口结束时,删除所建立的定时器196. ReleaseDC(hWnd,hdc);197. PostQuitMessage(0);198.break;199.default: //其他消息200.return DefWindowProc(hWnd, message, wParam, lParam);201. }202.return 0;203.}下面是运行后的截图效果:可以看到窗口中有漫天飞舞的雪花,我们可以调节数组大小,及几处设定的数值的大小,来使雪花来得更猛烈些。

相关文档
最新文档