河南城建学院计算机科学与工程学院
《动画典型案例分析maya》课程设计任务书
班 级 0824101
专 业 数字媒体技术
课程名称 动画典型案例分析maya
指导教师 张向娟 白粒沙
20##年12月
《动画典型案例分析maya》课程设计任务书
一、设计的目的和任务
通过设计达到熟悉掌握maya的特效动力学模块的目的。结合之前学的视听语言知识、photoshop、premiere AE等软件用maya动力学模块及特效部分知识制作电影电视里面常见的特效。
二、课程设计要求
1设计题目,下面2个题目任选其一
题目一:结合前面所学建模、动画等知识设计制作片长为3分钟左右的特效短片(如扇舞丹青),要求有片头,片尾,片头片尾可以结合AE软件制作。
题目二:制作包含动力学知识点的特效作品内容至少10个,复杂程度适中,个人作品创作包含以下知识点:Maya粒子系统知识、流体系统知识、柔体、刚体、毛发布料特效笔刷等。
至少能实现以下效果:(1)火焰燃烧效果 (2)粒子下雪或下雨树叶飘落等效果 (3)粒子替代如万剑齐发 (4)流动云层效果(5)粒子爆炸场面 (6)流体爆炸场面 (7)海洋效果 (8)柔体如柔体墙效果 (9) 多米诺骨牌效应。剩下效果镜头自己结合所学发挥。
要求:要真实、输出镜头构图要合理。(可参考六成绩评定标准)
2 、设计项目作品创作规范
从Maya渲染出的序列帧图片要求使用Nuke或Fusion或AE合成软件进行合成,可根据需要在这个合成软件里再添加一些效果如较色、模糊、发光等,尽量让画面真实美观。针对题目二再使用Premiere剪辑软件把每个镜头效果串联起来。整合后的视频文件为.mov格式,每个镜头尺寸统一为720*576,像素宽高比为1:1,帧率为25fps。剪辑过程中,根据内容添加镜头间的过渡效果,如黑场过渡、淡入淡出等过渡效果。根据设计好的排版添加文字信息,如学生姓名、联系方式以及其他内容的解说。为视频加入音频效果,音频效果要非常符合整个视频的情绪基调。
3课程设计一人一组一题,不得出现雷同现象。
4.课程设计结束时,每人需要上交.mov格式的文件一个。同时要上交一份课程设计报告。设计报告要求在3000字左右,报告内容应有课程设计题目、二级目录、设计制作方案及脚本,在脚本中应标出景别及时间,说明素材的来源和处理、制作流程,制作技术及相应的软件等。课程设计报告要求用A4纸打印后与作品一同上交,无设计报告者不予评定成绩,有设计报告无脚本者不予评定成绩。
三、课程设计题目及内容
本课程设计需要在平面设计、数字媒体技术、数字音频技术、动画技术、视听画面语言、视频编辑技巧基础上利用maya和其它工具软件进行的一项综合性的实践性练习,是本专业专业课综合技术的运用和练习。整体设计制作与以上专业课程的关系相当紧密,是一项理论联系实际的实践,设计者须熟悉理论基础知识和各软件的综合应用和操作。
设计题目和内容必须符合目前影视特效,标题与内容要一致,视频的视听效果要明显,有较强的视听吸引力,相关素材要能与主题相吻合。画面编辑和声音的编辑要符合视听语言的要求,文字、图像、声音的应用要符合影视画面编辑的原则。
四、设计时间及地点
1、设计时间:本学期第16、17周。上午:8:00-12:00,下午:2:00-3:45。
具体时间:20##年12月23——20##年1月3日
2、设计地点:计算机系实验中心 数字媒体技术机房。10号楼A301
五、设计的时间安排
六、成绩的评定方法与评分标准
设计成绩分为“优秀、良好、中等、及格、不及格”五个等级。对于无作品或设计报告者以及出勤率少于1/3 总课时者,设计成绩为“不及格”。
优秀的作业评分标准
1)画面整体,有明确的基调和和谐的的构图
2)画面颜色搭配协调
3)表现出应有的的体积感和质感
4)特效动态效果符合物理方面的运动规律
5)空间比例关系、透视关系、环境存在关系合理
6)画面有一定的层次感和细节
7)适当的添加运动模糊和自发光效果
8)设计有构思意识,创意新颖、可行,符合阶段性所掌握内容,有分镜效果
9)具有一定的艺术表现力和视觉冲击力
10)没有明显的、突然的、中断、抖动、闪烁
11)视频规格符合项目作品创作规范(第二项2 、设计项目作品创作规范)
非优秀的作业评分标准
1)画面琐碎,繁杂,主题不明确,兴趣点丢失
2)没有颜色搭配意识,缺色,画面整体灰阶不饱和
3)没有表现出应有的的体积感和质感
4)动态效果不真实、不自然不,符合物理方面的运动规律
5)空间比例关系、透视关系、环境存在关系合理
6)表现主题丢失或缺少细节,没有层次感
7)没有运动模糊和自发光效果的渲染
8)画面表现意思不明确,内容单调,有冗长的时间停留,造成审美疲劳的状况
9)画面平淡
100有突然的中断、抖动、闪烁现象
11)视频规格与项目作品创作规范(第二项2 、设计项目作品创作规范)不相符
。
七、课程设计机房辅导值班安排
八、设计时使用的主要参考书及手册
《Maya2009高手之路》铁钟 陈前 清华大学出版社 20##年1月
《Maya2009完全学习手册》铁钟 陈前 清华大学出版社 20##年1月
《三维影视特效设计与制作》胡铮 机械工业出版社 20##年1月
《数字音频编辑Adobe Audition 3.0》石雪飞 电子工业出版社 20##年5月
《影视动画视听语言》 孙立 海洋出版社 20##年10月
第二篇:动画与游戏设计 课程设计报告
《动画与游戏开发》
课程报告
学 号: 111102020103
姓 名: 张慧
专业班级: 11级计科本01班
日 期:
电子信息工程学院
1
目录
一、 课程内容及应用领域
1.1基于DirectX的粒子系统...........................................3
1.1.1 粒子系统简介...............................................3
1.1.2广告板技术................................................. 3
1.1.3粒子系统的基本原理......................................... 3
1.2粒子系统的应用领域 ............................................. 3
二、 课程内容的难点、疑点
2.1课程要点........................................................ 4
2.2课程难点........................................................ 4
2.3课程疑点........................................................ 4 三、实例开发
3.1实例题目及说明.................................................. 4
3.2关键技术........................................................ 5
3.2.1系统完成的四部曲........................................... 5
3.2.2星光粒子结构构成技术....................................... 5
3.2.3 MyPaint()绘图函数.........................................5
3.3开发过程........................................................9
3.3.1案例所需背景图............................................10
3.3.2程序部分代码..............................................10
3.3.3运行结果截图..............................................15
3.4总结..........................................................17
四、谈谈自己对课程内容的掌握程度
2
一、课程内容及应用领域
1.课程内容:基于DirectX的粒子系统 相关内容简介:
(1)粒子系统简介
粒子系统是三维图形编程领域中用于实现特殊效果的一种非常重要的技术.该技术是由Reeves于19xx年首次提出来的.通过粒子系统可以使用非常简单的粒子来构造复杂的物体,它为模拟动态的不规则物体,提供了强有力的技术手段。一般情况下,粒子的几何特征十分简单,可以用一个像素或一个小的多边形来表示.如果给出了粒子中心点的坐标和粒子大小,不难计算出绘制粒子所需要的四个顶点的位置坐标.
(2)广告板技术
由于通常使用平面图形而不是立体图形表示一个粒子,所以需要使用的粒子四边形始终面向观察者.这就要使用广告板技术.广告板技术的原理是,在渲染一个多边形时,首先根据观察方向构造一个旋转矩阵,利用该矩阵旋转多边形使其面向观察者,如果观察方向不断变化,就要不断旋转多边形.
(3)粒子系统的基本原理
粒子通常都是一个带有纹理的四边形。我们通过这个使用了纹理映射的四边形,可以认为粒子实际上是一个很小的网格模型,只不过是纹理赋予了它特殊的外表罢了。绘制粒子就如果绘制多边形一样简单,因为一个粒子说白了就是一个可改变大小并映射了纹理的四边形罢了。
粒子系统由大量的粒子构成,粒子是一种微小的物体,每个粒子都具有一定的属性,如位置、大小以及纹理,可能还需要颜色、透明度、运动速度、加速度、生命期等属性。我们可以把粒子想象成颗粒状的物体,如雪花,雨滴,沙尘,烟雾等特殊的事物。又比如游戏中的怪物,晶体,材料,在需要的时候,也可以通过粒子来实现。俗话说“不积跬步,无以至千里,不积小流,何以成江海”,单个的粒子是比较平凡的存在,但是如果将大量的粒子聚到一起,就可以实现很多神奇的效果了。在C/C++中,结构体“是用来定义粒子类型的绝佳武器,原则上用“类”也可以实现。
2.应用领域:
19xx年,奇才Reeves.V.T在它发表的论文《Particle Systems A Technique for Modeling a Class of Fuzzy Objects》中首次提出了粒子系统的概念。从此,粒子系统就开始广泛运用于计算机中各种模糊景物的模拟。经常使用粒子系统模拟的现象有火焰、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹或者像发光轨迹这样的抽象视觉效果等等。这些物体模型在计算机中往往很难用具体的形状、大小来描述,但是我们可以通过粒子系统的思想,去描述组成这些物体的每个元素和它的变化。
一般情况下,粒子的几何特征都十分的简单,可以采用一个像素或者是一个小的多边形来表示。需要注意的是,粒子系统的最大的缺陷是,当粒子数量达到很大的规模的时候,对运行时机器性能的要求会更加苛刻,如果机器的性能跟不上,就会显得达不到实时的运行效果。
在许多三维建模及渲染包内部就可以创建、修改粒子系统,如 3D Studio Max、Maya 以及 Blender 等。这些编辑程序使艺术家能够立即看到他们设定的特性或者规则下粒子系统的表现,另外还有一些插件能够提供增强的粒子系统效果,例如 AfterBurn 以及用于流体的 RealFlow。而2D的粒子特效软件中particleIllusion最为出色,因为他的渲染比一般 3
的3D软件快较为平面化。Combustion 这样的多用途软件或者只能用于粒子系统的Particle Studio 等都可以用来生成电影或者视频中的粒子系统。而目前,粒子系统技术被广泛用于大型3D游戏地制作中。
二、课程内容的难点、疑点
1.课程要点:
(1)星光粒子的结构构造:
struct flystar
{
int x; //星光所在的x坐标
int y; //星光所在的y坐标
int vx; //星光x方向的速度
int vy; //星光y方向的速度
int lasted; //星光存在的时间
BOOL exist; //星光是否存在
}flystar[50];
6个成员分别为,粒子坐标两个值,粒子方向两个值,持续时间lasted,和粒子是否存在的标识exist。
(2)星光粒子系统的更新
典型的粒子系统更新循环可以分为两个不同的阶段:模拟阶段和渲染阶段.每个循环执行每一帧动画.
成员函数Update负责根据当前运行时间更新整个粒子系统.该函数首先遍历离子链表中的所有粒子,根据当前粒子的存活时间计算粒子的当前位置和速度,从而实现对粒子运动轨迹的控制.然后根据粒子是否已经落到地面上,判断当前例子是否已经死亡,并删除死亡的粒子.
(3)星光粒子的运动轨迹
2.课程难点:
粒子运动轨迹的实现、粒子的更新渲染等
3.课程疑点:
(1)并不是所有的粒子都是使用由两个三角形组成的矩形来表示的。例如,在模拟雨景时,可以用两个顶点构成的一条线段来表示一个雨点粒子。同时,即使某个粒子系统中的粒子都是用矩形表示,也并不意味着在渲染粒子时,一定要使用广告板技术。例如,在模拟雪景时,通常是用矩形表示一个雪花粒子,但为了模拟学花在下降过程中随风飘舞的姿态,就不能使用广告板技术。
(2)可以不使用点精灵,而完全由程序控制每个粒子的渲染,也可以在初始化时一次性产生所有的粒子。
(3)粒子系统的效果与应用,关键在于如何描述粒子的运动轨迹,也就是构造粒子的运动函数.运动函数构造的恰当与否,直接决定仿真效果的逼真程度.
4
三、 实例开发
1.实例题目及说明
题目:基于DirectX的星光绽放 说明:本设计的星光绽放相当于是一个模拟爆炸(或者说是烟花)特效的展示,在这个案例之中,绽放点为在窗口中由随机数产生的一个位置,绽放后,会出现很多星光以不同的速度向四方飞散而去,当粒子飞出窗口后或者超出时间后便会消失。每一次爆炸所出现的粒子全部消失后,便会重新出现绽放的画面,以产生不断绽放星光的效果。
该设计运用DirectX中的粒子系统等的知识点,可在VC++的环境下进行运行,
2.关键技术
2.1粒子系统在宏观和微观上都是随时间不断变化的,一套粒子系统在它生命周期的每一刻,一般都需完成以下的四步曲的工作: (1)产生新的粒子:这一步当中,我们会根据预定的要求,产生一定数目的新粒子。粒子的各项初始属性都可以用rand函数来在一定的范围内赋上随机的值。
(2)更新现有粒子的属性:比如粒子有位置和移动速度,自旋速度等等属性,这就需要在每一帧当中根据原来的粒子的位置移动速度和自旋速度重新进行计算和赋值更新。
(3)删除已经消亡的粒子:这一步是可选的,具体情况具体分析,因为有些粒子系统中粒子是一直都存在的,没有消亡一说。在规定了粒子生命周期的一套粒子系统中,就需要判断每个粒子是否生命走到了尽头,如果是的话,那么它就game over,消亡了,得用相关代码把它从粒子系统中消除。
(4)绘制出粒子:这步没有的话什么都不是,不显示出来叫什么粒子系统啊。人家可不管你在之前做了多少工作,算了多少东西,反正玩家是要看到最终的显示效果的。
2.2 星光粒子的结构构造技术:
struct flystar
{
int x; //星光所在的x坐标
int y; //星光所在的y坐标
int vx; //星光x方向的速度
int vy; //星光y方向的速度
int lasted; //星光存在的时间
BOOL exist; //星光是否存在
}flystar[50];
2.3主要函数之一——MyPaint()绘图函数:
//全局变量声明
HINSTANCE hInst;
HBITMAP bg,star,mask; //用于贴图的三个HBITMAP变量
HDC hdc,mdc,bufdc;
HWND hWnd;
RECT rect;
int i,count; //定义count用于计数
struct flystar
{
5
int x; //星光所在的x坐标
int y; //星光所在的y坐标
int vx; //星光x方向的速度
int vy; //星光y方向的速度
int lasted; //星光存在的时间
BOOL exist; //星光是否存在
}flystar[50];
//全局函数声明
ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void MyPaint(HDC hdc);
//WinMain函数,程序入口点函数
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
MyRegisterClass(hInstance);
//初始化
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
//消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//设计一个窗口类,类似填空题,使用窗口结构体
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
6
wcex.hCursor = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "maple";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
//初始化函数
// 1.加载位图资源
// 2.取得内部窗口区域信息
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HBITMAP bmp;
hInst = hInstance;
hWnd = CreateWindow("maple", "星光绽放展示窗口" , WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd)
{
return FALSE;
}
MoveWindow(hWnd,10,10,600,450,true);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
hdc = GetDC(hWnd);
mdc = CreateCompatibleDC(hdc);
bufdc = CreateCompatibleDC(hdc);
bmp = CreateCompatibleBitmap(hdc,640,480);
SelectObject(mdc,bmp);
bg =
(HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,rect.right,rect.bottom,LR_LOADFROMFILE);
star =
(HBITMAP)LoadImage(NULL,"star.bmp",IMAGE_BITMAP,30,30,LR_LOADFROMFILE); mask =
(HBITMAP)LoadImage(NULL,"mask.bmp",IMAGE_BITMAP,30,30,LR_LOADFROMFILE); GetClientRect(hWnd,&rect);
SetTimer(hWnd,1,0,NULL);
MyPaint(hdc);
return TRUE;
}
//自定义绘图函数
// 1.窗口贴图
// 2.实现星光绽放的效果
7
void MyPaint(HDC hdc)
{
//创建粒子
if(count == 0) //随机设置爆炸点
{
int x=rand()%rect.right;
int y=rand()%rect.bottom;
for(i=0;i<50;i++) //产生星光粒子
{
flystar[i].x = x;
flystar[i].y = y;
flystar[i].lasted = 0; //设定该粒子存在的时间为零
if(i%2==0)
//按粒子编号i来决定粒子在哪个象限运动,且x,y方向的移动速度随机为1—15之间的一个值,由1+rand()%15来完成。
{
flystar[i].vx = -(1+rand()%15);
flystar[i].vy = -(1+rand()%15);
}
if(i%2==1)
{
flystar[i].vx = 1+rand()%15;
flystar[i].vy = 1+rand()%15;
}
if(i%4==2)
{
flystar[i].vx = -(1+rand()%15);
flystar[i].vy = 1+rand()%15;
}
if(i%4==3)
{
flystar[i].vx = 1+rand()%15;
flystar[i].vy = -(1+rand()%15);
}
flystar[i].exist = true; //设定粒子存在
}
count = 50;
//50个粒子由for循环设置完成后,我们将粒子数量设为50,代表目前有50颗星光 }
//先在内存dc中贴上背景图片
SelectObject(bufdc,bg);
BitBlt(mdc,0,0,rect.right,rect.bottom,bufdc,0,0,SRCCOPY);
for(i=0;i<50;i++)
8
{
if(flystar[i].exist) //判断粒子是否还存在,若存在,则根据其坐标
(flystar[i].x,flystar[i].y)进行贴图操作
{
SelectObject(bufdc,mask);
BitBlt(mdc,flystar[i].x,flystar[i].y,30,30,bufdc,0,0,SRCAND);
SelectObject(bufdc,star);
BitBlt(mdc,flystar[i].x,flystar[i].y,30,30,bufdc,0,0,SRCPAINT);
//计算下一次贴图的坐标
flystar[i].x+=flystar[i].vx;
flystar[i].y+=flystar[i].vy;
//在每进行一次贴图后,将粒子的存在时间累加1.
flystar[i].lasted++;
//进行条件判断,若某粒子跑出窗口区域一定的范围,则将该粒子设为不存在,且粒子数随之递减
if(flystar[i].x<=-10 || flystar[i].x>rect.right || flystar[i].y<=-10 ||
flystar[i].y>rect.bottom || flystar[i].lasted>50)
{
flystar[i].exist = false; //删除星光粒子
count--; //递减星光总数
}
}
}
//将mdc中的全部内容贴到hdc中
BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);
}
3.开发过程
(1)对案例整体进行选取和分析
在之前课堂做过相关案例的基础上,进行修改和创新,添加一些其他的内容.这个案例用到的知识紧扣教材,是对本学期学习程度的一个很好的检测,而且,这个实验也是在自己的能力范围之内的,可以做出来。
(2)分析清楚该案例要用到的技术和必要的环境
该案例主要运用DirectX中的粒子系统、纹理映色、点的坐标变换、光照等技术,运行环境为VC++及DirectX.
(3)找出基本的函数及坐标应用,包括所需粒子的形状、大小、颜色和位置
(4)加入所需图片和粒子,如下:
背景图:
9
星光粒子图:
(5)案例总体实现的部分程序代码:
#include "stdafx.h"
#include <stdio.h>
//全局变量声明
HINSTANCE hInst;
HBITMAP bg,star,mask; //用于贴图的三个HBITMAP变量 HDC hdc,mdc,bufdc;
HWND hWnd;
RECT rect;
int i,count; //定义count用于计数
struct flystar
{
10
int x; //星光所在的x坐标
int y; //星光所在的y坐标
int vx; //星光x方向的速度
int vy; //星光y方向的速度
int lasted; //星光存在的时间
BOOL exist; //星光是否存在
}flystar[50];
//全局函数声明
ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void MyPaint(HDC hdc);
//WinMain函数,程序入口点函数
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
MyRegisterClass(hInstance);
//初始化
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
//消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//设计一个窗口类,类似填空题,使用窗口结构体
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
11
wcex.hCursor = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "maple";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
//初始化函数
// 1.加载位图资源
// 2.取得内部窗口区域信息
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HBITMAP bmp;
hInst = hInstance;
hWnd = CreateWindow("maple", "星光绽放展示窗口" , WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd)
{
return FALSE;
}
MoveWindow(hWnd,10,10,600,450,true);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
hdc = GetDC(hWnd);
mdc = CreateCompatibleDC(hdc);
bufdc = CreateCompatibleDC(hdc);
bmp = CreateCompatibleBitmap(hdc,640,480);
SelectObject(mdc,bmp);
bg =
(HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,rect.right,rect.bottom,LR_LOADFROMFILE);
star =
(HBITMAP)LoadImage(NULL,"star.bmp",IMAGE_BITMAP,30,30,LR_LOADFROMFILE); mask =
(HBITMAP)LoadImage(NULL,"mask.bmp",IMAGE_BITMAP,30,30,LR_LOADFROMFILE); GetClientRect(hWnd,&rect);
SetTimer(hWnd,1,0,NULL);
MyPaint(hdc);
return TRUE;
}
12
//自定义绘图函数
// 1.窗口贴图
// 2.实现星光绽放的效果
void MyPaint(HDC hdc)
{
//创建粒子
if(count == 0) //随机设置爆炸点
{
int x=rand()%rect.right;
int y=rand()%rect.bottom;
for(i=0;i<50;i++) //产生星光粒子
{
flystar[i].x = x;
flystar[i].y = y;
flystar[i].lasted = 0; //设定该粒子存在的时间为零
if(i%2==0)
//按粒子编号i来决定粒子在哪个象限运动,且x,y方向的移动速度随机为1—15之间的一个值,由1+rand()%15来完成。
{
flystar[i].vx = -(1+rand()%15);
flystar[i].vy = -(1+rand()%15);
}
if(i%2==1)
{
flystar[i].vx = 1+rand()%15;
flystar[i].vy = 1+rand()%15;
}
if(i%4==2)
{
flystar[i].vx = -(1+rand()%15);
flystar[i].vy = 1+rand()%15;
}
if(i%4==3)
{
flystar[i].vx = 1+rand()%15;
flystar[i].vy = -(1+rand()%15);
}
flystar[i].exist = true; //设定粒子存在
}
count = 50;
//50个粒子由for循环设置完成后,我们将粒子数量设为50,代表目前有50颗星光 }
//先在内存dc中贴上背景图片
13
SelectObject(bufdc,bg);
BitBlt(mdc,0,0,rect.right,rect.bottom,bufdc,0,0,SRCCOPY);
for(i=0;i<50;i++)
{
if(flystar[i].exist) //判断粒子是否还存在,若存在,则根据其坐标
(flystar[i].x,flystar[i].y)进行贴图操作
{
SelectObject(bufdc,mask);
BitBlt(mdc,flystar[i].x,flystar[i].y,30,30,bufdc,0,0,SRCAND);
SelectObject(bufdc,star);
BitBlt(mdc,flystar[i].x,flystar[i].y,30,30,bufdc,0,0,SRCPAINT);
//计算下一次贴图的坐标
flystar[i].x+=flystar[i].vx;
flystar[i].y+=flystar[i].vy;
//在每进行一次贴图后,将粒子的存在时间累加1.
flystar[i].lasted++;
//进行条件判断,若某粒子跑出窗口区域一定的范围,则将该粒子设为不存在,且粒子数随之递减
if(flystar[i].x<=-10 || flystar[i].x>rect.right || flystar[i].y<=-10 ||
flystar[i].y>rect.bottom || flystar[i].lasted>50)
{
flystar[i].exist = false; //删除星光粒子
count--; //递减星光总数
}
}
}
//将mdc中的全部内容贴到hdc中
BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);
}
//消息处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_TIMER: //时间消息
MyPaint(hdc); //在消息循环中加入处理WM_TIMER消息,当接收到此消息时便调用MyPaint()函数进行窗口绘图
break;
case WM_KEYDOWN: //按键消息
if(wParam==VK_ESCAPE) //按下【Esc】键
PostQuitMessage(0);
14
break;
case WM_DESTROY: //窗口结束消息
DeleteDC(mdc);
DeleteDC(bufdc);
DeleteObject(bg);
DeleteObject(star);
DeleteObject(mask);
KillTimer(hWnd,1); //窗口结束时,删除所建立的定时器 ReleaseDC(hWnd,hdc);
PostQuitMessage(0);
break;
default: //其他消息
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
(6)运行结果截图:
星光左侧绽放
15
星光中间绽放
星光绽放到边界
16
4.总结
此次试验案例是基于DirectX技术构建的粒子系统,能够实粒子系统的基本内容,前面也提到过,本设计的星光绽放相当于是一个模拟爆炸(或者说是烟花)特效的展示,在这个案例之中,绽放点为在窗口中由随机数产生的一个位置,绽放后,会出现很多星光以不同的速度向四方飞散而去,当粒子飞出窗口后或者超出时间后便会消失。每一次爆炸所出现的粒子全部消失后,便会重新出现绽放的画面,以产生不断绽放星光的效果。
当然,本案例运用到的知识点不仅仅只有粒子系统,点坐标变换,光照文理等均有涉及,也明白了只有将各类知识信息集成应用,才能实现最真实的模拟。案例技巧上也学习到可以不使用点精灵,而完全由程序控制每个粒子的渲染,也可以在初始化时一次性产生所有的粒子。粒子系统的效果与应用,关键在于如何描述粒子的运动轨迹,也就是构造粒子的运动函数.运动函数构造的恰当与否,直接决定仿真效果的逼真程度.
案例可取之处在于案例的背景图片和星星都是可以进行修改的,可以将星光绽放改为其他的粒子特效.不过需注意的是,案例背景图片需要是.png格式,为了美观起见,背景图片颜色也不要过于鲜艳,以突出星星金光绽放的效果.
本案例也存在相当大的不足之处
,由于是参照别人开发的案例,在进行一些修改和创新后运行而成的,其中也是有许多知识点的运用还不够熟练,当然也导致案例本身存在一定的问题,比如:案例只能在一定的窗口下运行,还没有进行修改,让结果可以全屏显示,导致案例窗口扩大后,会出现绽放的星星累积到一起的情况.问题截图如下:
最后还有一个急需解决的问题,案例在VC++运行环境下运行时,一直出现错误“can`t open the file??”,至今也未弄明白这一问题出现的原因,由于这一问题的出现,导致原本可以运行处结果的实验案例在运行时一直有错误,仍未找出问题所在和解决办法.
总的来说,此次案例虽然存在一定的问题,但也是取得了不错的显示效果,希望老师能提出相关的意见和改进建议,并指导我们进行修改.
四、谈谈自己对课程内容的掌握程度
通过这次实验,对directx游戏编程这门功课有了进一步的了解,知道了如何用directx创建场景模拟,设计图形及点坐标的控制,包括基本图元的绘制,点精灵与粒子系统、雪粒子系统的实现等也加深了了解。实验既紧扣了教学知识,也检查了对本门课程的掌握程度,还让我们学以致用。虽然做的不是很完美,做出来的星光绽放依旧存在一定的缺陷,也不是那么好看,但是,毕竟是自己根据相关案例改编而成的。另外,运行的过程中,出现了许多的小问题,还好有老师指导,同学的帮助,最终运行成功了,收获还是很大的.
平常上课都是对老师给的案例进行分析,了解程序的结构和原理,看代码也是似懂非懂。所以,我觉得,对该门课程的掌握程度还是不高,还是有很多的不懂。还需要发大量的时间去研究它,多看一些有关游戏开发的书来提高自己知识,自己去开发个游戏还是有很大的难度,所以做这个实验花了很多的时间。但是,应该更加努力学习才是,而不是一味的抱怨课程太难学不懂,学不懂只能说明花的时间不够,下的功夫不够。
总的来说,基本达到了实验目的,完成了实验要求。最后,感谢老师和同学的帮忙! 17