欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    C++语言课程设计-桌球(11页).doc

    • 资源ID:36399803       资源大小:188KB        全文页数:11页
    • 资源格式: DOC        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    C++语言课程设计-桌球(11页).doc

    -C+语言课程设计-桌球-第 11 页C+语言课程设计一桌球一、实验内容玩家通过移动球杆到单一的桌球处碰撞桌球运动,当桌球于一定速度通过桌面右方的同样颜色的球洞后,则该球进洞,在桌面左边重新分配新球开始游戏。要求如下:1. 游戏的初始界面如下,其中左边有一个体积较小的桌球,其x方向位置固定,y方向位置随机。右边有八个颜色不一样,体积较大的球洞,游戏的目的是使用左边的桌球以一定小的速度穿过右边同样颜色的球洞就算桌球进洞,然后重新分配新球。2. 球杆随鼠标运动而运动,单击球杆,桌球获取一个前进的速度同时往前有运动。桌球的前进方向有一段指示球运动方向的虚线。3. 右侧的球洞以移动的频率不断更换位置。球洞的x左边不变,更换的是y坐标的位置,即每一轮中每一个球洞移动到下一个球洞的位置,最下边的球洞则移动到第一个球洞位置。所以的这些动作都要在一个频率的时间里面完成。因此当游戏一某一个频率进行的时候,右侧的球洞就能实现循环变化的效果。4. 球碰撞到桌面边沿的时候以发射角的角度弹走。5. 球进洞的判断是球以一定的速度通过同样颜色的球洞时,桌球消失,表明球进洞了,此时左侧随机生成新球。球运动到球洞的速度不能太大,太大则球直接运动过球洞,如果速度太小,则球同样不进洞。二、实验指南实验一开始实验【实验任务】步骤一、打开FunCode,创建一个的C+语言项目;步骤二、导入snooker模板。【实验思路】按实验指导完成。【实验指导】1、 打开FunCode,点击“项目”菜单,选择“创建C+工程”注意:工程名名称要求字母开头,只能包含字母和数字,且名字中间不能有空格。2、 点击菜单“项目”中的“导入地图模块”,如图一。跳出一个对话框,选中“snooker”模板,点击“导入到工程”按钮,如图二。 图 一 图 二3、导入成功后的,界面如下图所示:实验二初始化桌球和球杆同时在球的前进方向画虚线【实验内容】步骤一、设置球的初始位置,球杆的初始朝向步骤二、设置球杆随鼠标移动步骤三、在球的前进方向上画虚线【实验思路】在设置初始球的时候要考虑随机本局的球数字,如果和上一局的不一致,则将上局的球拉到屏幕外,将本局的球拉到屏幕内,在Y向上随机摆放球的出生位置,只随机Y方向坐标,不动X方向。对于球杆则通过系统的OnMouseMove函数获取到鼠标移动时的坐标位置,然后使用SetSpritePosition函数同步设置桌球精灵的位置。通过获取球的X和Y坐标,并求两个坐标平方和的平方根来得到球运动方向向量的大小,利用循环调用系统画线函数画虚线。【实验指导】1. 进入LessonX.h,添加CGameMain的成员变量,前面几个实验之后我们知道了类的成员变量一般设置访问属性为private,代码如下:int m_iPlayState;/ 操作状态,0 - 可以点击鼠标打球;1 - 球在运动中,等待下次打球机会int m_iBallNumber;/ 每局从0-7随机一个颜色图片,作为本局的球floatm_fOldRotation;/ 球杆的初始朝向,用于球杆复位CSprite*m_spBall8;/ 8个球的精灵CSprite*m_spBallCue;/球杆精灵2. 进入LessonX.cpp中,在构造函数里面先把m_iGameState的值由0改为1。然后填写初始化代码:m_iPlayState=0;m_iBallNumber=0;m_fOldRotation=0.f;/初始化球杆精灵m_spBallCue=new CSprite("BallCue");/初始化球和球洞精灵char* tmpName=""for(int iLoop = 0; iLoop < 8; iLoop+ )/初始化8个球精灵tmpName=CSystem:MakeSpriteName("Ball",iLoop);m_spBalliLoop=new CSprite(tmpName);m_fHoleRollTime=0.f;3. 在LessonX.cpp中的GameInit函数里面填写球和球杆的初始化代码。随机本局的球数字,如果和上一局的不一致,则将上局的球拉到屏幕外,将本局的球拉到屏幕内。intiNewBallNumber=CSystem:RandomRange( 0, 7 );if( iNewBallNumber != m_iBallNumber )m_spBallm_iBallNumber->SetSpritePositionY(50.f);/ 新球,移动到屏幕中m_iBallNumber=iNewBallNumber;m_spBallm_iBallNumber->SetSpritePositionX(-30.f);在Y向上随机摆放球的初始位置,只随机Y方向坐标,不动X方向intiPosY=CSystem:RandomRange( -25, 25 );m_spBallm_iBallNumber->SetSpritePositionY(float)iPosY);获取球拍的初始朝向,只做一次static int iInited = 0;if( !iInited )iInited=1;m_fOldRotation=m_spBallCue->GetSpriteRotation();4. 设置球杆随鼠标移动而移动。首先通过系统的OnMouseMove函数实时获取到鼠标移动的坐标位置参数,然后将该参数传给球杆精灵的SetSpritePosition函数,这样就能让球杆随鼠标移动了。由于鼠标在地图中有自己的图标,因此我们需要调用系统的隐藏鼠标的函数ShowCursor将鼠标隐藏掉。实现步骤如下:1) 在LessonX.h中添加我们自己定义的OnMouseMove函数的声明:voidOnMouseMove( const float fMouseX, const float fMouseY );/参数即为鼠标X,Y坐标的值2) 在LessonX.cpp中填写该函数的定义:void CGameMain:OnMouseMove( const float fMouseX, const float fMouseY )3) 调用球杆精灵的设置位置函数SetSpritePosition将鼠标的位置设置为球杆精灵的位置。在上面的函数里面填入:m_spBallCue->SetSpritePosition(fMouseX, fMouseY );4) 使用CSystem的隐藏鼠标的函数ShowCursor将鼠标在地图的图标隐藏掉。这一步可以在程序初始化的时候就完成。在GameInit函数里面的if( !iInited )判断里面填入一行代码:CSystem:ShowCursor(0);5) 在Main.cpp中的OnMouseMove函数里面填入我们的自定义函数,实时获取鼠标坐标参数:g_GameMain.OnMouseMove(fMouseX,fMouseY);5. 在球运动的方向画虚线比较简单。主要是获取球和球杆连线的向量,然后等到该向量的单位向量大小,调用DrawLine函数,利用for循环,判断循环因子为偶数的时候不画线,奇数的时候才画线。首先声明定义函数,进入LessonX.h,在CGameMain类中添加画虚线的函数声明:void DrawDottedLine();然后在LessonX中添加函数的定义:void CGameMain:DrawDottedLine()1) 在函数中填入如下代码:/ 获取球杆和球的位置floatfBallPosX=m_spBallm_iBallNumber->GetSpritePositionX();floatfBallPosY=m_spBallm_iBallNumber->GetSpritePositionY();floatfCuePosX=m_spBallCue->GetSpritePositionX();floatfCuePosY=m_spBallCue->GetSpritePositionY();m_spBallm_iBallNumber是指当前桌面上的球。2) 通过上面得到的坐标计算球和球杆之间的向量(fVectorX,fVectorY)。floatfVectorX=fBallPosX - fCuePosX;floatfVectorY=fBallPosY - fCuePosY;3) 判断球和球杆不重合的时候就执行画线操作。所以还需要在上面的代码后面添加一个if的判断,同时计算向量(fVectorX,fVectorY)的大小,以及将该向量单位化:/ 如果只有当两点不重合的时候(向量值不为零),才需要处理if( fVectorX > 0.001f | fVectorX < -0.001f | fVectorY > 0.001f | fVectorY < -0.001f )/ 计算该向量的大小,以及将该向量单位化(sqrt函数是开平方函数,回想下数学里如何求单位向量)floatfVectorSize=sqrt( fVectorX * fVectorX + fVectorY * fVectorY );floatfDirX=fVectorX / fVectorSize;floatfDirY=fVectorY /fVectorSize;因为sqrt()这个开方函数,所以需要包含头文件:#include<math.h>4) 用循环,画出球前进方向的虚线,算法:我们用循环画12段首尾相连的线段,如果全部画出来就是一条实线,如果循环变量为偶数就画,为奇数就不画,那么就得到一条虚,画一条线需要前后两个点: 一个点使用LastPos,一个点使用NewPos。循环12次,按照下面步骤写代码:NewPos等于LastPos加上Dir乘以PosStep(单位向量乘以长度值等于该向量上的一个坐标点)当循环变量为偶数的时候,使用DrawLine画一根线。在画了线之后,将NewPos赋值给LastPos具体代码如下:intiLoop= 0;floatfLastPosX= fBallPosX, fLastPosY = fBallPosY;floatfNewPosX= 0.f, fNewPosY = 0.f;floatfPosStep= fVectorSize / 10.f;for( iLoop = 0; iLoop < 12; iLoop+ )/ 新坐标等于前一坐标加上向量方向上的一个距离值fNewPosX=fLastPosX + fDirX * fPosStep;fNewPosY=fLastPosY + fDirY * fPosStep;/ 偶数段就画if( iLoop % 2 = 0 )CSystem:DrawLine( fLastPosX, fLastPosY, fNewPosX, fNewPosY, 2.f, 0, 0, 255, 0, 255 );/ 坐标往前移动(NewPos赋值给LastPos)fLastPosX=fNewPosX;fLastPosY=fNewPosY;5) 进入LessonX.cpp,在GameRun函数里面,先判断是否处理可以打球的状态,即球目前还处于静止状态,是的话就调用DrawDottedLine()进行画虚线操作:if( 0 = m_iPlayState )DrawDottedLine();实验三 球洞来回循环滚动【实验内容】步骤、循环改变球洞的位置实现来回滚动【实验思路】使用循环,将数组值分别往后移动一位,最后一位移动到第一位。同时移动精灵名字数组,移动对应的精灵Y坐标(移动精灵。使用GetSpritePositionY获取精灵的位置,交换一下,用SetSpritePositionY赋值回去)思路:先取出最后一个的值、名字、Y坐标,由后往前遍历数组,依次将前一个的值覆盖当前的值,最后将取出来的值赋值给第一个(这一步是在循环结束后做)【实验指导】1. 进入LessonX.h,添加CGameMain类球洞精灵的声明:intm_iHoleNumber8;/ 8个球洞当前的数字值,0 - 7来回滚动。对应的球数字打入对应的球洞才胜利CSprite*m_spBallHole8;/ 8个球洞的精灵floatm_fHoleRollTime;/ 球洞循环滚动间隔时间2. 进入LessonX.cpp,在构造函数里面初始化球洞精灵变量:m_fHoleRollTime=0.f;在构造函数for( iLoop = 0; iLoop < 8; iLoop+ )循环里添加下面代码:m_iHoleNumberiLoop=iLoop;/初始化8个球洞精灵tmpName=CSystem:MakeSpriteName( "BallHole", iLoop );m_spBallHoleiLoop=new CSprite(tmpName);3. 在CGameMain类中添加球洞循环更换函数。循环算法如下:先将最后一个球洞的Y坐标保存下来,然后使用一个for循环对第一个至第七个球洞所在的数组进行从后往前的遍历。每一次循环都先将当前球洞的Y坐标保存下来,然后将下一个球洞的Y坐标赋给当前球洞。第一次循环的时候将第七个球洞的Y坐标保存下来,然后将最后一个球洞的Y坐标赋给第七个球洞。第二次循环的时候将第六个球洞的Y坐标保存下来,然后将第七个球洞的坐标赋给第六个,依次类推,共进行六次循环。最后循环结束,将第一个球洞的Y坐标赋给最后一个球洞。1) 首先声明定义函数,进入LessonX.h,在CGameMain类中添加球洞循环更换的函数声明:void HoleChange(const float fDeltaTime);然后在LessonX中添加函数的定义:void CGameMain:HoleChange(const float fDeltaTime)2) 定义的函数中,首先初始化变量:intiLoop= 0, iLastData=0;/ iLoop是循环因子,iListData记录最后一个球洞的在m_iHoleNumber中的数值。floatfTempPosY= 0.f; /保存当前球洞的Y坐标float fLastPosY=0.f;/保存最后一个球洞的Y坐标m_fHoleRollTime += fDeltaTime;/滚动频率if( m_fHoleRollTime > 1.f )m_fHoleRollTime -= 1.f;m_fHoleRollTime -= 1.f;/保证了球洞更换速度不会太快或者太慢,同时m_fHoleRollTime的值不会一直在增加。3) 再在函数中添加下面代码:/ 取出最后一个值iLastData=m_iHoleNumber7;fLastPosY=m_spBallHoleiLastData->GetSpritePositionY();/ 从后往前遍历数组。注意只需要做6次循环(iLoop由7递减至1)for( iLoop = 7; iLoop > 0; iLoop- )m_iHoleNumberiLoop=m_iHoleNumberiLoop - 1;int tmpNum=m_iHoleNumberiLoop - 1;/ 先保存需要更改坐标的精灵的Y坐标作为下一个精灵的坐标,然后再给它赋值fTempPosY=m_spBallHoletmpNum->GetSpritePositionY();m_spBallHoletmpNum->SetSpritePositionY(fLastPosY);fLastPosY=fTempPosY;/ 将取出来的最后一个值赋值给第一个m_iHoleNumber0=iLastData;m_spBallHoleiLastData->SetSpritePositionY(fLastPosY);4. 在GameRun的if后面调用球洞循环更换的函数:HoleChange(fDeltaTime);至此,球洞循环来回滚动的实验结束。实验四 击打桌球【实验内容】步骤一、处理鼠标单击事件,球杆角度变化步骤二、球杆击打之后,桌球获取一个向前运动的速度【实验思路】获取系统鼠标点击的消息,判断游戏是否在进行以及球是否可以击打(即m_iPlayState不等于0),然后球杆旋转,模拟打球的操作。之后获取球和球杆之间的向量用来计算速度,最后利用SetSpriteLinearVelocity函数给该球一个速度,同时用SetSpriteDamping函数给球一个减速系数。【实验指导】1. 进入LessonX.h,添加如下变量声明:floatm_fRotateTime;/ 球杆拍下时,做个角度旋转,持续一小段时间,模拟拍下的动作添加一个我们自定义的函数OnMouseClick的声明:voidOnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY );2. 进入LessonX.cpp中,在构造函数里面对变量m_fRotateTime进行初始化:m_fRotateTime=0.f;3. 添加函数OnMouseClick的定义,在LessonX.cpp的最后面填入下面代码:void CGameMain:OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )4. 在上面的函数里面填入如下代码:1) 只响应游戏中可以点击打球的状态if( 2 != m_iGameState | 0 != m_iPlayState )return;2) 改变球的状态,同时给球杆一个旋转,模拟打球动作,这个过程持续一定的时间m_iPlayState = 1;m_fRotateTime=0.2f;m_spBallCue->SetSpriteRotation(m_fOldRotation + 10.f);3) 获取球和球杆之间的变量(通过获取坐标得到)/ 球的位置floatfPosX=m_spBallm_iBallNumber->GetSpritePositionX(); floatfPosY=m_spBallm_iBallNumber->GetSpritePositionY(); / 有A,B两点坐标,求两点间的向量 => B减去A得到一条由A指向B的向量。/ 下面的计算,得到一条鼠标坐标指向球坐标的向量floatfVectorX=fPosX - fMouseX;floatfVectorY=fPosY - fMouseY;4) 通过上面的变量计算球的速度,同时让球运动已经添加一个减速系数使其慢慢减速到静止。/ 将该向量放大,得到我们想要的速度fVectorX*= 12.f;fVectorY*= 12.f;/ 给球设置该速度,以及设置一个速度衰减系数,使其逐渐停止m_spBallm_iBallNumber->SetSpriteLinearVelocity(fVectorX, fVectorY);m_spBallm_iBallNumber->SetSpriteDamping(1.6f);5. 球杆按下之后做了旋转,需要对其进行复位。在GameRun函数最后面添加下面的代码:/ 球杆按下之后,做了个旋转。时间到了,将球杆复位if( m_fRotateTime > 0.f )m_fRotateTime-= fDeltaTime;if( m_fRotateTime <= 0.f )/ 球杆旋转复位m_spBallCue->SetSpriteRotation(m_fOldRotation);至此,本实验结束。实验五 球和桌球台边沿的碰撞【实验内容】步骤、判断球和桌球台的判断,改变球的运动方向【实验思路】两个精灵之间的碰撞我们已经做过了很多了,系统会自动检测到两个精灵的碰撞,然后就能得到它们的名字,因此我们可以自定义一个函数来接收这两个名字并进行相应的操作即行,额外要考虑的只是球碰撞之后的运动方向问题,这里我们一理想世界作参考,球碰了台沿之后会以物理中反射角的角度运动,速度不变。【实验指导】1 进入LessonX.h中添加桌球台边沿精灵的变量声明:CSprite*m_spVerSide2;/桌球台上下边沿精灵CSprite*m_spHorSide2;/桌球台左右边沿精灵添加自定义碰撞函数的声明:voidOnSpriteColSprite( const char szSrcName, const char szTarName );2 进入LessonX.cpp,在构造函数里面初始化桌球台边沿精灵:/初始化桌球边沿的4个精灵for(iLoop=0;iLoop<2;iLoop+)/上下边沿精灵初始化tmpName=CSystem:MakeSpriteName("VerSide",iLoop);m_spVerSideiLoop=new CSprite(tmpName);/左右边沿精灵的初始化tmpName=CSystem:MakeSpriteName("HorSide",iLoop);m_spHorSideiLoop=new CSprite(tmpName);在LessonX.cpp的最后面添加函数OnSpriteColSprite的定义:void CGameMain:OnSpriteColSprite( const char szSrcName, const char szTarName )3 在LessionX.cpp的GameInit()函数中添加如下代码,设置精灵碰撞模式。for(int i=0; i<8;i+)m_spBalli->SetSpriteCollisionSend(1);/设置球为发送碰撞模式for(int j=0;j<2;j+)/设置桌球台边沿精灵为接收碰撞m_spVerSidej->SetSpriteCollisionReceive(1); m_spHorSidej->SetSpriteCollisionReceive(1);4 碰撞的算法是这样的:碰到垂直的边的时候,将当前球的X方向速度取反即可得到反弹效果。水平方向则是对Y取反.如下图:水平方向上:垂直方向上:1) 判断是否是我们控制的球碰撞到边界if( strcmp( szSrcName, m_spBallm_iBallNumber->GetName() ) = 0 | strcmp( szTarName, m_spBallm_iBallNumber->GetName() ) = 0 )m_spBallm_iBallNumber是指当前控制的球。2) 在上面的if里面再进行判断,如果球碰到水平边(即上下边沿)则按下面代码处理:if( strstr( szSrcName, "VerSide" ) | strstr( szTarName, "VerSide" ) )floatfVelX=m_spBallm_iBallNumber->GetSpriteLinearVelocityX(); m_spBallm_iBallNumber->SetSpriteLinearVelocityX(fVelX * -1.f);3) 如果球碰到垂直边(即左右边沿)则按下面代码处理:else if( strstr( szSrcName, "HorSide" ) | strstr( szTarName, "HorSide" ) )floatfVelY= m_spBallm_iBallNumber->GetSpriteLinearVelocityY(); m_spBallm_iBallNumber->SetSpriteLinearVelocityY(fVelY * -1.f);5 在Main.cpp里面的OnSpriteColSprite函数添加我们自定义的函数:g_GameMain.OnSpriteColSprite(szSrcName,szTarName);至此,本实验结束。实验六桌球进洞【实验内容】步骤、桌球以一定速度移动到球洞中,则判为进洞,将球移出屏幕,生成新球【实验思路】判断球是否正在运动,是的话则获取该球的速度,同时判断该球的速度是否符合进洞速度要求以及该球的坐标是否在同款颜色的球洞精灵中,是的话则认为球进洞,将球移出屏幕,左侧生成新球。【实验指导】1. 进入LessonX.cpp中,在GameRun函数里面,前面以及有过判断球是否运动的if( 0 = m_iPlayState )操作了,只需要在后面添加一个else语句,判断球进洞的操作在else里面执行。2. 首先判断当前球m_spBallm_iBallNumber是否在同色球洞中,同时判断球的速度是否符合进洞要求。填入如下代码:else/ 判断球是否位于球洞内。floatfVelX=m_spBallm_iBallNumber->GetSpriteLinearVelocityX();floatfVelY=m_spBallm_iBallNumber->GetSpriteLinearVelocityY();/ 计算速度向量的大小.sqrt是开平方函数floatfSpeedValue=sqrt( fVelX * fVelX + fVelY * fVelY );3. 判断球的速度,小于30.f时获取球的坐标,m_spBallHolem_iBallNumber为当前同款颜色球洞精灵,通过m_spBallHolem_iBallNumber->IsPointInSprite(fPosX, fPosY )判断球的坐标是否在该球洞精灵里面,是的话重新开局,代码如下,同样写在else里面:/ 速度判断, 球的速度必须低于某个值,速度太大将直接滚过球洞if( fSpeedValue < 30.f )floatfPosX=m_spBallm_iBallNumber->GetSpritePositionX();floatfPosY=m_spBallm_iBallNumber->GetSpritePositionY();if( m_spBallHolem_iBallNumber->IsPointInSprite(fPosX, fPosY ) )/ 重新开始下一局m_iGameState = 1;return;/ 如果速度为0,则可以重新开始打球操作if( fSpeedValue < 0.50f )m_iPlayState = 0;至此,本实验结束。

    注意事项

    本文(C++语言课程设计-桌球(11页).doc)为本站会员(1595****071)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开