程序设计实习报告题目:模拟下雨学院:计算机与通信工程学院专业:计算机科学与技术班级:计算1402姓名:张田浩学号:1407010220一、需求分析1、本程序要求模拟下雨过程,要有雨点落下并有雨点落地时的水圈效果2、雨滴在屏幕出现的位置是随机的,雨圈的位置要和雨线对应,并且雨圈的大小要是随机的来增强效果3、雨要一直下,不受程序员控制二、总体设计1.利用easyx把TC下的graphics.h函数导入到了VC6.0中来实现绘图功能,并且调用”initgraphics”函数初始化图形模式600*480,2.雨滴和雨圈可以看作两个结构体,而且雨圈的结构体可以嵌套咋雨滴的结构体中3.程序主要分为五大模块(1)主函数voidmain()(2)雨点产生模块structdrop*creatDrop(void),voidrecreatDrop(structdrop*p),voidcreatRain(void)(3)雨点下落模块voidupdateRainLineData(structrainDrop*p),voiddrawRainLine(structrainDrop*p),voidclearRainLine(structrainDrop*p),voidrainDropDown(structrainDrop*p)(4)水纹生成模块voidupdateRainCircleData(structrainDrop*p),voiddrawRainCircle(structrainDrop*p),voidclearRainCircle(structrainDrop*p)(5)控制模块voidrain(void),voidclearAll(void)我的任务:负责雨点产生和下落模块及最后的调试,编写实习报告。三、详细设计1.雨圈的结构体structrainCircle雨点落下造成的水圈{intx;雨圈的圆心坐标inty;intr;水圈的半径intcurR;中间过程水圈的半径intrainCircleStep;水圈每次扩张的增量};2.雨线的结构体structrainDrop{intstartX;雨点开始的X值intstartY;雨点开始的Y值intendY;雨点结束的Y值intcurX;雨点降落中的X值intcurY;雨点降落中的Y值intrainLineStep;雨线每次的增量intrainLineLength;雨线的长度intstatus;表示下落过程是否完成structrainCirclewater;嵌套的雨圈结构体structrainDrop*next;用于创建动态链表的指针};3.动态链表的创建和释放structrainDrop*head;structrainDrop*p1,*p2;inti;p1=p2=creatDrop();head=p1;for(i=0;in;i++){p2=creatDrop();p1-next=p2;p1=p2;}在creatDrop函数中用malloc()动态分配内存4.雨线和雨圈的绘制与清除Setcolor()设定颜色,line()画线。出现时用白色画,让其消失就在原位置画一条黑线。5.三个if-else判断的核心函数(1)整个下雨的控制过程rain(){创建rainDrop类的指针p让它指向头指针;While(键盘没有输入){if(p指到表尾)p指向头指针;else{If(status==0)控制下雨;else控制形成雨圈;}延时;指针指向指向下一个;}(2)控制下雨rainDropDown(){If(当前的雨线的y坐标大于等于终点坐标){擦除上一条雨线;Status=0;}else{擦除上一条雨线;更新雨线坐标;画新雨线;}}(3)画雨圈思路和画雨线一样6.随机的实现使用”time.h”下的”rand”函数进行随机,对雨点雨圈的初始坐标,雨圈的半径,雨圈的扩张速度,延时时间进行随机。7.主函数实现过程(1)配置屏幕(2)创建链表(3)模拟下雨过程(4)下雨结束,清除链表8.使用的几个关键库函数initgraphics();kbhit();Sleep();四、编码源代码如下:#includestdio.h#includestdlib.h#includeconio.h#includetime.h#includewindows.h#includegraphics.hstructrainDrop*head;voidinitgraphics(void){intgmode,gdriver;gdriver=DETECT;initgraph(&gdriver,&gmode,);}intn=100;//雨的数目structrainCircle//雨点落下造成的水圈{intx;inty;intr;intcurR;intrainCircleStep;//水圈的顺序};structrainDrop{intstartX;//雨点开始的X值intstartY;//雨点开始的Y值intendY;//雨点结束的Y值intcurX;//雨点降落中的X值intcurY;//雨点降落中的Y值intrainColor;//雨点的颜色intrainLineStep;//雨线的顺序intrainLineLength;//雨线的长度intstatus;structrainCirclewater;structrainDrop*next;};structrainDrop*creatDrop(void){structrainDrop*p;p=(structrainDrop*)malloc(sizeof(structrainDrop));//动态分配内存p-startX=rand()%640;p-startY=rand()%430;p-endY=430+rand()%50;p-curX=p-startX;p-curY=p-startY;p-rainLineStep=8;p-rainLineLength=10;p-status=0;p-water.x=p-startX;p-water.y=p-endY;p-water.r=rand()%40;p-water.curR=rand()%2;p-water.rainCircleStep=rand()%2+1;p-next=NULL;return(p);}voidrecreatDrop(structrainDrop*p){p-startX=rand()%640;p-startY=rand()%430;p-endY=430+rand()%50;p-curX=p-startX;p-curY=p-startY;p-rainLineStep=8;p-rainLineLength=10;p-status=0;p-water.x=p-startX;p-water.y=p-endY;p-water.r=rand()%40;p-water.curR=rand()%2;p-water.rainCircleStep=rand()%2+1;}voidcreatRain(void)//创建链表{structrainDrop*p1,*p2;inti;p1=p2=creatDrop();head=p1;for(i=0;in;i++){p2=creatDrop();p1-next=p2;p1=p2;}}voidupdateRainLineData(structrainDrop*p)//控制起始雨点的Y值{p-curY+=p-rainLineStep;p-startY=p-curY-p-rainLineLength;}voiddrawRainLine(structrainDrop*p)//画雨线{setcolor(WHITE);line(p-startX,p-startY,p-curX,p-curY);}voidclearRainLine(structrainDrop*p)//以黑色表示雨线消失{setcolor(BLACK);line(p-startX,p-startY,p-curX,p-curY);}voidupdateRainCircleData(structrainDrop*p)//控制水圈的大小{p-water.curR+=p-water.rainCircleStep;}voiddrawRainCircle(structrainDrop*p)//画雨降落后的水圈{setcolor(WHITE);circle(p-water.x,p-water.y,p-water.curR);}voidclearRainCircle(structrainDrop*p)//以黑色表示水圈消失{setcolor(BLACK);circle(p-water.x,p-water.y,p-water.curR);}voidrainDropDown(structrainDrop*p)//控制雨的路径{if(p-curY=p-endY){clearRainLine(p);p-status=1;}else{clearRainLine(p);updateRainLineData(p);drawRainLine(p);}}voidfallToWater(structrainDrop*p)//控制雨圈雨点的衔接{if(p-water.curR=p-water.r){clearRainCircle(p);recreatDrop(p);}else{clearRainCircle(p);updateRainCircleData(p);drawRainCircle(p);}}voidrain()//控制全程雨的开始到结束{structrainDrop*p;p=head;while(!kbhit()){if(p==NULL)p=head;else{if(p-status==0)rainDropDown(p);elsefallToWater(p);}Sleep((rand()%2+1)/10.0);p=p-next;}}voidclearAll(void)//画图结束,释放空间{structrainDrop*p,*pf;p=head;while(p!=NULL){pf=p;p=p-next;free(pf);}closegraph();}voidmain(){initgraphics();creatRain();rain();clearAll();}五.综合测试1、在主程序中添加以下代码:printf(InputrainDropNumber:);/*输入雨点的数目*/scanf(%d,&n);printf(Inputdownspeed:);/*输入雨点的速度*/scanf(%d,&v);并定义n,v为全局变量,经过不断调试,最终确定了合适的雨点数目和雨点速度。2、由于本次编程要随机很多数据:雨圈的半径,延时时间,雨线雨圈的坐标,要是想达到好的表现效果,必须严格确定随机数的范围。initgraphics()函数已经把控制台初始化成了800*640,我们不断地调试数据,不断地改变rand()模上的数值,最终确定了雨圈半径的变化范围小于40,以控制台下方宽为50的矩形模拟地面。3、本次作业的核心算法在于链表的使用。在选择链表访问方式的时候遇到两个问题:其一是,一次访问一个结点的所有内容,继而把整个链表全部访问完毕;其二是,一次只访问所有结点的同一个位置,不断重复,从而把整个链表的内容全部访问。经过调试,发现要实现多雨点同时出现在屏幕,必须选用第二种方法。六.经验总结1.在编码前一定要先确定好需求,根据需求确定所需要的功能模块并考虑好实现功能的算法,然后把过程用伪代码和流程图的形式表示出来,这样在实际编码的时候才能事半功倍。2.要选择合适的编译环境,这次只需要使用到几个简单的绘图函数,使用mfc的话要学习的东西太多,所以我们想到