C语言课程设计桌球.docx

上传人:小飞机 文档编号:3155524 上传时间:2023-03-11 格式:DOCX 页数:17 大小:43.54KB
返回 下载 相关 举报
C语言课程设计桌球.docx_第1页
第1页 / 共17页
C语言课程设计桌球.docx_第2页
第2页 / 共17页
C语言课程设计桌球.docx_第3页
第3页 / 共17页
C语言课程设计桌球.docx_第4页
第4页 / 共17页
C语言课程设计桌球.docx_第5页
第5页 / 共17页
亲,该文档总共17页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《C语言课程设计桌球.docx》由会员分享,可在线阅读,更多相关《C语言课程设计桌球.docx(17页珍藏版)》请在三一办公上搜索。

1、C语言课程设计桌球C语言课程设计-桌球 一、实验内容 玩家通过移动球杆到单一的桌球处碰撞桌球运动,当桌球于一定速度通过桌面右方的同样颜色的球洞后,则该球进洞,在桌面左边重新分配新球开始游戏。要求如下: 1. 游戏的初始界面如下,其中左边有一个体积较小的桌球,其x方向位置固定,y方向位置随机。右边有八个颜色不一样,体积较大的球洞,游戏的目的是使用左边的桌球以一定小的速度穿过右边同样颜色的球洞就算桌球进洞,然后重新分配新球。 2. 3. 4. 5. 球杆随鼠标运动而运动,单击球杆,桌球获取一个前进的速度同时往前有运动。桌球的前进方向有一段指示球运动方向的虚线。 右侧的球洞以移动的频率不断更换位置。

2、球洞的x左边不变,更换的是y坐标的位置,即每一轮中每一个球洞移动到下一个球洞的位置,最下边的球洞则移动到第一个球洞位置。所以的这些动作都要在一个频率的时间里面完成。因此当游戏一某一个频率进行的时候,右侧的球洞就能实现循环变化的效果。 球碰撞到桌面边沿的时候以发射角的角度弹走。 球进洞的判断是球以一定的速度通过同样颜色的球洞时,桌球消失,表明球进洞了,此时左侧随机生成新球。球运动到球洞的速度不能太大,太大则球直接运动过球洞,如果速度太小,则球同样不进洞。 二、实验指南 实验一开始实验 步骤一、打开FunCode,创建一个的C+语言项目; 步骤二、导入snooker模板。 按实验指导完成。 1、

3、打开FunCode,点击“项目”菜单,选择“创建C语言工程” 注意:工程名名称要求字母开头,只能包含字母和数字,且名字中间不能有空格。 2、 点击菜单“项目”中的“导入地图模块”,如图一。跳出一个对话框,选中“snooker”模板,点击“导入到工程”按钮,如图二。 图 一 图 二 3、导入成功后的,界面如下图所示: 实验二初始化桌球和球杆同时在球的前进方向画虚线 步骤一、设置球的初始位置,球杆的初始朝向 步骤二、设置球杆随鼠标移动 步骤三、在球的前进方向上画虚线 在设置初始球的时候要考虑随机本局的球数字,如果和上一局的不一致,则将上局的球拉到屏幕外,将本局的球拉到屏幕内,在Y向上随机摆放球的出

4、生位置,只随机Y方向坐标,不动X方向。对于球杆则通过系统的dOnMouseMove函数获取到鼠标移动时的坐标位置,然后使用dSetSpritePosition函数同步设置桌球精灵的位置。通过获取球的X和Y坐标,并求两个坐标平方和的平方根来得到球运动方向向量的大小,利用循环调用系统画线函数画虚线。 1. 在Main.cpp中,初始化几个全局变量,代码如下: / 游戏玩法设计:上方有8个球洞,分别是数字0-7,球洞间的数字按一定速率滚 / 动,每局球都随机一个0-7的数字,对应的数字打入对应的球洞才胜利,开始打球 / 状态 g_iPlayState = 0; g_fRotateTime = 0.f

5、; g_fHoleRollTime = 0.f; 2. 初始化精灵: / 使用循环,给数组赋值: / 将数组的8个值分别赋值0-7即可,无需随机。名字使用dMakeSpriteName分 / 别产生,为BallHole0 - BallHole7 / 球洞精灵预先摆放在场景中,因此不需要创建 int iLoop = 0; for( iLoop = 0; iLoop B减去A得到一条由A指向B的向量。 /下面的计算,得到一条球杆坐标指向球坐标的向量 float fVectorX = float fVectorY = fBallPosX - fCuePosX; fBallPosY - fCuePos

6、Y; fBallPosX = fBallPosY = fCuePosX = fCuePosY = dGetSpritePositionX( g_szBallName ); dGetSpritePositionY( g_szBallName ); dGetSpritePositionX( BallCue ); dGetSpritePositionY( BallCue ); 3) 判断球和球杆不重合的时候就执行画线操作。所以还需要在上面的代码后面添加一个if的判断,同时计算向量的大小,以及将该向量单位化: if( fVectorX 0.001f | fVectorX 0.001f | fVecto

7、rY -0.001f ) / 计算该向量的大小,以及将该向量单位化(sqrt函数是开平方函数,回想下/ 数学里如何求单位向量) float fVectorSize = sqrt( fVectorX * fVectorX + fVectorY * fVectorY ); float fDirX = fVectorX / fVectorSize; float fDirY = fVectorY / fVectorSize; 4) 用循环,与上一个if判断平行,画出球前进方向的虚线: / 我们用循环画12段首尾相连的线段,如果全部画出来就是一条实线,如果循环/ 变量为偶数就画,为奇数就不画,那么就得到

