您好,欢迎访问三七文档
2/21页2目录一、设计题目二、目标和需求分析三、开发工具四、应用平台五、程序模块1、游戏盒子2、20483、扫雷4、贪吃蛇六、开发日志七、程序调试及运行八、程序开发总结总结:虽然做出来的东西真的没什么技术水平,但是我们尽量把这个东西的每个方方面面做完整。3/21页3目标和需求分析一个小的游戏盒子,可以用来启动其它游戏,当然,其它游戏也是我们大作业的编写内容,平时可以玩玩用来打发时间用到的工具VS2005Easyx图形库Pthread线程库Hge分工秦贤康组织大家,编写主程序,及构思计划,技术指导王尧所有的文件处理,数据算法方面优化王懿晨合作2048模块杨梓晗图片资源加工,音乐裁剪,按钮制作程维驰合作扫雷模块应用平台:WINDOWSX644/21页4程序模块程序功能模块:一、安装包:(写入开始菜单快捷方式,桌面快捷方式,开机启动等)//pascal脚本编写#defineMyAppNameC大作业#defineMyAppVersion2.0#defineMyAppPublisher五人小组#defineMyAppExeName1.exe[Setup]AppId={{49DB1DB4-FAE9-4ACB-A4B9-E5C420C5F10B}AppName={#MyAppName}AppVersion={#MyAppVersion};AppVerName={#MyAppName}{#MyAppVersion}AppPublisher={#MyAppPublisher}DefaultDirName={pf}\{#MyAppName}DisableDirPage=yesDefaultGroupName={#MyAppName}DisableProgramGroupPage=yes(剩余代码未全部给出)安装包内嵌:C语言报告游戏盒子开机启动,桌面快捷方式等快捷方式进入动画,左侧动画启动模块通知,和显示游戏信息2048扫雷贪吃蛇主界面信息显示通知栏信息显示意见箱5/21页5二、启动盒子:(用来启动各个模块的游戏)1、游戏模块(目前三个游戏)2048扫雷贪吃蛇2、通知模块暂时只有简单的实现网页支持6/21页67/21页7游戏启动盒子进入动画voidlogo(void){intw=GetSystemMetrics(SM_CXSCREEN);//1366intl=GetSystemMetrics(SM_CYSCREEN);//768全屏动画initgraph(w,l);inti;chars[20];cleardevice();HWNDhwnd=GetHWnd();Frametransparent(hwnd,0);SetWindowTransparent(hwnd,0,100,0x1|0x1);SetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_NOSIZE);//设置透明效果BeginBatchDraw();8/21页8for(i=l;il/2-300;i-=22){cleardevice();Image(gif,LOGO,w/2-210,i);FlushBatchDraw();}EndBatchDraw();for(intk=2;k29;k++)cg(k,w/2-150,l/2);Sleep(10);}voidcg(inta,intx,inty)//开场动画{chars[20];sprintf(s,LOGO%03d,a);Image(gif,s,x,y);//输出图片Sleep(100);}主界面9/21页9通知是用pthread增加的一个线程,独立,可以随时关闭通知,需要里再弹出pthread_tid;pthread_create(&id,NULL,GG1,NULL);//通知进入线程选择里面是一个判断函数,双击不同的图片有不同的返回值,然后点确定根据返回值启动不同模块,取消按钮可以取消选定10/21页102048资源定义:资源命名是与函数相关的voidshowFk(intx,inty,inttype){chars1[20];sprintf(s1,FK%d,type);//因此输出图片时只在改变一个type的值就可以输入不同的图片11/21页11Image(gif,s1,x,y);}//这样做的话两个方块合并的操作也简化成把方块的值加一核心算法大概分为两个方面:一,方块出现主要用到的是不重复随机数for(i=0;in;i++)x[i]=i;for(i=0;ik;i++){t=rand(i,n-1);swap(x[i],x[t]);out(x[i]);}//《编程珠玑》的算法把这个改了一下就可以用来随机生成方块二,方块移动1、如方块向又移动时要到最左边或者碰到方块才停止(过程中有动画模块)intmoveBlankUp()//移动方块{for(inti=0;i4;i++)for(intx=0;x4;x++)for(inty=0;y3;y++)//从上到下扫描{if(fk[x][y]==0&&fk[x][y+1]!=0)//如果某个方块上面方向是空的{fk[x][y]=fk[x][y+1];//向上移动fk[x][y+1]=0;//原来的位置变为空showFk(zbx[x],zby[y],fk[x][y]);//显示移动后的方块showFk(zbx[x],zby[y+1],fk[x][y+1]);//显示原来的空方块}}//完成移动一步return0;}2、移动时碰到相同的方块要合并(有优先原则:如2444右移变成_248,左移变成284_),合并后方块的值要加一,2的值是1,4为2,类推……3、合并不叠加原则(4444右移变成__88,而不是___16)intAddUp(void)//合并方块{for(intx=0;x4;x++)for(inty=0;y3;y++){if(fk[x][y]==fk[x][y+1]&&fk[x][y+1]!=0)//两个方块相同{12/21页12fk[x][y]++;//合并后方块的值要加一fk[x][y+1]=0;//被合并的方块消失y++;//合并不叠加原则,即跳过两个方块扫描}}return0;}编写技巧:先实现一个方向移动的功能,比如向下移动然后依次类推写出其它三个方向的,加上一个判失败条件所以主函数是这样的:#includegraphics.h#includefunction.h//功能实现放在这里#includeconio.h#includetime.h#includestdio.hintx,y;intzx,zy;//坐标intdirection;intzbx[4]={60,130,200,270};//背景上的坐标intzby[4]={60+60,130+60,200+60,270+60};intfk[4][4];//方块的数字voidmain(void){reset();//初始化界面while(fflush(stdin),direction=getch()){if(judgeDown()+judgeUp()+judgeLeft()+judgeRight()==0)//四个方向都不能移动,则输了gotogend;switch(direction){case'S':playdown();break;case'W':playup();break;case'D':playright();break;case'A':playleft();break;default:;//工程中应该保留有未知情况处理}}getchar();gend:cleardevice();outtextxy(160,20,You输了);Sleep(5000);closegraph();/*图形结束*/}13/21页13扫雷用一维数组,这样查询效率最高,因为方块数量是固定的算法:1、生成地雷。先规定一个地雷数量,再用一个不重复随机数生成算法生成地雷inti,t,tp;for(i=0;i100;i++)x1[i]=i;//给数组赋值//把雷生成for(i=0;i12;i++){t=rand()%(100-i)+i;//产生i到100的随机数tp=x1[i];x1[i]=x1[t];x1[t]=tp;//交换两个数fk[x1[i]/10][x1[i]%10]=11;//11表示这是一个地雷}《编程珠玑》里的随机数生成算法修改2、扫描地雷。为其他方块赋值。遍历每一个方块,判断周围有几个地雷。Fk[0]=1;表示第一个方块周围只有一个地雷14/21页14for(i=0;i12;i++)for(intw=-1;w=1;w++)for(intq=-1;q=1;q++)if(x1[i]/10+w=0&&x1[i]/10+w10&&x1[i]%10+q=0&&x1[i]%10+q10&&fk[x1[i]/10+w][x1[i]%10+q]!=11)fk[x1[i]/10+w][x1[i]%10+q]++;3、画出初始方块4、写一个掀开方块函数如果方块是地雷:掀开所有地雷,播放爆炸声音,扫雷失败如果不是地雷a:周围没有雷,把相邻的没有雷的全部掀开(用的是递归算法)b:周围有雷,掀开这个,显示周围地雷数量5、一个标记函数,6、一个判断扫雷成功函数15/21页15核心代码:intfkopen(intx,inty)//掀开方块{if(x=0&&x10&&y=0&&y10)//10x10个方块之内{if(fks[x][y]==0)//方块未打开{fks[x][y]=1;fko++;showFk(x*30+50,y*30+100,fk[x][y]);setcolor(BLUE);rectangle(x*30+50+4,y*30+100+4,x*30+50+24,y*30+100+24);if(fk[x][y]==0){for(inti=-1;i=1;i++)for(intj=-1;j=1;j++)fkopen(x+i,y+j);//递归调用}elseif(fk[x][y]==11)//11表示这是一个雷{win=-1;//输了for(inti=0;i12;i++)//显示所有雷{//创建线程pthread_tpid;pthread_create(&pid,NULL,test,NULL);showFk(x1[i]/10*30+50,x1[i]%10*30+100,11);Sleep(400);}}}//printf(%d,fko);if(fko=100-12)win=1;//win=1表示赢fko是掀开方块个数雷全部扫完,暂定12个地雷}return0;}16/21页16贪吃蛇主界面,可以选择难度,不同的难度Sleep(speed);的时间,speed的大小不同,就是蛇移动的速度不同。有加速和暂停功能,因为这个贪吃蛇有接近2000行的代码,(第一次写,不会分cpp写),所以就不多上代码了核心算法:没有按键的时候,蛇按原来方向行走,有按键就改变方向吃到食物,长度变化每个关卡蛇的移动进度条背景音乐碰到东西加速暂停奖励惩罚死亡统计总分数,写入文件主界面排行榜选择难度进入游戏退出三个关卡数据处理,回到主界面添加玩家姓名读取/创建score.txt17/21页17撞墙判死排行榜数据结构:用的文件存储,并将成绩进行排序,因为每次只增加一个数据,所以采用的是插入排序voidrank(void){fp=fopen(score.txt,r);intn,a[12],k=1;//最多存12个成绩charb[12][12];fscanf(fp,%d\n,&n);for(inti=1;i=n;i++){fscanf(fp,%s%d,&b[i],&a[i]);if(a[i]totalscore)k=i+1;}fclose(fp);还原按钮用来清空数据进入游戏先输入用户姓名18/21页18InputBox(name,20,请输入姓名,玩家姓名,王尧,20,100);//输入用户第一关
本文标题:C语言大作业报告
链接地址:https://www.777doc.com/doc-5160533 .html