力度,如果一直按下键盘按键,则fDeltaTime会一直增加,因此角度和力度就改变。以大炮的炮口为发射点,根据力度和角度计算x和y方向的速度值,计算炮弹的飞行时间,使用一个for循环来得到飞行过程中的抛物线上的坐标,然后就可以画出该抛物线。
【实验指导】
1、 进入LessonX.h中,添加下面的成员变量的声明:
float float int 度
static const float m_fBumbForceY 形成一个抛物线弹道轨迹 float float 角度
CSprite* m_pDandanGun; CTextSprite* CTextSprite*
m_pDegreeText;
//发射炮精灵
//角度显示精灵
m_fKeyUp
;
// 上下键是否按下的变量:1按下0弹起,用于计算角度 ;
// 上下键是否按下的变量:1按下0弹起,用于计算
m_fKeyDown
;
// 炮弹发射之后,给它一个向下的常力,使其
m_fGunRotation m_fGunStrength m_iCalStrength ;
; ;
// 炮的朝向 // 炮的力度
// 1 : 空格键按下中,计算力度,力度渐增。0 : 不计算力
m_pStrengthText; //力度显示精灵
CSprite* m_pBumpTemplate; //炸弹模板精灵
2、 进入LessonX.cpp中在构造函数里面添加以上变量的初始化代码:
m_fGunRotation
m_fGunStrength m_iCalStrength m_fKeyUp
m_fKeyDown m_pDandanGun m_pDegreeText
m_pStrengthText
= =
= = 0; 0.f; = = = = =
0.f;
new CSprite(\new CTextSprite(\new CTextSprite(\new CSprite(\350.f; 0.f;
m_pBumpTemplate
3、 m_fBumbForceY是const的成员变量,因此我们需要对其单独进行定义,在文件的
最后面添加下面一行代码:
const float CGameMain::m_fBumbForceY=10.f;
4、 在GameInit函数里面添加下面的初始化代码:
m_fGunRotation m_fGunStrength
= =
m_fMaxRotation; // 炮台的初始角度为最大角度 0.f;
5、 进入LessonX.h中,添加响应键盘按下的处理事件函数OnKeyDown的声明:
void OnKeyDown( const int iKey, const int iAltPress, const int iShiftPress, const int iCtrlPress );
6、 进入LessonX.cpp中添加上面的函数的定义:
void CGameMain::OnKeyDown( const int iKey, const int iAltPress, const int iShiftPress, const int iCtrlPress ) { }
1) 如果判断按下空格键,开始计算力度. 只在游戏进行中并且是等待开炮的状态
按键才有效,在上面的函数里面添加如下代码:
if( KEY_SPACE == iKey && 2 == m_iGameState && 0 == m_iFireState )
{
}
m_iCalStrength =
1;
2) 如果按下上下方向键:
if( KEY_UP == iKey ) { }
else if( KEY_DOWN == iKey ) {
m_fKeyDown = }
1.f;
m_fKeyUp = 1.f;
7、 最后在Main.cpp中OnkeyDown中添加我们的处理函数:
g_GameMain.OnKeyDown(iKey,bAltPress,bShiftPress,bCtrlPress);
8、 在等待开炮的状态下,可以调整角度和力度。
1) 进入GameRun函数,首先需要知道大炮是否开炮,添加下面的if判断:
if( 0 == m_iFireState ) { }
2) 计算力度,按下空格键之后随时间增加,在上面的if判断里面添加如下的代码:
if( m_iCalStrength ) {
}
m_fGunStrength
+= 50.f * fDeltaTime; // 50每秒
if( m_fGunStrength > 200.f ) //大炮力度的最大值
m_fGunStrength = 200.f;
3) 计算角度,按下方向键调整大小,添加如下代码:
// 15度每秒
m_fGunRotation += (m_fKeyDown - m_fKeyUp) * 15.f * fDeltaTime; if( m_fGunRotation < 280.f )
//大炮角度的最小值
// 角度超过最大值
m_fGunRotation = 280.f; m_fGunRotation
=
else if( m_fGunRotation > m_fMaxRotation )
m_fMaxRotation; // 回到初始位置
9、 接下来画出前半段抛物线弹道轨迹,首先要获取大炮炮口的挂接点作为炮弹发射点
(画线起始点,模板中,在该点位置设置一个链接点),根据当前朝向、力度,计算出XY两个方向上的速度值。再计算炮弹的质量,计算炮弹飞行时间,根据Y方向的常力作用力和质量,计算出Y方向该作用力的速度值,半段抛物线的总飞行时间为fHalfTime(单位秒),我们每隔fSimDelta(秒)的时间采样一个点,就得到整个时间长度上的各个坐标点。
1) 获取大炮炮口的挂接点作为炮弹发射点,在if( 0 == m_iFireState )添加如下代码:
float fOl dPosX = float fOldPosY =
m_pDandanGun->GetSpriteLinkPointPosX(1); m_pDandanGun->GetSpriteLinkPointPosY(1);
float fNewPosX = float fVelocityX m_fGunStrength;
float fVelocityY m_fGunStrength;
0.f, fNewPosY = = =
0.f;
m_fGunRotation m_fGunRotation
) )
* *
2) 计算出XY两个方向上的速度值:
CSystem::RotationToVectorX( CSystem::RotationToVectorY(
3) 获取炮弹质量:
float fMass
=
m_pBumpTemplate->GetSpriteMass();
4) 计算炮弹飞行时间(只画半个抛物线,所以只计算一半的时间)
float fHalfTime =
- fVelocityY / (m_fBumbForceY / fMass);
5) 计算出Y方向该作用力的速度值:
float fForceVelY = m_fBumbForceY / fMass;
6) 半段抛物线的总飞行时间为fHalfTime(单位秒),我们每隔fSimDelta(秒)的时间采样一个点,就得到整个时间长度上的各个坐标点:
float fTime
=
0.f; 0.0333f;
float fSimDelta = {
fNewPosX = fNewPosY = // 画线
CSystem::DrawLine( fOldPosX, fOldPosY, fNewPosX, fNewPosY, 2.f, 0, 0, 255, 0, 255 ); }
fOldPosX = fNewPosX; fOldPosY = fNewPosY;
fOldPosX + fVelocityX * fSimDelta;
fOldPosY + (fVelocityY + fForceVelY * fTime) * fSimDelta;
for( fTime = 0.f; fTime < fHalfTime; fTime += fSimDelta )
10、 我们需要实时更新炮旋转角度和数值,因此在GameRun函数最后添加如下的
代码:
m_pDandanGun->SetSpriteRotation(m_fGunRotation);
m_pDegreeText->SetTextValue(m_fGunRotation);
m_pStrengthText->SetTextValue(m_fGunStrength);
至此,本实验结束。
实验四 发射炮弹
【实验内容】
步骤一、创建炮弹精灵 步骤二、模拟真实发射
【实验思路】
获取系统的键盘空格键按下后释放按键的消息,然后利用for循环创建三个炮弹精灵,给他们一个向前的速度,同时因为是模拟真实的炮弹发射,因此需要给他们一个向下的力量,整体效果就是一段抛物线的弹道轨迹了。
【实验指导】
1、 进入LessonX.h中添加如下的成员变量以及响应空格键释放事件的处理函数的声明:
float
m_fRoundTime ; // 炮弹发射之后,等待一定时间才开始下回合
CAnimateSprite* m_pBump[3]; //炸弹精灵数组
void OnKeyUp( const int iKey ); //键盘抬起的函数声明
2、 进入LessonX.cpp中,添加以上成员变量以及函数的定义:
1) 在构造函数中初始化以上成员变量,添加以下代码:
m_fRoundTime = 0.f;
同时初始化炸弹精灵数组,在for(int i=0;i m_pBump[i]=new CAnimateSprite(CSystem::MakeSpriteName(\ 2) 添加我们的自定义函数OnKeyUp的定义: void CGameMain::OnKeyUp( const int iKey ) { } 3) 最后在Main.cpp中添加对空格键释放事件的处理函数,在OnkeyUp中添加下面 一行代码: g_GameMain.OnKeyUp(iKey); 3、 进入LessonX.cpp中,我们首先要判断释放的按键是空格键还是上下方向键,因此 在OnKeyUp中需要添加一个判断,在该函数定义中添加如下代码: if( KEY_SPACE == iKey && 2 == m_iGameState && 0 == m_iFireState ) { } // 上下键 if( KEY_UP == iKey ) { } else if( KEY_DOWN == iKey ) { } m_fKeyDown = 0.f; m_fKeyUp = 0.f; 4、 如果按下空格键,则处理发射炮弹动作,相应的代码在if( KEY_SPACE == iKey && 2 == m_iGameState && 0 == m_iFireState)里面完成。 1) 更改发射状态,在炮弹未落地之前不能再次发射,设置等待3秒的回合时间: m_iFireState = 1; 0; = 3.f; m_iCalStrength = m_fRoundTime float fPosX int float fPosY iLoop = = 2) 获取大炮炮口的挂接点作为炮弹发射点: m_pDandanGun->GetSpriteLinkPointPosX(1); m_pDandanGun->GetSpriteLinkPointPosY(1); = 0; 3) 添加下面的变量定义代码: float fGunRotation = float fGunStrength = m_fGunRotation - 10.f; m_fGunStrength - 10.f;