连连看C语言毕业课程设计报告.docx

上传人:b****9 文档编号:25567328 上传时间:2023-06-09 格式:DOCX 页数:23 大小:23.28KB
下载 相关 举报
连连看C语言毕业课程设计报告.docx_第1页
第1页 / 共23页
连连看C语言毕业课程设计报告.docx_第2页
第2页 / 共23页
连连看C语言毕业课程设计报告.docx_第3页
第3页 / 共23页
连连看C语言毕业课程设计报告.docx_第4页
第4页 / 共23页
连连看C语言毕业课程设计报告.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

连连看C语言毕业课程设计报告.docx

《连连看C语言毕业课程设计报告.docx》由会员分享,可在线阅读,更多相关《连连看C语言毕业课程设计报告.docx(23页珍藏版)》请在冰豆网上搜索。

连连看C语言毕业课程设计报告.docx

连连看C语言毕业课程设计报告

(此文档为word格式,下载后您可任意编辑修改!

问题描述

连连看是一款简单有趣的小游戏,曾经风靡一时,玩家要将相同的两张牌用三根以内的直线连在一起就可以消除,规则简单容易上手,游戏速度节奏快,画面清晰可爱,适合细心的玩家。

游戏胜利条件的判定:

将棋盘上面的格子全部消除掉;失败的判定:

规定的时间内格子没有消除。

问题分析

连连看需要解决的问题包括:

(1)整个游戏界面和各种图案的图形显示;

(2)如何判断鼠标所点的两个图像能否相消;

•(3)如何判断是否消除完全;

•(4)如何判断游戏的结束及如何终止游戏;

•(5)游戏难度的设计和得分规则

游戏总的流程可以描述如下:

首先出现游戏界面,一幅由10*6的小图片的构成的画面,玩家需要点击2个相同图案的对子,其连接线不多于3根直线,也就是说连接相同图案时,直线只能有两个折点,就可以成功将对子消除。

此外,需要重点考虑的是游戏面板和各种形状的方块的数据结构表示。

格子面板可以用一个二维数组来表示。

1、开发工具的介绍

【VS2008】

VS2008引入了250多个新特性,整合了对象、关系型数据、XML的访问方式,语言更加简洁。

使用VisualStudio2008可以高效开发Windows应用程序。

设计器中可以实时反映变更,XAML中智能感知功能可以提高开发效率。

同时VisualStudio2008支持项目模板、调试器和部署程序。

VisualStudio2008可以高效开发Web应用,集成了AJAX1.0,包含AJAX项目模板,它还可以高效开发Office应用和Mobile应用。

VS的开发界面分为两个版本:

整合模式和孤立模式,分别对基于语言的开发和基于特别工具的开发作了优化。

【EasyX】

EasyX是针对C++的图形库,可以帮助C语言初学者快速上手图形和游戏编程。

许多学编程的都是从C语言开始入门的,而目前的现状是:

  1.有些学校以TurboC为环境讲C语言,只是TurboC的环境实在太老了,复制粘贴都很不方便。

  2.有些学校直接拿VC来讲C语言,因为VC的编辑和调试环境都很优秀,并且VC有适合教学的免费版本。

可惜在VC下只能做一些文字性的练习题,想画条直线画个圆都很难,还要注册窗口类、建消息循环等等,初学者会受严重打击的。

初学编程想要绘图就得用TC,很是无奈。

  3.还有计算机图形学,这门课程的重点是绘图算法,而不是Windows编程。

所以,许多老师不得不用TC教学,因为Windows绘图太复杂了,会偏离教学的重点。

新的图形学的书有不少是用的OpenGL,可是门槛依然很高。

所以,于是就有了EasyX库方便的开发平台和TC简单的绘图功能。

2、设计

【程序总体结构】:

【界面设计】:

界面的设计通过插入背景图片beijing.bmp,在对每一个格子的赋图片,通过getimage()从board.bmp中截下所需要的图,再利用putimage()放置每一个小图。

具体算法:

loadimage(&beijing,"D:

\\llk\\beijing.bmp");载入背景图

putimage(0,0,&beijing);放置背景图

for(inti=0;i

for(intj=0;j

{

idy=i*54+board_Y,idx=j*48+board_X;

putimage(idx,idy,&image[board[i+1][j+1]]);根据赋的值放置每一个格子图

}

beijing.bmp

board.bmp

【重要数据的数据结构设计】:

structBOARD点击的格子信息

{

inttx,ty;格子坐标

intxx,yy;屏幕坐标

intdata;图片类型

};

定义BOARD型的结构体,里面包含的是鼠标点击以后,所读取的点击点在屏幕里的坐标(xx,yy)

在二维数组里的坐标board[tx][ty],以及在给每一个二维数组元素赋的值data(用来判断两个格子是否相等,相等以后赋值为0,以便判断是否存在格子,为之后的寻找路径铺垫)

intboard[ROW+2][COL+2];

二维数组,用来记录格子的信息,其值是判定是否有方块的标志。

MOUSEMSGmouse;

鼠标的记录类型structMOUSEMSG

{

UINTuMsg;当前鼠标消息

boolmkCtrl;Ctrl键是否按下

boolmkShift;Shift键是否按下

boolmkLButton;鼠标左键是否按下

boolmkMButton;鼠标中键是否按下

boolmkRButton;鼠标右键是否按下

intx;当前鼠标x坐标(物理坐标)

inty;当前鼠标y坐标(物理坐标)

intwheel;鼠标滚轮滚动值

};

#defineboard_X140格子区距左边框距离

#defineboard_Y140格子呢区距上边框距离

#defineCOL10格子区列数

#defineROW6格子区行数

#defineboard_number15游戏图片数目

【函数设计】:

函数的功能列表:

voidInit();初始化界面

voidload_picture();加载图片

voiddel(BOARD&rec);每个格子赋值为

voidleftbottondown(MOUSEMSGmouse);实现鼠标左击效果

voidframe(intleftx,intlefty);画边框

booljudge_mouse(intleftx,intlefty);判断鼠标是否在游戏区

voidselect(intleftx,intlefty);显示选中效果

voidaccurate(int&leftx,int&lefty);使格子的坐标都在边缘

voidcover(intx1,inty1,intx2,inty2,intx3,inty3,intx4,inty4);覆盖直线

voidline(intx1,inty1,intx2,inty2,intx3,inty3,intx4,inty4);用直线连接

voidexchange(BOARD&pre,BOARD&cur);交换格子信息

boolclick(intmousex,intmousey);判断单击是否有效

voidrecord(intleftx,intlefty,BOARD&rec);记录选中的格子

voidmouse_to_board(intmousex,intmousey,int*idx,int*idy);鼠标的坐标转为格子的数组下标

intfindpath(BOARD&pre,BOARD&cur);寻找路径,判断是否相等

voidprogressbar();画进度条

voidupdateprogressbar(longt);更新进度条

因为有许多的函数是执行图像处理以及坐标转化的简单操作,这里画出包含关键算法的主要函数的流程图,其他的函数只做文字的描述介绍。

findpath(BOARD&pre,BOARD&cur)函数

cover(intx1,inty1,intx2,inty2,intx3,inty3,intx4,inty4)函数

Init()函数

load_picture()函数:

这是一个类似于初始图片的函数,利用loadimage,SetWorkingImage,对含有格子图片信息的图进行分割读取,并存入image[]的IMAGE类型的数组里,同时还读入了填充背景的图(填充线条)。

del(BOARD&rec)函数:

删除函数,将之前记录的鼠标信息全部赋值为0;

leftbottondown(MOUSEMSGmouse)函数:

记录鼠标的信息,如果鼠标是第一次点击的话,将其信息存入pre里,如果鼠标是第二次点击的话,将其存入cur里,通过findpath()函数来相消与否,如果能相消,则将鼠标点的两块区域覆盖,同时调用del函数,来清除信息,在此过程中,根据统计剩余格子对数的变量counter,来给出分数(用s[]数组来存储分数信息,并在相应位置输出)。

frame(intleftx,intlefty)函数:

根据导入的参数画一个格子边框。

judge_mouse(intleftx,intlefty)函数:

判断鼠标的点击区域是否在规定的范围里。

select(intleftx,intlefty)函数:

在鼠标点击选择以后,显示frame的效果,并记录数据。

accurate(int&leftx,int&lefty)函数:

规范坐标的函数,鼠标点击的区域是在一个范围内的,此函数能把属于一个区域的坐标归整为统一的坐标。

line(intx1,inty1,intx2,inty2,intx3,inty3,intx4,inty4)函数:

连线函数,通过导入的点的坐标来调用moveto,lineto函数画线。

exchange(BOARD&pre,BOARD&cur)函数:

交换格子信息的函数,在点击2次后,发现两个格子并不能相消后,将pre取第二次点击的格子信息。

click(intmousex,intmousey)函数:

判断点击的地方是不是有效,即已经被消去的格子,点击时,没有像有格子的地方一样会出现线框的情况。

record(intleftx,intlefty,BOARD&rec)函数:

将鼠标的屏幕坐标转化并记录在BOARD类型的变量里。

mouse_to_board(intmousex,intmousey,int*idx,int*idy)函数:

将鼠标的坐标转化为格子信息。

progressbar()函数:

画进度条,作矩形,并填充相应颜色。

updateprogressbar(longt)函数:

进度条的更新函数,读取当前系统时间与游戏开始时系统时间的差,来画图覆盖进度条,从而达到进度条运动的效果。

【程序运行整体视图】

3、源程序

#include

a:

b

#defineDGREE2时间条的运动速度

structBOARD点击的格子信息

{

inttx,ty;格子坐标

intxx,yy;屏幕坐标

intdata;图片类型

}pre,cur,dur;

IMAGEimage[board_number+1];图片库

IMAGEtianchong;填充图片

IMAGEtianchong1;覆盖分数的图片

IMAGEtianchong2;覆盖分数的图片

intboard[ROW+2][COL+2];游戏图纸

MOUSEMSGmouse;

intcounter=board_number*2;

voidInit();初始化界面

voidload_picture();加载图片

voiddel(BOARD&rec);每个格子赋值为

voidleftbottondown(MOUSEMSGmouse);实现鼠标左击效果

voidframe(intleftx,intlefty);画边框

booljudge_mouse(intleftx,intlefty);判断鼠标是否在游戏区

voidselect(intleftx,intlefty);显示选中效果

voidaccurate(int&leftx,int&lefty);使格子的坐标都在边缘

voidcover(intx1,inty1,intx2,inty2,intx3,inty3,intx4,inty4);覆盖直线

voidline(intx1,inty1,intx2,inty2,intx3,inty3,intx4,inty4);用直线连接

voidexchange(BOARD&pre,BOARD&cur);交换格子信息

boolclick(intmousex,intmousey);判断单击是否有效

voidrecord(intleftx,intlefty,BOARD&rec);记录选中的格子

voidmouse_to_board(intmousex,intmousey,int*idx,int*idy);鼠标的坐标转为格子的数组下标

intfindpath(BOARD&pre,BOARD&cur);寻找路径,判断是否相等

voidprogressbar();画进度条

voidupdateprogressbar(longt);更新进度条

intfindpath(BOARD&pre,BOARD&cur)

{

inti,j,path,min1,max1,min2,max2,left,right,top,bottom;

intm,n;

if(board[pre.ty][pre.tx]!

=board[cur.ty][cur.tx])判断是否点中相同

returnfalse;

min1=max1=pre.tx;

min2=max2=cur.tx;

while(min1-1>=0&&board[pre.ty][min1-1]==0)min1--;查找水平方向公共区域

while(min2-1>=0&&board[cur.ty][min2-1]==0)min2--;

left=max(min1,min2);左边界

while(max1+1<=11&&board[pre.ty][max1+1]==0)max1++;

while(max2+1<=11&&board[cur.ty][max2+1]==0)max2++;

right=min(max1,max2);右边界

if(left==0)

{

line(pre.tx,pre.ty,0,pre.ty,0,cur.ty,cur.tx,cur.ty);左边缘连通

Sleep(300);

cover(pre.xx,pre.yy,board_X-48,pre.yy,board_X-48,cur.yy,cur.xx,cur.yy);覆盖线条

returntrue;

}

if(right==11)

{

line(pre.tx,pre.ty,11,pre.ty,11,cur.ty,cur.tx,cur.ty);

Sleep(300);

cover(pre.xx,pre.yy,board_X+480,pre.yy,board_X+480,cur.yy,cur.xx,cur.yy);覆盖线条

returntrue;

}

for(i=left;i<=right;i++)

{

path=0;记录竖直方向上的长度

m=min(pre.ty,cur.ty);

n=max(pre.ty,cur.ty);

for(j=m+1;j

{

path=path+board[j][i];

if(path>0)break;

}

if(path==0)

{

line(pre.tx,pre.ty,i,pre.ty,i,cur.ty,cur.tx,cur.ty);

Sleep(300);

cover(pre.xx,pre.yy,board_X+(i-1)*48,pre.yy,board_X+(i-1)*48,cur.yy,cur.xx,cur.yy);覆盖线条

returntrue;

}

}

min1=max1=pre.ty;查找垂直方向公共区域

min2=max2=cur.ty;

while(min1-1>=0&&board[min1-1][pre.tx]==0)min1--;

while(min2-1>=0&&board[min2-1][cur.tx]==0)min2--;

top=max(min1,min2);

while(max1+1<=7&&board[max1+1][pre.tx]==0)max1++;

while(max2+1<=7&&board[max2+1][cur.tx]==0)max2++;

bottom=min(max1,max2);

if(top==0)

{

line(pre.tx,pre.ty,pre.tx,0,cur.tx,0,cur.tx,cur.ty);同在顶端消除

Sleep(300);

cover(pre.xx,pre.yy,pre.xx,board_Y-54,cur.xx,board_Y-54,cur.xx,cur.yy);覆盖线条

returntrue;

}

if(bottom==7)

{

line(pre.tx,pre.ty,pre.tx,7,cur.tx,7,cur.tx,cur.ty);

Sleep(300);

cover(pre.xx,pre.yy,pre.xx,board_Y+324,cur.xx,board_Y+324,cur.xx,cur.yy);覆盖线条

returntrue;

}

for(j=top;j<=bottom;j++)

{

path=0;记录水平方向的长度

m=min(pre.tx,cur.tx);

n=max(pre.tx,cur.tx);

for(i=m+1;i

{

path+=board[j][i];

if(path>0)break;

}

if(path==0)

{

line(pre.tx,pre.ty,pre.tx,j,cur.tx,j,cur.tx,cur.ty);

Sleep(300);

cover(pre.xx,pre.yy,pre.xx,board_Y+(j-1)*54,cur.xx,board_Y+(j-1)*54,cur.xx,cur.yy);覆盖线条

returntrue;

}

}

returnfalse;

}

voidInit()初始化

{

intix,iy,jx,jy,idx,idy,temp;

srand((unsigned)time(NULL));

load_picture();

IMAGEbeijing;

for(inti=0,x=1;x<=ROW;++x)

{

for(inty=1;y<=COL;++y)

{

board[x][y]=i++%board_number+1;

}

}

loadimage(&beijing,"D:

\\llk\\beijing.bmp");载入背景图

putimage(0,0,&beijing);放置背景图

getimage(&tianchong,3*48,2*);

getimage(&tianchong1,3*48,2*);

getimage(&tianchong,55);

for(intk=0;k<60;++k)

{

ix=rand()%ROW+1;

iy=rand()%COL+1;

jx=rand()%ROW+1;

jy=rand()%COL+1;

if(board[ix][iy]!

=board[jx][jy])使数据打乱

{

temp=board[ix][iy];

board[ix][iy]=board[jx][jy];

board[jx][jy]=temp;

}

}

for(inti=0;i

for(intj=0;j

{

idy=i*54+board_Y,idx=j*48+board_X;

putimage(idx,idy,&image[board[i+1][j+1]]);根据赋的值放置每一个格子图

}

setbkmode(TRANSPARENT);

setfont(35,0,"华文琥珀");

setcolor(YELLOW);

outtextxy(700,100,"分数");

outtextxy(700,150,"000");

}

voidload_picture()

{

IMAGEimage1,background;

loadimage(&image1,"D:

\\llk\\board.bmp");

SetWorkingImage(&image1);

for(inti=1;i<=board_number;i++)

getimage(&image[i],0,i*54,48,54);

loadimage(&background,"IMAGE","bg");

SetWorkingImage(&background);

getimage(&tianchong,3*56,2*);

SetWorkingImage();

putimage(0,0,&background);

}

voidleftbottondown(MOUSEMSGmouse)单击左键

{

staticintclick1=0,x,y;

chars[3];

intnumber,i;

click1++;

select(mouse.x,mouse.y);显示选中效果

if(click1==1)

{

record(mouse.x,mouse.y,pre);

}

if(click1==2)

{

mouse_to_board(mouse.x,mouse.y,&x,&y);

if(x!

=pre.tx||y!

=pre.ty)

{

record(mouse.x,mouse.y,cur);

if(findpath(pre,cur))

{

board[pre.ty][pre.tx]=board[cur.ty][cur.t

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1