void SetDir(int dir) {m_iDir = dir;} void SetSpeedX(float speedX) {m_fSpeedX = speedX;} void SetSpeedY(float speedY) {m_fSpeedY = speedY;} //get方法
int GetHp() {return m_iHp;} int GetDir() {return m_iDir;} float GetSpeedX() {return m_fSpeedX;} float GetSpeedY() {return m_fSpeedY;}
3、CTankPlayer的父类是CSprite类(具体声明查看CommonClass.h),构造函数为CSprite( const char *szName )。 4、所以通过上边方法自动生成的类,如果系统自动生成构造函数CTankPlayer(void), 删
除掉它以及在CTankPlayer.cpp中自动生成的对构造函数实现的代码: CTankPlayer::CTankPlayer(void) { }
再为CTankPlayer类添加新的构造函数:CTankPlayer(const char* szName)。
CTankPlayer::CTankPlayer(const char* szName):CSprite(szName) //对构造函数进行实现 {
m_iDir=0; m_fSpeedX=0.f; m_fSpeedY=0.f;
m_iHp=2;
}
子类对象创建时,要先调用父类的构造函数完成父类部分的构造。如果父类没有默认构造函数,子类的构造函数必须显示调用父类的构造函数。CTankPlayer构造函数调用CSprite类构造函数,并将参数szName的值传递给它,从而将名称为szName的精灵图片与CTankPlayer对象绑定起来。
5、为CTankPlayer类添加Init函数,该函数主要用来完成该类的初始化工作。这里,先
调用setHp方法设置血量。然后调用父类的SetSpritePosition函数将坦克精灵设置在屏幕中央(0,0)处。接下来给坦克精灵设置时间边界的大小,与世界边界的碰撞模式为WORLD_LIMIT_NULL,表示精灵与世界边界碰撞的响应由代码完成,同时设置坦克碰撞模式为发送碰撞和接收碰撞。
void CTankPlayer::Init() {
SetHp(2);
SetSpritePosition(0.f,0.f);
SetSpriteWorldLimit(WORLD_LIMIT_NULL, -26, -22, 26, 22);
SetSpriteCollisionActive(1,1);//设置为可以接受和发生碰撞
SetSpriteVisible(true); }
6、在CGameMain类中增加一个私有成员变量m_pTankplayer,类型为CTankPlayer*。
注意在LessonX.h添加头文件:
#include\
7、按下空格键后,程序会调用键盘按下事件响应函数,将m_iGameState的值改为1,
8
上海锐格软件有限公司
游戏进入开始状态(见实验一)。程序再次执行CGameMain::GameMainLoop函数时,根据m_iGameState的值调用并执行CGameMain::GameInit函数。因此,可以在该函数中创建我方坦克,并调用CTankPlayer::Init函数来完成该类对象的初始化工作。
m_pTankPlayer=new CTankPlayer(\新建一个名字是myPlayer的我方坦克对象
m_pTankPlayer->CloneSprite(\我方坦克克隆在funcode模板中存在的名字为player的坦克,表示新建的坦克对象有现在精灵的所有属性 m_pTankPlayer->Init();
8、接下来,我们为CTankPlayer类添加OnMove函数,参数iKey、bPress分别表示按下
的是哪个按键和按键是否按下。首先声明该函数,访问权限为public:
void OnMove(int iKey, bool bPress);
9、接着,完成OnMove方法。
void CTankPlayer::OnMove(int iKey, bool bPress) {
if(bPress) {
switch (iKey) {
case KEY_W: SetDir(0); SetSpeedX(0); SetSpeedY(-8); break; case KEY_D: SetDir(1); SetSpeedX(8); SetSpeedY(0); break; case KEY_S: SetDir(2); SetSpeedX(0); SetSpeedY(8); break; case KEY_A: SetDir(3); SetSpeedX(-8); SetSpeedY(0); break; }
SetSpriteRotation(float(90*GetDir())); //用方向值乘于90得到精灵旋转度数SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY()); } else {
9
if(iKey == KEY_W || iKey == KEY_D || iKey == KEY_S || iKey == KEY_A) {
SetSpeedX(0); SetSpeedY(0);
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY()); } } }
用参数bPress来判断键盘是按下还是弹起。如果bPress为false,表示键盘弹起,且弹起的键是WASD键时,设置坦克的X轴和Y轴移动速度都为0。如果bPress为true,表示键盘按下,根据按下的键,为m_iDir,m_fSpeedX,m_fSpeedY赋予相应的值。SetSpriteRotation和SetSpriteLinearVelocity函数用来设置精灵的角度和线性速度,具体含义参考CommonClass.h文件。 10、在CGameMain类的OnKeyDown函数中,通过调用CTankPlayer类的OnMove方法,
根据按下的键,控制坦克朝指定方向运动。只有游戏进入开始状态,按键才有效。注意:OnMove参数bPress的值为true。在OnKeyDown函数中添加代码如下:
if(m_iGameState == 2) {
m_pTankPlayer->OnMove(iKey, true); }
11、编译并运行程序。按空格键开始,按WASD键,坦克会向规定的方向运动。但是松
开按键后,坦克继续前进,不会停止下来。
12、参考CSystem::OnKeyUp函数,给CGameMain类声明并定义一个OnKeyUp函数,
用来处理按键弹起事件,然后在CSystem::OnKeyUp函数中调用它。关于这个函数如何声明、定义以及调用参考实验一。
13、在CGameMain::OnKeyUp函数中调用CTankPlayer的OnMove方法,参数bPress的
值为false。
void CGameMain::OnKeyUp(const int iKey) {
if(m_iGameState == 2) {
m_pTankPlayer->OnMove(iKey, false); } }
14、编译并运行程序,按下WASD键,坦克运行;松开按键,坦克停止。接下来,我们
来实现坦克运行到黑色区域边界停止运动的效果。
15、参考CSystem::OnSpriteColWorldLimit函数,给CGameMain类声明并定义一个
OnSpriteColWorldLimit函数,用来处理精灵与世界边界的碰撞事件,然后在CSystem:: OnSpriteColWorldLimit函数中调用它。关于这个函数如何声明、定义以及调用参考实验一。
16、当坦克精灵碰到边界时,将精灵的速度都设为0,精灵停止运动。
用字符串处理函数strstr()来判断碰到世界边界的精灵是否为我方坦克。当碰到世界边界的精灵名字中含有”player”的时候,strstr会返回一个非空值。因此代码如下:
void CGameMain::OnSpriteColWorldLimit( const char *szName, const int iColSide )
10
上海锐格软件有限公司 { if(strstr(szName,\判断碰到世界边界的坦克是否为我方坦克 {
m_pTankPlayer->SetSpriteLinearVelocity(0,0); } }
实验三 坦克开炮
【实验内容】
1、创建子弹类CBullet;
2、通过按键J控制坦克开炮; 【实验运行结果】
【实验思路】
创建子弹类,该类应具备子弹的运动方向、起始位置、X轴速度、Y轴速度等属性,其中运动方向和起始位置由坦克的方向和位置决定。
通过按键控制坦克发射子弹,因此在CGameMain类的OnKeyDown方法中实现该需求。此时我们为CTankPlayer类添加发射子弹的方法OnFire。当按下J键后,坦克发射子弹,在OnFire方法中,我们需要告诉子弹的方向和初始位置。而创建子弹我们由CGameMain类来完成。这样减少了类之间的耦合。 【实验指导】
1、通过类向导创建CBullet类,其继承于CSprite类,具体做法参考实验一;
2、为CBullet类添加m_iDir,m_fSpeedX,m_fSpeedY,m_iHp,m_iOwner五个成员,分别表
示方向、X轴、Y轴速度、子弹血量以及发射子弹归属坦克,0表示地方坦克,1表示我方坦克,并参考实验二添加变量的get和set方法。
3、为CTankPlayer类添加构造函数和析构函数。参照实验二,把构造函数中将所有变量
进行初始化。
4、为CBullet类添加OnMove方法,参数为iDir表示子弹的运动方向。
5、完成OnMove方法。根据方向m_iDir,首先设置m_fSpeedX,m_fSpeedY的值,然后
设置根据方向设置旋转角度,最后设置子弹的运动速度。
void CBullet::OnMove(int iDir)
11