当前位置:首页 > 04FunCode游戏设计+C++课程设计 - 桌球+ - 图文
移动的坐标位置参数,然后将该参数传给球杆精灵的SetSpritePosition函数,这样就能让球杆随鼠标移动了。由于鼠标在地图中有自己的图标,因此我们需要调用系统的隐藏鼠标的函数ShowCursor将鼠标隐藏掉。实现步骤如下: 1) 在LessonX.h中添加我们自己定义的OnMouseMove函数的声明:
void OnMouseMove( 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) 在函数中填入如下代码:
// 获取球杆和球的位置 float fBallPosX = float fBallPosY = float fCuePosX = float fCuePosY =
m_spBall[m_iBallNumber]->GetSpritePositionX(); m_spBall[m_iBallNumber]->GetSpritePositionY(); m_spBallCue->GetSpritePositionX(); m_spBallCue->GetSpritePositionY();
m_spBall[m_iBallNumber]是指当前桌面上的球。
2) 通过上面得到的坐标计算球和球杆之间的向量(fVectorX,fVectorY)。
float fVectorX =
float fVectorY =
fBallPosX - fCuePosX; fBallPosY - fCuePosY;
3) 判断球和球杆不重合的时候就执行画线操作。所以还需要在上面的代码后面添
加一个if的判断,同时计算向量(fVectorX,fVectorY)的大小,以及将该向量单位化:
// 如果只有当两点不重合的时候(向量值不为零),才需要处理
if( fVectorX > 0.001f || fVectorX < -0.001f || fVectorY > 0.001f || fVectorY < -0.001f )
{
// 计算该向量的大小,以及将该向量单位化(sqrt函数是开平方函数,回想下数学里如何求单位向量)
float fVectorSize float fDirX
float fDirY }
=
=
sqrt( fVectorX * fVectorX + fVectorY * fVectorY );
fVectorX / fVectorSize; =
fVectorY / fVectorSize;
因为sqrt()这个开方函数,所以需要包含头文件:
#include
4) 用循环,画出球前进方向的虚线,算法:我们用循环画12段首尾相连的线段,
如果全部画出来就是一条实线,如果循环变量为偶数就画,为奇数就不画,那么就得到一条虚,画一条线需要前后两个点: 一个点使用LastPos,一个点使用NewPos。循环12次,按照下面步骤写代码:
NewPos等于LastPos加上Dir乘以PosStep(单位向量乘以长度值等于该向量上的一个坐标点)
当循环变量为偶数的时候,使用DrawLine画一根线。 在画了线之后,将NewPos赋值给LastPos 具体代码如下:
int
iLoop
= 0;
float fLastPosX = fBallPosX, fLastPosY = fBallPosY; float fNewPosX = 0.f, fNewPosY = 0.f; float fPosStep = fVectorSize / 10.f; for( iLoop = 0; iLoop < 12; iLoop++ ) {
// 新坐标等于前一坐标加上向量方向上的一个距离值 fNewPosX = fNewPosY =
fLastPosX + fDirX * fPosStep; fLastPosY + fDirY * fPosStep;
// 偶数段就画 if( iLoop % 2 == 0 )
CSystem::DrawLine( fLastPosX, fLastPosY, fNewPosX, fNewPosY, 2.f, 0, 0, 255,
0, 255 );
}
// 坐标往前移动(NewPos赋值给LastPos) fLastPosX = fLastPosY =
fNewPosX; fNewPosY;
5) 进入LessonX.cpp,在GameRun函数里面,先判断是否处理可以打球的状态,
即球目前还处于静止状态,是的话就调用DrawDottedLine()进行画虚线操作:
if( 0 == m_iPlayState ) {
}
DrawDottedLine();
实验三 球洞来回循环滚动
【实验内容】
步骤、循环改变球洞的位置实现来回滚动
【实验思路】
使用循环,将数组值分别往后移动一位,最后一位移动到第一位。同时移动精灵名字数组,移动对应的精灵Y坐标(移动精灵。使用GetSpritePositionY获取精灵的位置,交换一下,用SetSpritePositionY赋值回去)
思路:先取出最后一个的值、名字、Y坐标,由后往前遍历数组,依次将前一个的值覆盖当前的值,最后将取出来的值赋值给第一个(这一步是在循环结束后做)
【实验指导】
1. 进入LessonX.h,添加CGameMain类球洞精灵的声明:
int
m_iHoleNumber[8];
// 8个球洞当前的数字值,0 - 7来回滚动。对应的球数字
// 8个球洞的精灵
打入对应的球洞才胜利 CSprite* float
m_spBallHole[8];
m_fHoleRollTime; // 球洞循环滚动间隔时间
2. 进入LessonX.cpp,在构造函数里面初始化球洞精灵变量:
m_fHoleRollTime
=
0.f;
在构造函数for( iLoop = 0; iLoop < 8; iLoop++ )循环里添加下面代码:
m_iHoleNumber[iLoop] = //初始化8个球洞精灵
tmpName=CSystem::MakeSpriteName( \m_spBallHole[iLoop]=new CSprite(tmpName);
iLoop;
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) 定义的函数中,首先初始化变量:
int iLoop
= 0, iLastData
=
0;// iLoop是循环因子,iListData记录最后
一个球洞的在m_iHoleNumber中的数值。
float fTempPosY float fLastPosY =
= 0.f; //保存当前球洞的Y坐标 0.f;//保存最后一个球洞的Y坐标
m_fHoleRollTime += fDeltaTime;//滚动频率 if( m_fHoleRollTime > 1.f ) {
m_fHoleRollTime -= 1.f; }
m_fHoleRollTime -= 1.f;//保证了球洞更换速度不会太快或者太慢,同时m_fHoleRollTime的值不会一直在增加。
3) 再在函数中添加下面代码:
// 取出最后一个值 iLastData = fLastPosY =
m_iHoleNumber[7];
m_spBallHole[iLastData]->GetSpritePositionY();
// 从后往前遍历数组。注意只需要做6次循环(iLoop由7递减至1) for( iLoop = 7; iLoop > 0; iLoop-- ) {
m_iHoleNumber[iLoop] =
m_iHoleNumber[iLoop - 1];
int tmpNum=m_iHoleNumber[iLoop - 1];
// 先保存需要更改坐标的精灵的Y坐标作为下一个精灵的坐标,然后再给它赋值 fTempPosY
=
m_spBallHole[tmpNum]->GetSpritePositionY();
m_spBallHole[tmpNum]->SetSpritePositionY(fLastPosY);
共分享92篇相关文档