8、一条虚线 / 画一条线需要前后两个点: 一个点使用LastPos,一个点使用NewPos。循环12/ 次,按照下面步骤写代码: / NewPos等于LastPos加上Dir乘以PosStep(单位向量乘以长度值等于该向量上/ 的一个坐标点) / 当循环变量为偶数的时候,使用dDrawLine画一根线 / 在画了线之后,将NewPos赋值给LastPos int iLoop = 0; float fLastPosX = fBallPosX, fLastPosY = fBallPosY; float fNewPosX float fPosStep = 0.f, fNewPosY = 0.f; =

9、fVectorSize / 10.f; for( iLoop = 0; iLoop 12; iLoop+ ) / 新坐标等于前一坐标加上向量方向上的一个距离值 fNewPosX fNewPosY = fLastPosX + fDirX * fPosStep; = fLastPosY + fDirY * fPosStep; / 偶数段就画 if( iLoop % 2 = 0 ) dDrawLine( fLastPosX, fLastPosY, fNewPosX, fNewPosY, 2.f, 0, 0, 255, 0, 255 ); / 坐标往前移动(NewPos赋值给LastPos) fLas

10、tPosX = fNewPosX; fLastPosY = fNewPosY; 实验三 球洞来回循环滚动 步骤、循环改变球洞的位置实现来回滚动 使用循环,将数组值分别往后移动一位,最后一位移动到第一位。同时移动精灵名字数组,移动对应的精灵Y坐标(移动精灵。使用dGetSpritePositionY获取精灵的位置,交换一下,用dSetSpritePositionY赋值回去) 思路:先取出最后一个的值、名字、Y坐标,由后往前遍历数组,依次将前一个的值覆盖当前的值,最后将取出来的值赋值给第一个(这一步是在循环结束后做) 1. 在Main.cpp中,添加球洞精灵的声明: / 8个球洞当前的数字值,0

11、- 7来回滚动。对应的球数字打入对应的球洞才胜利 int char float g_iHoleNumber8; g_szHoleName864; g_fHoleRollTime = / 8个球洞的精灵名字 / 球洞循环滚动间隔时间 0.f; 2. 在Main.cp的while循环中初始化球洞精灵变量: / 使用循环,给数组赋值: / 将数组的8个值分别赋值0-7即可,无需随机。名字使用dMakeSpriteName分 / 别产生,为BallHole0 - BallHole7 / 球洞精灵预先摆放在场景中,因此不需要创建 int iLoop = 0; for( iLoop = 0; iLoop

12、1.f ) g_fHoleRollTime -= 1.f; 4. 在上面的if判断里面添加下面代码: / 取出最后一个值 iLastData = fLastPosY = g_iHoleNumber7; dGetSpritePositionY( g_szHoleName7 ); strcpy( szLastName, g_szHoleName7 ); / 从后往前遍历数组。注意只需要做6次循环(iLoop由7递减至1) for( iLoop = 7; iLoop 0; iLoop- ) g_iHoleNumberiLoop = g_iHoleNumberiLoop - 1; / 先保存需要更改坐

13、标的精灵的Y坐标作为下一个精灵的坐标,然后再给它 / 赋值 fTempPosY = dGetSpritePositionY( g_szHoleNameiLoop - 1 ); dSetSpritePositionY( g_szHoleNameiLoop - 1, fLastPosY ); fLastPosY = fTempPosY; strcpy( g_szHoleNameiLoop, g_szHoleNameiLoop - 1 ); / 将取出来的最后一个值赋值给第一个 g_iHoleNumber0 = iLastData; strcpy( g_szHoleName0, szLastName

14、 ); dSetSpritePositionY( g_szHoleName0, fLastPosY ); 5. 至此,球洞循环来回滚动的实验结束。 实验四 击打桌球 步骤一、处理鼠标单击事件,球杆角度变化 步骤二、球杆击打之后,桌球获取一个向前运动的速度 获取系统鼠标点击的消息,判断游戏是否在进行以及球是否可以击打,然后球杆旋转,模拟打球的操作。之后获取球和球杆之间的向量用来计算速度,最后利用dSetSpriteLinearVelocity函数给该球一个速度,同时用dSetSpriteDamping函数给球一个减速系数。 1. 在Main.cpp中添加如下变量声明: float g_fRota

