C语言吃金豆游戏程序设计实验报告

更新时间:2024-06-25 10:27:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

实训报告

实训题目: 吃金豆游戏程序设计 院 系: 计算机科学与工程学院 专 业: 软件工程(单招) 学 号: 092213112 姓 名: 刘泽中 指导教师: 周荣 实训地点: N6-109 开课时间: 至 学年第 学期

常熟理工学院计算机科学与工程学院 制

常熟理工学院

学生姓名 刘泽中 实训报告成绩 评语:

指导教师(签名) 年 月 日

说明:指导教师评分后,实训报告交院办公室保存。

092213112 刘泽中

目录

1.实训的目的和任务 ...................................................... 3

1.1实训目的 ......................................................... 3 1.2实训任务 ......................................................... 3 2.开发环境 .............................................................. 3

2. 1 硬件环境 ........................................................ 3 2.2 软件环境 ......................................................... 3 3.PACMAN游戏功能描述与分析 .............................................. 4

3.1功能描述: ....................................................... 4 3.2游戏软硬件最低标配设施: ......................................... 5 3.3需求分析 ......................................................... 6 3.4总体功能要求 ..................................................... 6 3.5程序用到的知识点 ................................................. 6 3.6游戏各功能流程图 ................................................. 6 4.程序详细分析 .......................................................... 9

4.1 部分函数功能描述 ................................................. 9 4.2 结构体的定义 .................................................... 10 4.3部分函数源码分析 ................................................ 10 4.4 程序运行界面图示 ................................................ 22 5.个人总结 ............................................................. 26

实训报告要求与排版字号:

1.实训报告排版打印统一用A4(21 X 29.7cm)格式。

2.标题用小二号黑体加粗,正文用四号宋体。行距为固定值20磅。 3.页面上边距2.54cm,下边距2.54 cm,左边距3cm,右边距2.2cm; 4. 实训报告页码从正文页面起计算。页码字号,选用小四号粗黑体并居中。

常熟理工学院

092213112 刘泽中

1.实训的目的和任务

1.1实训目的

进一步加深、巩固所学专业课程(《C语言程序设计》)的基本理论知识,理论联系实际,进一步培养自己综合分析问题和解决问题的能力。掌握运用C语言独立地编写、调试应用程序和进行其它相关设计的技能。

使学生在掌握C语言的基本语法的基础上,能够更好的理解和运用其解决实际问题。在实践实习操作中让学生对结构化程序设计有更进一步深刻的认识与了解,提高学生的实践操作能力。

1.2实训任务

1.2.1游戏基本功能:

游戏屏幕是一个 NxN 的网格,其中某些格子是固定的墙壁,其他网格是可以通行的,开始的时候放满了金豆。游戏开始后,玩家通过键盘的方向键控制游戏主角PACMAN移动,经过的地方,金豆被吃掉,同时加分。游戏屏幕上还有一个怪物,它会随机地移动。PACMAN如果碰到怪物,游戏失败。如果吃掉了全部金豆,则游戏成功。

1.2.2附加功能

1.2.2.1. 游戏主菜单:开始游戏、查看成绩排行榜、退出游戏等项目。

1.2.2.2. 每次游戏成功结束,要求输入用户名,并记录成绩到文件score.txt。如果已有同名用户,且本次得分更高,则替代之。在显示排行榜时,按得分高低排序。 1.2.2.3. 使用不同的关卡,即使用多个场景文件 scene(0-n).txt,在开始游戏时选择。 1.2.2.4. 加入声音效果,吃到金豆时,Win/Lost时显示不同的声音。

2.开发环境

2. 1 硬件环境

常熟理工学院软件实验室机房九章楼N6-109机房12号机器 2.2 软件环境

092213112 刘泽中

3.6.5 退出程序流程图 (略)

4.程序详细分析

4.1 部分函数功能描述

4.1.1 void init();/*用于图形模式初始化*/

4.1.2 void initPacman(Face *face,int r,int c,int size,int x0,int y0)

/*pacman的一些初始值设置(坐标,初始位置,大小等)*/

4.1.3 void initMonster(Monster *monster,int x,int y,enum Direction dir)

