基本操作:
initgraphics(void)
操作结果;图形模式的初始化 rainDrop *creatDrop(void)
操作结果;构造雨点
drawRainLine(struct rainDrop *p)
初始条件:
雨点已经产生 操作结果;画雨点下落路线 creatRain(void) 初始条件:
雨点已经产生
操作结果;产生雨连续下落的效果 setwinddirection(struct rainDrop *p)
初始条件:
雨点已经开始下落
操作结果:
风向的设置(无风,东风,西风 updateRainLineData(struct rainDrop *p)
初始条件:
雨点已经产生 操作结果;雨点的下落过程更改
updateRainCircleData and floatradius(struct rainDrop *p)
初始条件:
雨点已经出现且落在湖面上 操作结果;水圈涟漪的设计
rainDropDown(struct rainDrop *p)
初始条件:
雨点下落到湖面
操作结果;使雨点在落到湖面上消失 drawRainCircle(struct rainDrop *p)
初始条件:
水圈涟漪已存在 操作结果;水圈涟漪的画出
clearRainLine(struct rainDrop *p)
初始条件:
雨点已经出现且已经画出了一段痕迹 操作结果;清除雨点的滑落路线 clearRainCircle(struct rainDrop *p)
初始条件:
水圈涟漪已存在 操作结果;清除水圈涟漪 clearAll(void)
操作结果:
清除所有 }ADT graphList
程序的主要模块包括四个部分:
(1)主函数:
voidmain()
(2)设定雨滴:
creatDrop(void)structrainDrop*prainLineLength(structrainDrop*p)
(3)结束end
各模块调用关系
主程序
雨的设置
3详细设计
StructrainCircle//定义水圈的相关数据
{//横坐标、纵坐标、路线步骤、水圈半径等等}
Structraindrop//定义雨点下落的过程的数据
{//包括雨点开始结束的坐标,颜色,路径,长度,对是否到达水面的判断,水圈的产生以及指向下一个雨点}
Voidinitgraphics(void)//图形函数的初始化
{
intgmodegdiver;
gdriver=DETECT;
initgraph(&gdriver,&gmode,“C:
//TC20//BGI”)
//其中gdriver和gmode分别表示图形驱动器和模式,“C:
//TC20//BGI”是指的图形驱动程序所在的目录路径,由于使用的是虚拟的TURBOC编译器,其指定路径是“C:
//TC20//BGI”。
Structraindrop*creatDrop(void)//雨点开始产生时的随机设置
{
Structraindrop*p;
P=(structraindrop*)molloc(LEN);
p->startX=rand()%640;//随机产生的位置X
p->startY=rand()%430;//随机产生的位置Y
p->endY=430+rand()%50;//结束坐标
p->curX=p->startX;//每个雨点消失的横坐标
p->curY=p->startY;//每个雨点消失的纵坐标
p->rainLineStep=8:
//共分8个步骤
p->rainColor=rand()%15+1;//彩色的随机产生
p->rainLineLenth=rand()%10+10;//雨点大小的随即产生
p->status=0;
p->water.x=p->startX;
p->water.y=p->startY;//随机产生的涟漪的位置
p->water.r=p->rand()%45;//随机产生涟漪的半径
p->water.curR=rand()%3;//涟漪消失的半径
p->water.rainCircleStep=rand()%3+1;
p->next=NULL;
return(p);
}
VoidrecreatatDrop(structraindrop*p)//重复产生雨点
{//跟雨点开始的随机设置是一样的}
VoidcreatRain(void)//重复雨点的产生,使之连续不断
{//用随机产生雨点,重复产生,使得雨点连续不断}
voidupdateRainLineData(structrainDrop*p)
{//这个是每次下落雨点的数目}
voiddrawRainLine(structrainDrop*p)
{//画出雨点的下落的轨迹}
voidclearRainLine(structrainDrop*p)
{//清除雨点的轨迹
if(p->curY<=400)
setcolor(BLACK);//判断是否到了水面,不是的话就是黑色的
line(p->startX,p->startY,p->curX,p->curY);
if(p->curY>400)
setcolor(BLUE);//到了水面之后用蓝色清除雨点的轨迹
line(p->startX,p->startY,p->curX,p->curY);
}
voidrainDropDown(structrainDrop*p)//构造雨点的下落效果
{//如果发生坐标大于结束坐标,雨点的下落效果产生
if(p->curY>=p->endY)
{
clearRainLine(p);
p->status=1;
}
else
{
clearRainLine(p);//清除原来雨点的轨迹
updateRainLineData(p);//产生新雨点的线路
drawRainLine(p);//画出新路线
}
}
voidupdateRainCircleData(structrainDrop*p)
{//水圈的消失半径
p->water.curR+=p->water.rainCircleStep;
}
voiddrawRainCircle(structrainDrop*p)
{//画出水圈的半径,包括颜色和大小}
voidclearRainCircle(structrainDrop*p)//消除水圈
{//由于池塘是蓝色的,所以用蓝色来刷新水圈的填充色
setcolor(BLUE);
circle(p->water.x,p->water.y,p->water.curR);
}
voidfallToWater(structrainDrop*p)
{//这个是落水的动画}
voidrain(void)//下雨的动画
{//里面有个计时器,构造下雨的动画}
voidclearAll(void)//清除所有的东西
{//里面有个closegraph是用来关闭图像的}
main()//主函数
{intw;
printf("InputrainDropNumber:
(<300)");
scanf("%d",&rainDropNumber);//输入雨量,小于300
printf("InputdownDelay:
(<50)");
scanf("%d",&downDelay);//输入雨点下落速度,小于50
randomize();
initgraphics();
setbkcolor(BLACK);//画出背景
setfillstyle(1,BLUE);
bar(0,390,640,480);//构造池塘
creatRain();
rain();
clearAll();//调用各个模块
}
开始
输入雨量
输入雨速
画夜幕池塘
产生雨点
雨点路径
结束
关闭图像
继续?
清除水圈
画出水圈
清除路径
否
是
4编码测试
输入界面,输入雨点数,雨速
输入雨量50,雨速1
输入雨量150,雨速1
5设计体会
选题的时候,主要是这个主题吸引了我,池塘夜降彩色雨,一听名字就是要做出一个动画出来的,所以很好奇做出来是什么效果,然后就想尝试一下。
一接触的时候无从下手,从来没有用过图形库。
然后一开始用的是vc来编程,怎么也弄不出来,后来发现vc中没有tc中的graphics.h的库。
然后就开始在网上找关于这个库的资料,慢慢的从画一个圆圈入手,慢慢的把图形做出来,勉勉强强的把效果弄出来了,能力有限,本来想加一个风的效果的,可是做不出来,只能做出夜降彩色雨。
有点遗憾。
这个程序中使用的就是简单的链表,采用带头结点的循环链表,仅需改变头尾两个指针即可。
creatRain,drawRainLine和rainDropDown以及确定链表中第一个结点和之后一个结点的运算时间都是O(l),销毁雨点线路算法clearRainLine和销毁水圈算法clearRainCircle都是对每个元素调用一个O
(1)的函数,因此都是O(n),也有简单的图表的应用,也有对链表的的应用,即双向循环链表的使用。
课程设计做完了,做的不完美,还有好多不足的地方,还有没有加上其他特效有点遗憾,但是经过自己的努力做出了以前没做过的东西,收获了不少,也有点成就感。
6参考文献
[1]严蔚敏.数据结构(C语言版)[M].清华大学出版社2008年11月
[2]严蔚敏.数据结构题集(C语言版)[M].清华大学出版社2008年11月
7程序源代码在文件夹中