打气球课设报告jsp.docx
《打气球课设报告jsp.docx》由会员分享,可在线阅读,更多相关《打气球课设报告jsp.docx(12页珍藏版)》请在冰豆网上搜索。
![打气球课设报告jsp.docx](https://file1.bdocx.com/fileroot1/2022-11/24/b047a1a0-3149-4bc1-bc69-ae7f95e60d68/b047a1a0-3149-4bc1-bc69-ae7f95e60d681.gif)
打气球课设报告jsp
课程设计报告
1.设计内容
程序设计题目为“打气球”游戏设计与实现,主要实现以下功能:
2,飞翔的气球(怎么飞?
随机飞,随机速度又怎么表现?
该如何记时?
)
3,打气球(怎么算打中?
打中后,气球爆炸怎么表现?
声音呢?
)
4,给我个计数器(计算打中的,飞走的,甚至击中概率)
5,成与败(怎么算胜利?
怎么算失败?
如何表现)
6,完善(结尾)
(1)使用面向对象的方法,设计并实现“打气球”游戏。
(2)气球由地平线随机产生,并向上运动;
(3)用户使用鼠标点击气球,点中气球,气球消失,分数增加100分;
(4)游戏时间为60秒,时间采用倒计时方式显示,游戏时间为0时,提示用户是否重新开始;
(5)“开始/暂停”按钮。
当点击“开始”按钮,游戏开始,按钮文字变为“暂定”;点击“暂停”按钮,游戏处于暂停状态,按钮文字变为“开始”;
(6)“退出”按钮。
点击“退出”按钮,提示是否退出信息,若确定退出,关闭程序;若取消,则回到软件运行界面。
2.设计思想和实现方法
(1)绘制游戏界面。
综合考虑绘图和控件功能的实现,使用AppWizard建立一个基于对话窗口的MFC应用程序框架,并通过控件工具栏选取绘图区域,创建“暂停/开始”按钮、“退出”按钮以及分别显示时间和分数的两个编辑框。
(2)绘制气球及地平线。
在OnPaint()函数下添加代码,创建黑色画笔和红色画刷,分别用来勾画椭圆(气球)、直线(绳子)和填充气球。
通过ExcludeClipRect()函数擦除四边,从而规定了图形显示区域。
绘图时,以椭圆中心坐标作为参考,用Ellipse()函数绘制气球,用MoveTo()、LineTo()函数画绳子和地平线。
(3)实现“退出”功能。
当点击“退出”按钮时弹出确认退出对话框,点“是”则调用OnOK()退出程序。
(4)实现“暂停/开始”功能。
首先定义一个bool型变量并初始化为1,用它的值作为if语句的判断条件实现开始和暂停的功能转换。
如果时间为0,按钮变为“重新开始”,点击后弹出确认重新开始对话框,选择“是”重新开始游戏;游戏开始后单击按钮,用KillTimer()实现暂停功能,按钮变为“开始”;再点击则重新调用SetTimer()开启计时器,按钮变为“暂停”。
(5)随机产生多个气球。
定义一个二维数组,第一维表示随机产生的气球数目,第二维表示气球中心坐标。
在OnTimer事件中,响应绘图事件时,通过纵坐标递减实现气球上升,并使用rand()函数使横纵坐标随机变化实现气球的随机摆动,当气球升至显示区域外就重新产生一个;响应时间事件时,定义一个时间全局变量并初始化为60,变量递减同时以文本形式不断输出以实现倒计时。
如果时间为0,则暂停。
在OnCreate()函数下,通过for循环随机产生每个气球中心点的横纵坐标,并通过SetTimer()定义两个定时器,分数每0.05秒刷新一次,时间每过1秒刷新一次。
(6)用鼠标“打”气球。
这是鼠标的单击事件,当游戏暂停或结束时不执行。
游戏进行时,判断鼠标单击的位置是否在气球上,即判断鼠标坐标到气球中心的距离,当点在气球范围内的时候将气球坐标移至界面外,气球消失,同时分数加100,并重新以文本形式输出。
3.核心代码说明
(1)变量定义
#defineNUM10//每一次随机产生的气球最大数
inta[NUM][2];//第一维控制数目第二维表示气球坐标
intcount=60;//时间
longscore;//分数
boolstate=1;
说明:
此段代码写在程序的开端,将产生的气球数目赋值给变量,则只需改变此处变量的值就可以轻易地改变气球个数,易于修改操作;二维数组的第一维与for循环语句相结合,可以实现对每一个气球的操作,第二维表示坐标,实现对气球的定位。
(2)绘制气球、绳子和地平线
else
{
//CDialog:
:
OnPaint();
CPaintDCdc(this);
CPenbPen(PS_SOLID,0,RGB(0,0,0));//黑色画笔
CBrushrbrush(RGB(255,0,0));//红色画刷
dc.SelectObject(&bPen);
dc.SelectObject(&rbrush);
dc.ExcludeClipRect(450,0,800,600);//规定图形显示区域
dc.ExcludeClipRect(0,401,800,600);
dc.ExcludeClipRect(0,0,10,600);
dc.ExcludeClipRect(0,0,800,10);
dc.MoveTo(30,400);//绘制地平线
dc.LineTo(440,400);
for(inti=0;i<=NUM;i++)//绘制气球和绳子以气球的中心点作为参考点
{
dc.Ellipse(a[i][0]-20,a[i][1]-25,a[i][0]+20,a[i][1]+25);//宽40高50
dc.MoveTo(a[i][0],a[i][1]+25);
dc.LineTo(a[i][0],a[i][1]+65);//绳长40
}
}
说明:
用RGB()函数选择颜色,黑色画笔绘制气球轮廓、绳子和地平线,红色画刷填充气球;
为使界面分明,需要规定显示气球的区域,四次调用ExcludeClipRect()函数分别擦除了界面右、下、左、上的部分区域;绘制地平线时,纵坐标需稍小于绘图区的下边界纵坐标;为简化操作,选取球心作为气球的定位点,并以此点坐标表示气球和绳子的端点坐标,操作此点即操作整体。
(3)“退出”按钮
voidCTempDlg:
:
OnExit()
{
if(IDYES==MessageBox("确认退出?
","Exit",MB_YESNO))//弹出确认退出对话框
CDialog:
:
OnOK();
}
说明:
单击按钮,屏幕弹出对话框,点击“是”,调用OnOK()退出程序。
(4)“暂停/开始”按钮
voidCTempDlg:
:
OnS_P()
{
if(state==0&&count==0)//时间为0单击重新开始
{
if(IDYES==MessageBox("是否重新开始?
","",MB_YESNO))
{
SetDlgItemText(IDP_S,"暂停");//按钮变为暂停
charbuffer[15];
score=0;
sprintf(buffer,"SCORE:
%4d",score);
m_score1=(LPCTSTR)buffer;
UpdateData(0);
count=60;
state=1;
SetTimer(1,50,NULL);//分数0.05秒刷新一次
SetTimer(2,1000,NULL);//时间1秒刷新一次
}
return;
}
if(state==1)//点击后暂停按钮变为开始
{
SetDlgItemText(IDP_S,"开始");
KillTimer
(1);
KillTimer
(2);
state=0;
}
Else//点击后游戏开始按钮变为暂停
{
SetDlgItemText(IDP_S,"暂停");
SetTimer(1,50,NULL);
SetTimer(2,1000,NULL);
state=1;
}
}
说明:
state初值为1,通过判断其值执行相应的if语句。
游戏开始后,单击按钮,按钮变为“开始”,同时调用KillTimer()函数,程序暂停;再次单击,按钮变为“暂停”,调用SetTimer()函数,程序继续。
随着游戏的进行,当时间递减为0时,点击弹出确认重新开始的对话框,若点击“是”,则时间变为60,分数归0并输出,按钮变为“暂停”,游戏重新开始。
(5)事件响应:
气球运动和倒计时
voidCTempDlg:
:
OnTimer(UINTnIDEvent)
{
inti;
switch(nIDEvent)
{
case1:
for(i=0;i<=NUM;i++)
{
if(a[i][1]<=0||a[i][0]<0)//气球升至界面外则重新随机产生一个
{
a[i][0]=rand()%(450-30)+30;
a[i][1]=rand()%(480-450)+450;
}
Else//气球上升并随机摆动
{
a[i][1]-=rand()%4+2;
a[i][0]+=rand()%4-2;
}
InvalidateRect(NULL,TRUE);
}
return;
case2:
//输出时间
charbuffer[15];
count--;
sprintf(buffer,"TIME:
%4d",count);//格式化输出到字符串
m_time1=(LPCTSTR)buffer;
UpdateData(0);
if(count==0)
{
SetDlgItemText(IDP_S,"重新开始");
KillTimer
(1);
KillTimer
(2);
state=0;
}
return;
}
}
说明:
OnTimer()函数是通过switch语句对事件进行响应,此段程序中,case1中首先对每个气球进行了位置判断,若气球中心到了界面之外则重新产生气球;而界面中的气球则在上升过程中随机摆动,这样就大大避免了气球相互重叠的情况。
case2中主要实现倒计时功能,并将时间转化为字符格式输出,时间为0时,开始按钮变为“重新开始”。
(6)创建、定义函数
intCTempDlg:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(CDialog:
:
OnCreate(lpCreateStruct)==-1)
return-1;
srand((int)GetCurrentTime());//初始化随机数发生器rand()%(MAX-MIN)+MIN
POINTpoint;//记录鼠标位置
GetCursorPos(&point);
ScreenToClient(&point);
for(inti=0;i<=NUM;i++)
{
a[i][0]=rand()%(450-30)+30;
a[i][1]=rand()%(480-450)+450;
}
SetTimer(1,50,NULL);
SetTimer(2,1000,NULL);
charbuffer[15];
sprintf(buffer,"SCORE:
%4d",score);//输出分数
m_score1=(LPCTSTR)buffer;
sprintf(buffer,"TIME:
%4d",count);//输出时间
m_time1=(LPCTSTR)buffer;
return0;
}
说明:
此段代码主要就各功能进行函数的创建和定义,包括:
初始化随机数发生器并获取随机数产生气球,定义并获取鼠标位置,设置时间和分数的定时器,定义时间和分数的输出。
(7)鼠标单击事件
voidCTempDlg:
:
OnLButtonDown(UINTnFlags,CPointpoint)//打气球
{
if(state==0)return;
for(inti=0;i<=NUM;i++)
{
if((point.x-a[i][0])*(point.x-a[i][0])<=400&&(point.y-a[i][1])*(point.y-a[i][1])<=625)//判断鼠标是否点中气球
{
a[i][0]=0;
a[i][1]=0;
score+=100;
charbuffer[15];
sprintf(buffer,"SCORE:
%4d",score);
m_score1=(LPCTSTR)buffer;
UpdateData(0);
break;
}
}
CDialog:
:
OnLButtonDown(nFlags,point);
}
说明:
打气球过程是通过鼠标点击气球实现的。
State为0时,游戏暂停或结束,程序不运行;游戏过程中,通过判断鼠标点击的位置与气球中心位置的距离判断是否点中气球。
若点中,将气球移至显示界面外,同时分数加100并重新输出。
4.测试报告
游戏开始后,界面如下:
点击暂停按钮,程序暂停:
用鼠标点击气球,分数加100:
时间倒计为0,程序暂停,按钮变为“重新开始”:
点击“重新开始”按钮,弹出确认对话框:
点击“是”,游戏重新开始,分数为0,时间从60倒计:
点击“退出”按钮,弹出确认对话框:
点击“是”则程序退出。
5.存在问题及分析
(1)随机产生气球时,为使界面清晰美观,需要控制产生的数目,尽量避免气球相互重叠覆盖的情况。
数目可由二维数组控制,后一问题则必须操作气球位置来解决,程序中是通过气球的随机摆动来减少重叠机会的。
(2)打气球时,判断鼠标是否点中气球,实际就是判断到椭圆中心的距离。
而点中范围其实是气球所在的矩形。
若要点中椭圆,则判断时最好与椭圆方程相结合。
(3)游戏中对分数的刷新频率要把握适度,太快屏幕显得不稳定,太慢分数变化不及时。
经在游戏中的不断调整选择了0.05秒作为刷新频率,比较合适。
(4)对于“暂停/开始”按钮的功能交替,需要设置一个变量作为判断条件。
因此定义一个bool型变量,0、1分别代表两个功能。
其实也可以定义一个整型变量,用奇数和偶数代表两个功能状态。
6.总结
在游戏功能实现方面,本程序基本实现了游戏中需要的各种基本功能,包括:
(1)气球由地平线随机产生,并向上运动,同时随机小范围摆动;
(2)用户使用鼠标点击气球,点中气球,气球消失,分数增加100分;
(3)游戏时间为60秒,时间采用倒计时方式显示,游戏时间为0时,程序暂停,单击“重新开始”按钮,提示用户是否重新开始;
(4)“开始/暂停”按钮。
游戏开始后,点击“暂停”按钮,游戏处于暂停状态,按钮文字变为“开始”;点击“开始”按钮,游戏重新开始,按钮文字变为“暂停”;
(5)“退出”按钮。
点击“退出”按钮,提示是否退出信息,若确定退出,关闭程序;若取消,则回到软件运行界面。
仍存在的不足是:
运行程序时游戏直接开始,不是通过点击“开始”按钮实现的。
本程序简洁易懂,层次清晰,可读性和可操作性都很强,用简单的语句实现了多种功能,修改或完善时也较为灵活方便。