/*Monster的一些初始设置(坐标,运动方向)*/

4.1.4 void drawBlock(int i,int j)/*用于画整个地图盘面*/ 4.1.5 void drawBall(int i,int j)/*用于画地图上的金豆*/ 4.1.6 void drawWall(int i,int j) /*画地图中的墙*/

4.1.7 void drawGame()/*调用上面三个函数,完成整个地图的绘制*/ 4.1.8 void drawPacman(Face *face)/*画主角Pacman*/

4.1.9 void drawmonster(int i,int j,int color)/*画第二男主角Monster*/ 4.1.10 void delays()/*设置延时,用于处理动画效果,易修改*/ 4.1.11 void drawCaidan()/*用于绘画选择关卡里面的提示菜单界面*/ 4.1.12 void moveFace(Face *face)/*移动第一男主角Pacman*/

4.1.13 void moveMonster(Monster *monster)/*移动第二男主角Monster*/ 4.1.14 void clearFace(int i,int j)/*清除第一男主角Pacman的图案*/ 4.1.15 void clearMonster(int i,int j) /*清除第二男主角Monster的图案*/ 4.1.16 void changeDir(Face *face,enum Direction dir)/*调整Pacman运动方向*/ 4.1.17 void srandMonster(Monster *monster)/*为Monster随机产生一个方向*/ 4.1.18 void Win()/*显示赢了的画面并输出分数*/ 4.1.19 void gameOver()/*显示输了的画面并输出分数*/ 4.1.20 void DoError()/*输了的声音*/ 4.1.21 void DoWin()/*赢了的声音*/

4.1.22 void DoOK()/*第一男主角Pacman改变一次方向的声音*/ 4.1.23 void gamePlay()/*整个游戏的主要核心函数*/ 4.1.24 void showLevel()/*在屏幕上输出第几关的函数*/

常熟理工学院

4.1.25 void loadLevel()/*读取相应等级的地图函数*/

4.1.26 void Help()/*选择关卡里面F8键对应产生的帮助信息*/ 4.1.27 void softHighscore()/*排行榜的显示*/ 4.1.28 void chooseKard()/*选择关卡主界面*/

4.1.29 void showMenu()/*程序运行开始前显示五彩的游戏名称Pacman*/ 4.1.30 void Menu()/*游戏的主菜单*/

4.1.31 int main()/*主函数用于调用init及Menu来实现整个程序的运转*/

4.2 结构体的定义

4.2.1 Pacman的定义: typedef struct{

int r,c;

int startX,startY; int isLive;

enum Direction dir;

}Face;/*定义Pacman,成员包括坐标,起始位置,死活的标志以及运动方向*/ 4.2.2 Monster的定义: typedef struct{ int x; int y;

enum Direction dir;

}Monster; /*定义Monster,成员包括坐标,运动方向*/

4.3部分函数源码分析

4.3.1 图形模式初始化函数