15、teTime;/ 球杆拍下时,做个角度旋转,持续一小段时间,模拟拍下的动作 2. 进入Main.cpp中对变量g_fRotateTime进行初始化: g_fRotateTime = 0.f; 3. 在dOnMouseClick中填入如下代码: 1) 只响应游戏中可以点击打球的状态 if( 2 != g_iGameState | 0 != g_iPlayState ) return; 2) 改变球的状态,同时给球杆一个旋转,模拟打球动作,这个过程持续一定的时间 g_iPlayState = 1; g_fRotateTime =0.2f; dSetSpriteRotation( BallCue,

16、g_fOldRotation + 10.f ); 3) 获取球和球杆之间的变量 / 球的位置 float fPosX float fPosY = = dGetSpritePositionX( g_szBallName ); dGetSpritePositionY( g_szBallName ); / 有A,B两点坐标,求两点间向量 = B减去A得到一条由A指向B的向量。 / 下面的计算,得到一条鼠标坐标指向球坐标的向量 float fVectorX = float fVectorY = fPosX - fMouseX; fPosY - fMouseY; 4) 通过上面的变量计算球的速度,同时让

17、球运动已经添加一个减速系数使其慢慢减速到静止。 / 将该向量放大,得到我们想要的速度 fVectorX *= 12.f; fVectorY *= 12.f; / 给球设置该速度,以及设置一个速度衰减系数,使其逐渐停止 dSetSpriteLinearVelocity( g_szBallName, fVectorX, fVectorY ); dSetSpriteDamping( g_szBallName, 1.6f ); 4. 球杆按下之后做了旋转,需要对其进行复位。在while循环的最后面添加下面的代码: / 球杆按下之后,做了个旋转。时间到了,将球杆复位 if( g_fRotateTime

18、0.f ) 至此,本实验结束。 g_fRotateTime -= fDeltaTime; if( g_fRotateTime “碰撞”里选中“发送碰撞” 2 同样,依次在地图中点击上图中的四个桌球台边沿精灵,分别给左右上下的边起名字为:VerSide1、VerSide0、HorSide0、HorSide1进入精灵与精灵碰撞函数,碰撞的算法是这样的:碰到垂直的边的时候,将当前球的X方向速度取反即可得到反弹效果。水平方向则是对Y取反.如下图: 水平方向上: 3 垂直方向上: 1) 判断是否是我们控制的球碰撞到边界 if( strcmp( szSrcName, g_szBallName ) = 0

19、| strcmp( szTarName, g_szBallName ) = 0 2) 在上面的if里面再进行判断,如果球碰到水平边则按下面代码处理: 3) 判断碰撞到垂直还是水平边 if( strstr( szSrcName, VerSide ) | strstr( szTarName, VerSide ) ) float fVelX = dGetSpriteLinearVelocityX( g_szBallName ); dSetSpriteLinearVelocityX( g_szBallName, fVelX * -1.f ); 4) 如果球碰到垂直边则按下面代码处理: else if(

20、 strstr( szSrcName, HorSide ) | strstr( szTarName, HorSide ) ) float fVelY = dGetSpriteLinearVelocityY( g_szBallName ); dSetSpriteLinearVelocityY( g_szBallName, fVelY * -1.f ); 至此,本实验结束。 实验六桌球进洞 步骤、桌球以一定速度移动到球洞中,则判为进洞,将球移出屏幕,生成新球 判断球是否正在运动,是的话则获取该球的速度,同时判断该球的速度是否符合进洞速度要求以及该球的坐标是否在同款颜色的球洞精灵中,是的话则认为球进

21、洞,将球移出屏幕,左侧生成新球。 1. 在Main.cpp的while循环当中,前面以及有过判断球是否运动的if( 0 = g_iPlayState )操作了,只需要在后面添加一个else语句,判断球进洞的操作在else里面执行。 2. 在球洞精灵初始化的后面,填入如下代码: / 判断球是否位于球洞内。 float fVelX float fVelY = = dGetSpriteLinearVelocityX( g_szBallName ); dGetSpriteLinearVelocityY( g_szBallName ); / 计算速度向量的大小.sqrt是开平方函数 float fSpe

22、edValue = sqrt( fVelX * fVelX + fVelY * fVelY ); 3. 判断球的速度,小于30.f时获取球的坐标,g_spBallHoleg_iBallNumber为当前同款颜色球洞精灵,通过dIsPointInSprite判断球的坐标是否在该球洞精灵里面,是的话重新开局,写在2的后边,代码如下, / 速度判断, 球的速度必须低于某个值,速度太大将直接滚过球洞 if( fSpeedValue 30.f ) float fPosX float fPosY = = dGetSpritePositionX( g_szBallName ); dGetSpritePositionY( g_szBallName ); if( dIsPointInSprite( g_szHoleNameiIndex, fPosX, fPosY ) ) / 重新开始下一局 g_iGameState = 1; return; / 如果速度为0,则可以重新开始打球操作 if( fSpeedValue 0.50f ) g_iPlayState = 0; 至此,本实验结束。

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号