void init(){ int gdriver,gmode; gdriver=DETECT;

initgraph(&gdriver,&gmode,\ cleardevice();/*清屏*/ }

4.3.2 文件的读取函数

void loadFile(){

092213112 刘泽中

FILE *fp; int i,k=0,m=0;

if((fp=fopen(\判断文件是否能打开*/

printf(\ exit(1);

}

for(i=0;i<8;i++){/*格式化读取函数*/

fscanf(fp,\ }

fclose(fp);/*关闭文件*/ }

4.3.3 对文件内的信息进行排序

void sortHighscore(){/*运用选择法进行排序*/ int i,k,j; int temp; char temp2[20]; for(i=0;i<9;i++){ k=i;

for(j=i+1;j<9;j++)

if(highScorescore[j]>highScorescore[k]) k=j;

temp=highScorescore[k];/*拷贝分数到中间变量*/

strcpy(temp2,highScorename[k]); /*拷贝姓名到中间变量*/ highScorescore[k]=highScorescore[i]; strcpy(highScorename[k],highScorename[i]); highScorescore[i]=temp; strcpy(highScorename[i],temp2); }

saveHighscore();/*调用saveHighscore()函数将排好序的函数写入文件*/

}

4.3.4 画地图界面函数 void drawGame(){

常熟理工学院

int i,j,size;

till=0;/*用于计算地图中金豆的总个数*/ for(i=0;i<10;i++)

for(j=0;j<10;j++)

str2[i][j]=str[i][j];/*拷贝地图用于gamePlay里面的判断*/ for(i=0;i<10;i++)

for(j=0;j<10;j++)

if(str[i][j]==0)/*如果是0就是路,否则就是墙*/

drawBlock(i,j);/*画路*/ else drawWall(i,j);/*画墙*/

size=imagesize(ORGX+1*W,ORGY+1*H,ORGX+1*W+W-1,ORGY+1*H+H-1); buff=(void*)malloc(size); /*计算缓存大小,把格子存入缓存区用于清除*/

getimage(ORGX+1*W,ORGY+1*H,ORGX+1*W+W-1,ORGY+1*H+H-1,buff); for(i=0;i<10;i++)

}

4.3.5 画第一男主角Pacman

void drawPacman(Face *face){ int x0,y0;

x0=ORGX+face->c*W+W/2;/*计算男主角的中心坐标*/

y0=ORGY+face->r*W+W/2; setfillstyle(1,RED); setcolor(RED);

if(face->dir==RIGHT){ /*默认方向右*/

clearFace(face->r,face->c); /*擦除Pacman*/

pieslice(x0,y0,30,330,12); /*画扇形*/

pieslice(x0,y0,0,360,12);/*画圆,制作动画效果*/ delays(); /*延时,制作动画效果*/ }else{

for(j=0;j<10;j++) }

if(str[i][j]==0){/*如果是路的话*/

drawBall(i,j);/*画金豆*/ till++;/*金豆的总个数加1*/

092213112 刘泽中

setcolor(RED);

circle(x0,y0,12); /*画圆*/ floodfill(x0,y0,RED); /*填充红色*/ setfillstyle(1,WHITE); setcolor(WHITE);

delays(); /*延时*/

switch(face->dir){ case UP: /*上*/

pieslice(x0,y0,60,120,12);break; pieslice(x0,y0,240,300,12);break;

pieslice(x0,y0,150,210,12);break;

case DOWN: /*下*/ case LEFT: /*左*/ } }

}

4.3.6 Pacman的移动(Monster移动与之相仿,故略)

void moveFace(Face *face){

switch(face->dir){/*if语句用来判断是否为墙*/ }

4.3.7 Pacman的清除(Monster清除与之相仿,故略)

void clearFace(int i,int j){/*将存入缓存的那一块图取出来覆盖*/ putimage(ORGX+j*W,ORGY+i*H,buff,COPY_PUT);

}

4.3.8 随机产生怪物方向的函数

case UP:if(str[face->r-1][face->c]==0) face->r--;break; case DOWN:if(str[face->r+1][face->c]==0) face->r++;break; case LEFT:if(str[face->r][face->c-1]==0) face->c--;break; case RIGHT:if(str[face->r][face->c+1]==0) face->c++;break;

}

092213112 刘泽中

loadMap();/*读地图*/ showLevel();/*显示地图等级*/ gamePlay();/*开始游戏*/ if(sumball==till) Win();

flag=0;/*退出循环标志*/

}else if(pg==2){level=pf+4;/*第二页的*/ levelAlone();

loadMap(); /*读地图*/ showLevel(); gamePlay();

if(sumball==till) /*判断赢了没*/

Win();

flag=0; }break;

}

setcolor(BLACK); setfillstyle(0,BLACK);

rectangle(orgx-2,orgy-2,orgx+9*mw+mw-1+2,orgy+9*nw+nw-1+2);

rectangle(orgx-10,orgy-10,orgx+9*mw+mw-1+10,orgy+9*nw+nw-1+10);

floodfill(orgx-5,orgy-5,BLACK);/*画选择地图的外方框*/ switch(pf){

case 1:orgx=35;orgy=20;break;/*地图位置坐标*/ case 2:orgx=260;orgy=20;break; case 3: orgx=35;orgy=250;break; case 4: orgx=260;orgy=250;break; }

setcolor(WHITE); setfillstyle(1,WHITE);

rectangle(orgx-2,orgy-2,orgx+9*mw+mw-1+2,orgy+9*nw+nw-1+2);

rectangle(orgx-10,orgy-10,orgx+9*mw+mw-1+10,orgy+9*nw+nw-1+10);

floodfill(orgx-5,orgy-5,WHITE);

常熟理工学院

putimage(510,20,buff2,COPY_PUT);/*取出缓存图像覆盖*/ setcolor(BLUE); settextstyle(2,0,6); if(pg==1){

sprintf(s,\输出选择地图的等级*/ outtextxy(540,70,s); }else if(pg==2){

sprintf(s,\第二页的地图等级*/ outtextxy(540,70,s); } } getch(); }

4.3.13 主界面函数 void Menu(){ int f=1;

本处略去作图代码(比较长)

while(f){/*While循环实现光标上下滚动的效果*/

switch(m){

case 1: setcolor(GREEN);

settextstyle(0,0,4);

outtextxy(240,160,\未选中,绿色*/ settextstyle(0,0,4);

setcolor(WHITE);/*其余未选中的为白色,下同*/ outtextxy(132,242,\ int p=0; char s[30]; int key; int m;

outtextxy(160,320,\ outtextxy(250,400,\

case 2: setcolor(GREEN);

092213112 刘泽中

settextstyle(0,0,4);

outtextxy(132,242,\ settextstyle(0,0,4); setcolor(WHITE);

outtextxy(240,160,\ outtextxy(160,320,\ outtextxy(250,400,\ case 3: setcolor(GREEN);

settextstyle(0,0,4);

outtextxy(160,320,\ settextstyle(0,0,4); setcolor(WHITE);

outtextxy(240,160,\ outtextxy(132,242,\ outtextxy(250,400,\ case 4: setcolor(GREEN);

settextstyle(0,0,4); outtextxy(250,400,\ settextstyle(0,0,4); setcolor(WHITE);

outtextxy(240,160,\ outtextxy(132,242,\ outtextxy(160,320,\ }

key=bioskey(0); switch(key){

case UP: if(m<2) m=4;else m--;break;

/*可实现从最下面可再按下回的最上面*/

case DOWN: if(m>3)m=1;else m++;break;

case ENTER: if(m==1) {f=0;p=1;}/*f为while循环的结束标志*/

else if(m==2) {f=0;p=2;} else if(m==3){f=0;p=3;} else if(m==4){f=0;p=4;}break;

}

常熟理工学院

}

if(p==1){loadLevel();}/*开始游戏,先读取等级*/ else if(p==2) {chooseKard();}/*选择关卡*/ else if(p==3) {softHighscore();}/*查看排行榜*/ else exit(0);}

4.3.14 主函数 int main(){

init();/*图形模式初始化*/

showMenu();/*显示游戏名称*/

Menu();/*调用主界面函数*/ cleardevice();/*清屏*/

getch();

closegraph();/*关闭图形模式*/

}

4.4 程序运行界面图示

4.4.1 程序开始界面

092213112 刘泽中

4.4.2 游戏主界面

4.4.3 开始游戏主界面

常熟理工学院

4.4.4 选择关卡界面图a

4.4.5 选择关卡界面图b

4.4.6 输入地图路径界面

092213112 刘泽中

4.4.7 排行榜界面图

4.4.8 等级显示界面图

常熟理工学院

5.个人总结

这次的实训为期十天,算是很长很长的了,第一天我看到了实训要求后觉得很简单,一看那些地图,不就是一些些个小方块拼成的嘛,于是当天下午我就画按要求画出了棋盘,当天晚上实现了Pacman吃金豆的功能,第二天早上加入了妖怪,基本就已经完成主要任务。但是事实上并没有我想象中那么简单,当天下午同学那我程序试玩一下发现程序有许多BUG,比如说妖怪会吃金豆,妖怪会吃妖怪,妖怪会生产金豆,Pacman碰到妖怪有时死不掉有时死的掉等等BUG,于是第二天下午带晚上我都是在找BUG,修复BUG的。修复BUG比写程序困难多了,至少我是这样认为的,有时候代码里的“=”号不小心写成了“==”号这种细小的错误很难查出来,而这两个符号执行出来的效果是完全不一样的。

修复BUG的过程中,我深深感悟到了程序的严谨性以及好的算法的重要性。当我完成了基本功能后我并没有停留,而是去慢慢实现老师列出的附加功能。十天说长也很长,说短也不短。十天的实训不但锻炼了我们的编程水平,而且提高了我们的坚韧性。如果能在一个找了两个个小时都找不出来的BUG面前心如止水,那么你就成功了。每每遇到一个新的BUG,我都会很平静的去对待,慢慢看,仔细研究。我相信,这次实训中所遇到的问题、困难,我们都用心去解决了,在我们往后的编程道路上,一定会有所帮助。

在实训过程中,对所学的知识点有了更加深刻的理解,通过实践操作对图形体统的初始化和关闭、各种画图函数的使用、结构体的定义及使用、数组的定义及使用、函数嵌套及调用和键盘操作这些重要知识点进行了巩固,达到了实训的基本目的,同时在编写代码的过程中也体会到了C语言具有的语句简洁、使用灵活、执行效率高等特点。

遇到一些不会的知识点,比如说sound函数,我就去查阅资料,上网找列子,去想办法弄懂它,然后把它加入到我的程序里来,让我的程序更加完美。这种自主学习的方法极大的促进了自己的动手能力及独立思考能力,开发了自己的逻辑思维能力,培养了分析问题、解决问题的能力。深刻体会到“没有做不到的,只有想不到的”的寓意。当遇到一些难题能亲自动手解决它,你会发现你会很有成就感,会很快乐。遇到不会的,自主学习,学成之后又是一种满足感,这些带给我快乐的都一步一步加深我对编程的兴趣。

在程序中,我主要用到的结构体与链表,其实像这种小游戏完全可以用全

092213112 刘泽中

局变量、全局数组来做,但是我用的是结构体,结构体可以再一个结构中声明不同的数据类型,而且结构体变量是可以相互复制的,这些都是数组做不到的。而且使用结构体大大节省了内存空间,提高了效率。并且为了程序后续的一些开发提供了更方便的修改方法,比如说,在后续程序开发中若想多添加两个怪物,就可以直接定义结构体后面添加一句 Monster monster[n];然后在操作Monster的过程中,通过一个for循环,然后直接使用monster[i].x, monster[i].y来控制Monster的坐标,这样就能实现多个妖怪的运行。在后续的开发中可以设置更难的关卡,添加更多的妖怪,对于结构体来说是非常方便的。

在整个程序中,我最自豪最欣慰的就是选择关卡那个界面,我自认为做的很好,但是也是有很多不足的地方的。在我原本设想的程序里,可以通过鼠标来控制翻页、帮助、读取地图这些功能键,不需要键盘,而且在游戏中,没关都会随机产生一个小苹果,吃掉小苹果就可以反吃妖怪等等,这些其实都很简单,但由于时间关系,都没有一一实现,这也是比较遗憾的地方。另外,整个程序虽然我界面比较丰富且实现了更多的功能,但是程序并不是很严谨,算法也不是很精,而且主要的playGame做的很普通,没在游戏中加入更多的功能。

实训过程中,不仅是考察一个人的编程能力,更多的还是考察一个人的耐心。10天转瞬即逝,我们付出了多少我们也就收获了多少,在这次实训中,我感悟很多,我也学到了很多,我感到很满足。实训不仅锻炼了我们的编程能力,而且对于我们所学的知识进行了查漏补缺,搞清楚了以前C语言中不懂的知识点,使我更加了解掌握C语言。我想,这次实训对我们而言是宝贵的,更是无法替代的,我很感激老师和学校能提供我们这样一个机会,让我们可以学到专业知识以外的东西,这对我们来说,不单单是怎么样处理问题,而是培养了我们坚持不懈的精神,让我们更加有信息和勇气去面对将来更大的挑战!

六:程序源代码(略)

如有疑问请联系q497089524 版权所有,违版必究!

本文来源:https://www.bwwdw.com/article/7ux3.html

Top