【效果图】
【写在前面的话】
1.虚函数在哪里很不舒服?Commclass里面加了一个无参结构
2、bug很多,比如世界边界,子弹都有问题。这个程序已经改正了。
3.十个需求已经改变,但我删除了这个程序。以后会发布。
4.如果有子弹,调整子弹的碰撞体,改善边界
【Funcode创建类】
CBullet.h
#ifndef CBULLET_H #define CBULLET_H #include <CommonClass.h> #include "CWeapon.h" class CBullet : public CWeapon { public: CBullet(){}; CBullet(const char* szName); // 分别表示方向,X轴、Y轴速、子弹血量和发射子弹属于坦克,0表示地方坦克,1表示我们坦克 int m_iDir; float m_fSpeedX,m_fSpeedY; int m_iHp; int m_iOwner; virtual void OnMove(int iDir); //set方法 void SetDir(int Dir); void SetOwner(int Owner); void SetHp(int Hp); void SetSpeedX(float SpeedX); void SetSpeedY(float SpeedY); //get方法 int GetDir(); int GetOwner(); int GetHp(); float GetSpeedX(); float GetSpeedY(); ///初始化方法 virtual void Init(); virtual void OnMove(int iKey, bool bPress); void OnSpriteColSprite(CWeapon* pSprite); virtual ~CBullet(){}; protected: private: }; #endif // CBULLET_H
CBullet.cpp
#include "CBullet.h" #include <iostream> using namespace std; #include<windows.h> #include<mmsystem.h> #pragma comment(lib,"Winmm.lib") #include <LessonX.h> CBullet::CBullet(const char* szName):CWeapon(szName) ///实现构造函数 { m_iDir=0; m_fSpeedX=0.f; m_fSpeedY=0.f; m_iHp=2; m_iOwner = 0; } void CBullet::OnMove(int iDir) { SetDir(iDir); switch(GetDir()) { case 0: if(m_iOwner==1) { SetSpeedX(0); SetSpeedY(-20); }else{ SetSpeedX(0); SetSpeedY(-10); } break; case 1: if(m_iOwner==1) { SetSpeedX(20); SetSpeedY(0); }else{ SetSpeedX(10); SetSpeedY(0); } break; case 2: if(m_iOwner==1) { SetSpeedX(0); SetSpeedY(20); }else{ SetSpeedX(0); SetSpeedY(10); } break; case 3: if(m_iOwner==1) { SetSpeedX(-20); SetSpeedY(0); }else{ SetSpeedX(-10); SetSpeedY(0); } break; } SetSpriteRotation(90*GetDir()); SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY()); } void CBullet::SetDir(int Dir) { m_iDir = Dir; } void CBullet::SetOwner(int Owner) { m_iOwner = Owner; } void CBullet::SetHp(int Hp) { m_iHp = Hp; } void CBullet::SetSpeedX(float SpeedX) { m_fSpeedX = SpeedX; } void CBullet::SetSpeedY(float SpeedY) { m_fSpeedY = SpeedY; } //get方法 int CBullet::GetDir() { return m_iDir; } int CBullet::GetOwner() { return m_iOwner; } int CBullet::GetHp() { return m_iHp; } float CBullet::GetSpeedX() { return m_fSpeedX; } float CBullet::GetSpeedY() { return m_fSpeedY; } void CBullet::Init() { } void CBullet::OnMove(int iKey, bool bPress) { } void CBullet::OnSpriteColSprite(CWeapon* pSprite) { if(pSprite == NULL) { return; } if(GetOwner() == 1 && strstr(pSprite->GetName(),"aim_nor") != NULL) ///我们的坦克子弹与军营碰撞 { return; } if(GetOwner() == 0 && strstr(pSprite->GetName(),"enemy") != NULL) ///敌方坦克子弹击中地方坦克 { return; } if(strstr(pSprite->GetName(),"wall")==NULL) { // mciSendString(TEXT("open D:\\图片\\坦克战争材料\\boom.wav alias Mysong"), NULL, 0,NULL); // // mciSendString(TEXT("play MySong"), NULL, 0, NULL); } // cout<<pSprite->GetName()<<"的HP:"<<pSprite->GetHp()<<endl; pSprite->SetHp(pSprite->GetHp()-2); if(strstr(pSprite->GetName(),"enemy")!=NULL) { pSprite->SetHp(0); } SetHp(0.f); }
CTankEnemy.h
#ifndef CTANKENEMY_H #define CTANKENEMY_H #include <CommonClass.h> #include "CWeapon.h" class CTankEnemy : public CWeapon { public: CTankEnemy(const char* szName); CTankEnemy(); int m_iDir; int iDir; float m_fSeedX;
float m_fSpeedY;
float m_fChangeDirTime;
float m_fBulletCreateTime;
int m_iHp;
//set方法
void SetHp(int hp);
void SetDir(int dir);
void SetSpeedX(float speedX);
void SetSpeedY(float speedY);
void SetChangeDirTime(float ChangeDirTime);
//get方法
int GetHp();
int GetDir();
float GetSpeedX();
float GetSpeedY();
float GetChangeDirTime();
void OnFire(float fDeltaTime);
//初始化方法
void Init();
void OnMove();
//处理世界边界的碰撞
void OnMove(int dir);
void OnMove(float fDeltaTime);
void OnSpriteColSprite();
void OnSpriteColSprite(CWeapon* pSprite);
//追踪
void trackMove();
virtual ~CTankEnemy();
protected:
private:
};
#endif // CTANKENEMY_H
CTankEnemy.cpp
#include "CTankEnemy.h"
#include "LessonX.h"
#include <iostream>
using namespace std;
CTankEnemy::CTankEnemy(const char* szName):CWeapon(szName)
//对构造函数进行实现
{
iDir = 0;
m_iDir=0;
m_fSpeedX=0.f;
m_fSpeedY=0.f;
m_iHp=2;
m_fBulletCreateTime = 0.f;
m_fChangeDirTime = 0.f;
}
CTankEnemy::~CTankEnemy()
{
//dtor
}
void CTankEnemy::SetHp(int hp){m_iHp = hp;}
void CTankEnemy::SetDir(int dir){m_iDir = dir;}
void CTankEnemy::SetSpeedX(float speedX){m_fSpeedX = speedX;}
void CTankEnemy::SetSpeedY(float speedY){m_fSpeedY = speedY;}
void CTankEnemy::SetChangeDirTime(float ChangeDirTime){m_fChangeDirTime = ChangeDirTime;}
//get方法
int CTankEnemy::GetHp(){return m_iHp;}
int CTankEnemy::GetDir(){return m_iDir;}
float CTankEnemy::GetSpeedX(){return m_fSpeedX;}
float CTankEnemy::GetSpeedY(){return m_fSpeedY;}
float CTankEnemy::GetChangeDirTime(){return m_fChangeDirTime;}
void CTankEnemy::Init()
{
int iPos = CSystem::RandomRange(0,2);
float fPosX;
SetDir(2);
SetHp(2);
switch (iPos)
{
case 0:
fPosX = -24.f;
break;
case 1:
fPosX = 0.f ;
break;
case 2:
fPosX = 24.f;
break;
default:
break;
}
SetSpritePosition(fPosX,-20.f);
SetSpriteLinearVelocity(0.f,8.f);
SetSpriteCollisionActive(1,1); //设置可以接受和发送碰撞
SetSpriteRotation(float(90*GetDir()));
SetSpriteWorldLimit(WORLD_LIMIT_NULL,-26, -22, 26, 22);
}
void CTankEnemy::OnMove()
{
switch (iDir)
{
case 0://上
SetSpeedX(0);
SetSpeedY(-8);
break;
case 1://右
SetSpeedX(8);
SetSpeedY(0);
break;
case 2://下
SetSpeedX(0);
SetSpeedY(8);
break;
case 3://左
SetSpeedX(-8);
SetSpeedY(0);
break;
}
SetDir(iDir);
SetSpriteRotation(float(90*GetDir())); //用方向值乘于90得到精灵旋转度数
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());
if(GetDir()==0 || GetDir()==1 || GetDir()==2)
{
iDir = GetDir()+1;
}
else //如果方向值等于3,设为0
{
iDir = 0;
}
}
void CTankEnemy::trackMove()
{
int Dir = 0;
if(GetSpritePositionX()<g_GameMain.m_pTankPlayer->GetSpritePositionX()-2)
{
SetSpeedX(8);
SetSpeedY(0);
Dir = 1;
SetDir(Dir);
}else if(GetSpritePositionX()>g_GameMain.m_pTankPlayer->GetSpritePositionX()+2){
SetSpeedX(-8);
SetSpeedY(0);
Dir = 3;
SetDir(Dir);
}
else if(GetSpritePositionY()<g_GameMain.m_pTankPlayer->GetSpritePositionY()-2)
{
SetSpeedX(0);
SetSpeedY(8);
Dir = 2;
SetDir(Dir);
}
else if(GetSpritePositionY()>g_GameMain.m_pTankPlayer->GetSpritePositionY()+2){
SetSpeedX(0);
SetSpeedY(-8);
Dir = 0;
SetDir(Dir);
}
SetSpriteRotation(float(90*GetDir())); //用方向值乘于90得到精灵旋转度数
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());
}
void CTankEnemy::OnMove(float fDeltaTime)
{
m_fChangeDirTime+=fDeltaTime;
if(m_fChangeDirTime>2.0f)
{
OnMove();
m_fChangeDirTime = 0.f;
}
}
void CTankEnemy::OnMove(int dir)
{
if(dir==0)
{
SetDir(2);
SetSpeedX(0);
SetSpeedY(8);
}else if(dir==1)
{
SetDir(3);
SetSpeedX(-8);
SetSpeedY(0);
}else if(dir==2)
{
SetDir(0);
SetSpeedX(0);
SetSpeedY(-8);
}else{
SetDir(1);
SetSpeedX(8);
SetSpeedY(0);
}
SetSpriteRotation(float(90*GetDir())); //用方向值乘于90得到精灵旋转度数
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());
}
void CTankEnemy::OnFire(float fDeltaTime)
{
m_fBulletCreateTime+=fDeltaTime;
if(m_fBulletCreateTime>3.0f)
{
//cout<<"地方发射子弹了"<<endl;
m_fBulletCreateTime = 0.0f;
float x,y;
x = GetSpritePositionX();
y = GetSpritePositionY();
switch(GetDir())
{
case 0:
y=y-GetSpriteHeight()/2-1;
break;
case 1:
x=x+GetSpriteWidth()/2+1;
break;
case 2:
y=y+GetSpriteHeight()/2+1;
break;
case 3:
x=x-GetSpriteWidth()/2-1;
break;
}
g_GameMain.AddBullet(GetDir(),x,y,0);
}
}
void CTankEnemy::OnSpriteColSprite(CWeapon* pSprite)
{
if(pSprite == NULL)
{
return;
}
if(strstr(pSprite->GetName(),"enemy")!=NULL)return;
if(strstr(pSprite->GetName(),"wall")!=NULL)
{
SetSpriteLinearVelocity(0.f,0.f);
m_fChangeDirTime = 3.8;
}
SetSpriteLinearVelocity(0.f,0.f);
m_fChangeDirTime = 3.8;
}
void CTankEnemy::OnSpriteColSprite()
{
SetSpriteLinearVelocity(0.f,0.f);
}
CTankPlayer.h
#ifndef CTANKPLAYER_H
#define CTANKPLAYER_H
#include <CommonClass.h>
#include "CWeapon.h"
class CTankPlayer : public CWeapon
{
public:
CTankPlayer();
CTankPlayer(const char* szName);
int m_iDir;
float m_fSpeedX;
float m_fSpeedY;
int key;
int m_iHp;
//set方法
void SetHp(int hp);
void SetDir(int dir);
void SetSpeedX(float speedX);
void SetSpeedY(float speedY);
//get方法
int GetHp();
int GetDir();
float GetSpeedX();
float GetSpeedY();
//初始化方法
void Init();
void OnMove(int iKey, bool bPress);
// 开火,发射子弹
void OnFire();
void OnSpriteColSprite(CWeapon* pSprite);
virtual ~CTankPlayer();
protected:
private:
};
#endif // CTANKPLAYER_H
CTankPlayer.cpp
#include "CTankPlayer.h"
#include "LessonX.h"
#include <iostream>
using namespace std;
CTankPlayer::CTankPlayer(const char* szName):CWeapon(szName) //对构造函数进行实现
{
m_iDir=0;
m_fSpeedX=0.f;
m_fSpeedY=0.f;
m_iHp=2;
}
CTankPlayer::~CTankPlayer()
{
//dtor
}
void CTankPlayer::SetHp(int hp){
m_iHp = hp;
// cout<<"我的血量变成了"<<m_iHp<<endl;
}
void CTankPlayer::SetDir(int dir){m_iDir = dir;}
void CTankPlayer::SetSpeedX(float speedX){m_fSpeedX = speedX;}
void CTankPlayer::SetSpeedY(float speedY){m_fSpeedY = speedY;}
//get方法
int CTankPlayer::GetHp(){return m_iHp;}
int CTankPlayer::GetDir(){return m_iDir;}
float CTankPlayer::GetSpeedX(){return m_fSpeedX;}
float CTankPlayer::GetSpeedY(){return m_fSpeedY;}
void CTankPlayer::Init()
{
SetHp(2);
SetSpritePosition(0.f,0.f);
SetSpriteWorldLimit(WORLD_LIMIT_NULL, -26, -22, 26, 22);
SetSpriteCollisionActive(1,1);//设置为可以接受和发生碰撞
SetSpriteVisible(true);
}
void CTankPlayer::OnMove(int iKey, bool bPress)
{
key = iKey;
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
{
if(iKey == KEY_W || iKey == KEY_D || iKey == KEY_S || iKey == KEY_A)
{
SetSpeedX(0);
SetSpeedY(0);
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());
}
}
}
void CTankPlayer::OnFire()
{
float x,y;
x = GetSpritePositionX();
y = GetSpritePositionY();
switch(GetDir())
{
case 0:
y=y-GetSpriteHeight()/2-1;
break;
case 1:
x=x+GetSpriteWidth()/2+1;
break;
case 2:
y=y+GetSpriteHeight()/2+1;
break;
case 3:
x=x-GetSpriteWidth()/2-1;
break;
}
g_GameMain.AddBullet(GetDir(),x,y,1);
}
void CTankPlayer::OnSpriteColSprite(CWeapon* pSprite)
{
if(pSprite == NULL)
{
return;
}
else if(strstr(pSprite->GetName(),"bullet") != NULL)
{
SetHp(0);
}
else if(strstr(pSprite->GetName(),"wall") != NULL)
{
SetSpeedX(0);
SetSpeedY(0);
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());
}
}
CWeapon.h
#ifndef CWEAPON_H
#define CWEAPON_H
#include <CommonClass.h>
class CWeapon : public CSprite
{
public:
CWeapon();
CWeapon( const char *szName );
CWeapon( const char *szName, const char *szCloneName );
// CWeapon(const char* szName);
int m_iDir;
float m_fSpeedX;
float m_fSpeedY;
int m_iHp;
//set方法
void SetHp(int hp);
void SetDir(int dir);
void SetSpeedX(float speedX);
void SetSpeedY(float speedY);
//get方法
int GetHp();
int GetDir();
float GetSpeedX();
float GetSpeedY();
bool IsDead(); //判断精灵是否死亡
virtual void Init(){}; //初始化函数
virtual void OnMove(float fDeltaTime){}; //敌方坦克移动函数
virtual void OnMove(){};
virtual void trackMove(){};
virtual void OnFire(float deltaTime){}; //发射子弹函数
virtual void OnSpriteColSprite(CWeapon* pSprite){}; //精灵与精灵碰撞时处理函数
virtual void OnSpriteColSprite(){};
virtual ~CWeapon();
protected:
private:
};
#endif // CWEAPON_H
CWeapon.cpp
#include "Cweapon.h"
CWeapon::CWeapon( const char *szName ):CSprite(szName) //对构造函数进行实现
{
m_iDir=0;
m_fSpeedX=0.f;
m_fSpeedY=0.f;
m_iHp=2;
}
CWeapon::~CWeapon()
{
//dtor
}
void CWeapon::SetHp(int hp){m_iHp = hp;}
void CWeapon::SetDir(int dir){m_iDir = dir;}
void CWeapon::SetSpeedX(float speedX){m_fSpeedX = speedX;}
void CWeapon::SetSpeedY(float speedY){m_fSpeedY = speedY;}
//get方法
int CWeapon::GetHp(){return m_iHp;}
int CWeapon::GetDir(){return m_iDir;}
float CWeapon::GetSpeedX(){return m_fSpeedX;}
float CWeapon::GetSpeedY(){return m_fSpeedY;}
bool CWeapon::IsDead()
{
if(m_iHp == 0)
{
return true;
}
return false;
}
LessonX.h
/
//
//
//
//
/
#ifndef _LESSON_X_H_
#define _LESSON_X_H_
//
#include <Windows.h>
//在此类中增加该头文件
#include <CTankPlayer.h>
#include "CBullet.h"
#include "CTankEnemy.h"
#include <CTankFriend.h>
#include<vector>
using namespace std;
/
//
// 游戏总管类。负责处理游戏主循环、游戏初始化、结束等工作
class CGameMain
{
private:
int m_iGameState; // 游戏状态,0:结束或者等待开始;1:初始化;2:游戏进行中
CSprite* m_pSplash; //标题
CSprite* m_pStart;//按任意键开始
//子弹的数量
int m_iBulletNum;
// CTankEnemy* m_pTankEnemy;
void LoadMap();
vector<CWeapon*> m_vWeapon;
float m_fTankEnemyTime;
int m_iTankEnemyNumber;
CWeapon* m_pAim_nor;
CTextSprite* m_pScore; //表示分数的文本精灵
CTextSprite* m_pHight; //表示最高分的文本精灵
CTextSprite* m_pEnemy;//表示敌人数量的文本精灵
int m_iScore;//分数
int m_iEnemy;//敌人数量
int m_iHight;//几局最高分
float m_fDeltaTime;//表示游戏时间
int chooseStatus;//0~9分别代表9个需求
CTankFriend *m_friend_Tank;
public:
CGameMain(); //构造函数
//增加一个私有成员变量
CTankPlayer* m_pTankPlayer;
//添加子弹方法
void AddBullet( int iDir,float fPosX,float fPosY ,int iOwner);
CWeapon* FindWeaponByName(const char* szName);//根据名字查找到对象
void DeleteWeaponByName(const char* szName);
void AddTankEnemy(float fDeltaTime);
void DeleteAllSprite();
~CGameMain(); //析构函数
// Get方法
int GetGameState() { return m_iGameState; }
// Set方法
void SetGameState( const int iState ) { m_iGameState = iState; }
// 游戏主循环等
void GameMainLoop( float fDeltaTime );
void GameInit();
void GameRun( float fDeltaTime );
void GameEnd();
void OnMouseMove( const float fMouseX, const float fMouseY );
void OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY );
void OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY );
void OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress );
void OnKeyUp( const int iKey );
void OnSpriteColSprite( const char *szSrcName, const char *szTarName );
void OnSpriteColWorldLimit( const char *szName, const int iColSide );
};
/
//
extern CGameMain g_GameMain;
#endif // _LESSON_X_H_
LessonX.cpp
/
//
//
//
//
/
#include <Stdio.h>
#include "CommonClass.h"
#include "LessonX.h"
#include <iostream>
#include<windows.h>
#include<mmsystem.h>
#pragma comment(lib,"Winmm.lib")
//mciSendString(TEXT("open D:\C++\TankWar - 副本\background.wav"),NULL,NULL, NULL); //打开音乐文件
//
//mciSendString(TEXT("play D:\C++\TankWar - 副本\background.wav"),NULL,NULL,NULL); //播放音乐文件
//
//mciSendString(TEXT("D:\C++\TankWar - 副本\background.wav"),NULL,NULL, NULL); //关闭音乐
using namespace std;
//
//
CGameMain g_GameMain;
//地图初始化,1代表砖块
int g_iMap[11][13]=
{
{0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,1,0,1,1,1,1,0,0,1,0},
{0,1,0,1,0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,1,1,1,1,0,0,0,0},
{0,1,0,1,0,0,0,0,0,0,0,1,0},
{0,1,0,1,0,1,1,1,1,0,0,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,1,0,1,1,1,1,0,0,1,0},
{0,1,0,1,0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,1,1,1,0,0,0,0,0},
{0,0,0,0,0,1,0,1,0,0,0,0,0}
};
// int g_iMap[11][13]=
// {
// {0,0,0,0,0,0,0,0,0,0,0,0,0},
// {0,0,0,0,0,0,0,0,0,0,0,0,0},
// {0,1,0,0,0,1,0,1,0,0,0,1,0},
// {1,1,1,1,1,1,1,1,1,1,1,1,1},
// {0,0,0,1,0,1,0,1,0,1,0,0,0},
// {0,0,0,1,0,0,0,0,0,1,0,0,0},
// {0,0,0,1,0,1,0,1,0,1,0,0,0},
// {1,1,1,1,1,1,1,1,1,1,1,1,1},
// {0,1,0,1,0,0,0,0,0,1,0,1,0},
// {0,0,0,0,0,1,1,1,0,0,0,0,0},
// {0,0,0,0,0,1,0,1,0,0,0,0,0}
// };
//==============================================================================
//
// 大体的程序流程为:GameMainLoop函数为主循环函数,在引擎每帧刷新屏幕图像之后,都会被调用一次。
//==============================================================================
//
// 构造函数
CGameMain::CGameMain()
{
m_iGameState = 0;
m_iBulletNum = 0;
m_pSplash = new CSprite("splash");//与精灵进行绑定
m_pStart = new CSprite("start");
m_pScore = new CTextSprite("score");
m_pHight = new CTextSprite("hight");
m_pEnemy = new CTextSprite("enemyNum");
m_iScore=0;//分数
m_iEnemy=0;//敌人数量
m_iHight = 0;
m_fDeltaTime = 0.f;
}
//==============================================================================
//
// 析构函数
CGameMain::~CGameMain()
{
//析构函数中删除两个精灵
delete m_pSplash;
delete m_pStart;
}
//==============================================================================
//
// 游戏主循环,此函数将被不停的调用,引擎每刷新一次屏幕,此函数即被调用一次
// 用以处理游戏的开始、进行中、结束等各种状态.
// 函数参数fDeltaTime : 上次调用本函数到此次调用本函数的时间间隔,单位:秒
void CGameMain::GameMainLoop( float fDeltaTime )
{
switch( GetGameState() )
{
// 初始化游戏,清空上一局相关数据
case 1:
{
GameInit();
SetGameState(2); // 初始化之后,将游戏状态设置为进行中
}
break;
// 游戏进行中,处理各种游戏逻辑
case 2:
{
// TODO 修改此处游戏循环条件,完成正确游戏逻辑
if(!m_pTankPlayer->IsDead() && !m_pAim_nor->IsDead() && m_fDeltaTime<300)
{
GameRun( fDeltaTime );
}
else // 游戏结束。调用游戏结算函数,并把游戏状态修改为结束状态
{
SetGameState(0);
GameEnd();
}
}
break;
// 游戏结束/等待按空格键开始
case 0:
default:
break;
};
}
//=============================================================================
//
// 每局开始前进行初始化,清空上一局相关数据
void CGameMain::GameInit()
{
m_pSplash->SetSpriteVisible(false);
m_pStart->SetSpriteVisible(false);
// 实例化我方坦克
m_pTankPlayer=new CTankPlayer("myplayer");//新建一个名字是myPlayer的我方坦克对象
m_pTankPlayer->CloneSprite("player");//我方坦克克隆在funcode模板中存在的名字为player的坦克,表示新建的坦克对象有现在精灵的所有属性
m_pTankPlayer->Init();
m_pTankPlayer->SetSpritePositionX(-26+2);
m_pTankPlayer->SetSpritePositionY(22-2);
m_vWeapon.push_back(m_pTankPlayer);
// 初始化地方坦克
// m_pTankEnemy = new CTankEnemy("enemy");
// m_pTankEnemy->Init();
LoadMap();
m_iTankEnemyNumber = 0;
m_fTankEnemyTime = 0.f;
m_pAim_nor = new CWeapon("myaim_nor");
m_pAim_nor->CloneSprite("aim_nor");
m_vWeapon.push_back(m_pAim_nor);
m_pAim_nor->SetSpriteCollisionReceive(true);
m_pAim_nor->SetSpritePosition(0.f,20.f);
m_iBulletNum = 0;
m_iTankEnemyNumber = 0;
m_fTankEnemyTime = 4.f;
m_iScore = 0;
m_iHight = 0;
m_iEnemy = 0;
m_fDeltaTime = 0.f;
FILE * fp =fopen("save.dat","r+");
if(fp)
{
fread(&m_iHight,sizeof(int),1,fp);
fclose(fp);
}
m_pHight = new CTextSprite("hight");
m_pHight->SetTextValue(m_iHight);
// PlaySound("D:\\C++\\TankWar - 副本\\background.wav",NULL,SND_FILENAME|SND_ASYNC); //播放
// PlaySound(NULL,NULL,SND_FILENAME); //暂停当前音乐,其实就是放空音乐
// sndPlaySound("D:\\C++\\TankWar - 副本\\background.wav", SND_ASYNC | SND_NODEFAULT|SND_LOOP); //播放
// string str = "D:\\C++\\TankWar - 副本\\background.wav";
// mciSendString(("open D:\\C++\\TankWar - 副本\\background.wav"),NULL,NULL, NULL); //打开音乐文件
// mciSendString(("play movie"),"open D:\\C++\\TankWar - 副本\\background.wav",NULL,NULL); //播放音乐文件
}
//=============================================================================
//
// 每局游戏进行中
void CGameMain::GameRun( float fDeltaTime)
{
// if(m_pTankEnemy)
// {
// m_pTankEnemy->OnMove(fDeltaTime);
// m_pTankEnemy->OnFire(fDeltaTime);
// }
m_fDeltaTime += fDeltaTime;
m_pScore->SetTextValue(m_iScore);
m_pHight->SetTextValue(m_iHight);
m_pEnemy->SetTextValue(m_iEnemy);
AddTankEnemy(fDeltaTime);
// mciSendString("open D:\\C++\TankWar - 副本\\background.wav alias mymusic", NULL, 0, NULL); // 打开音乐
// mciSendString("setaudio mymusic volume to 600",NULL,0,NULL); //设置音量大小
// mciSendString("play mymusic", NULL, 0, NULL); //开始音乐
// mciSendString("play mymusic repeat", NULL, 0, NULL); //循环播放
//PlaySound(NULL,NULL,SND_FILENAME); //暂停当前音乐,其实就是放空音乐
for(int i=0;i<m_vWeapon.size();i++)
{
if(strstr(m_vWeapon[i]->GetName(),"bullet")!=NULL)
{
if(m_vWeapon[i]->GetHp()==0)
{
// cout<<"进来了"<<endl;
DeleteWeaponByName(m_vWeapon[i]->GetName());
continue;
}
}
if(!m_vWeapon[i]->IsDead())
{
if(strstr(m_vWeapon[i]->GetName(),"myfriend")!=NULL)
{
m_vWeapon[i]->OnMove();
}else if(strstr(m_vWeapon[i]->GetName(),"enemy")!=NULL){
m_vWeapon[i]->OnMove(fDeltaTime);
m_vWeapon[i]->OnFire(fDeltaTime);
}else{
m_vWeapon[i]->OnMove(fDeltaTime);
m_vWeapon[i]->OnFire(fDeltaTime);
}
}
else
{
DeleteWeaponByName(m_vWeapon[i]->GetName());
}
}
// cout<<m_pTankPlayer->GetName()<<"坦克的血量为:"<<m_pTankPlayer->GetHp()<<endl;
}
//=============================================================================
//
// 本局游戏结束
void CGameMain::GameEnd()
{
FILE * fp =fopen("save.dat","w+");
if(m_iScore>m_iHight)
fwrite(&m_iScore,sizeof(int),1,fp);
fclose(fp);
m_pSplash->SetSpriteVisible(true);
m_pStart->SetSpriteVisible(true);
SetGameState(0);
//mciSendString(TEXT("close D:\\C++\\TankWar - 副本\\background.wav"),NULL,NULL, NULL); //关闭音乐
}
//==========================================================================
//
// 鼠标移动
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void CGameMain::OnMouseMove( const float fMouseX, const float fMouseY )
{
}
//==========================================================================
//
// 鼠标点击
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void CGameMain::OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )
{
}
//==========================================================================
//
// 鼠标弹起
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void CGameMain::OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY )
{
}
//==========================================================================
//
// 键盘按下
// 参数 iKey:被按下的键,值见 enum KeyCodes 宏定义
// 参数 iAltPress, iShiftPress,iCtrlPress:键盘上的功能键Alt,Ctrl,Shift当前是否也处于按下状态(0未按下,1按下)
void CGameMain::OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress )
{
if( 0 ==GetGameState() )
{
//如果按下空格,而且现在的运行状态是0,就把他设置为1
if(iKey == KEY_SPACE)
{
m_iGameState = 1;
}
}
if(m_iGameState == 2)
{
m_pTankPlayer->OnMove(iKey, true);
if(iKey == KEY_J)//判断按下键是够为J键
{
m_pTankPlayer->OnFire();
if(m_friend_Tank!=NULL)
{
m_friend_Tank->OnFire();
}
}
}
}
//==========================================================================
//
// 键盘弹起
// 参数 iKey:弹起的键,值见 enum KeyCodes 宏定义
void CGameMain::OnKeyUp( const int iKey )
{
}
//===========================================================================
//
// 精灵与精灵碰撞
// 参数 szSrcName:发起碰撞的精灵名字
// 参数 szTarName:被碰撞的精灵名字
void CGameMain::OnSpriteColSprite( const char *szSrcName, const char *szTarName )
{
CWeapon* tarSprite = FindWeaponByName(szTarName);
if(strstr(szSrcName,"bullet") != NULL)//发送碰撞为子弹
{
// cout<<"tarSprite的名字是"<<tarSprite->GetName()<<" HP是"<<tarSprite->GetHp()<<endl;
if(strstr(tarSprite->GetName(),"myplayer")!=NULL)
{
int hp = m_pTankPlayer->GetHp();
tarSprite->SetHp(hp);
}else if(strstr(tarSprite->GetName(),"myaim_nor")!=NULL)
{
int hp = m_pAim_nor->GetHp();
tarSprite->SetHp(hp);
}
CBullet *tmpBullet = (CBullet*)FindWeaponByName(szSrcName);
tmpBullet->OnSpriteColSprite(tarSprite);
if( tmpBullet->GetOwner()==1 && strstr(szTarName,"enemy") != NULL)
{
m_iScore++;
m_iEnemy--;
}
CWeapon* pBullet = FindWeaponByName(szSrcName);
pBullet->SetHp(0);
}
else if(strcmp(szSrcName,"myplayer")==0) //发送碰撞为我方坦克
{
m_pTankPlayer->OnSpriteColSprite(tarSprite);
}
else if(strstr(szSrcName,"enemy") != NULL)//发送碰撞为敌方坦克
{
CTankEnemy* tmpEnemy = (CTankEnemy*)FindWeaponByName(szSrcName);
tmpEnemy->OnSpriteColSprite(tarSprite);
}else if(strstr(szSrcName,"myfriend")!=NULL)
{
m_friend_Tank->OnSpriteColSprite(tarSprite);
}
}
//===========================================================================
//
// 精灵与世界边界碰撞
// 参数 szName:碰撞到边界的精灵名字
// 参数 iColSide:碰撞到的边界 0 左边,1 右边,2 上边,3 下边
void CGameMain::OnSpriteColWorldLimit( const char *szName, const int iColSide )
{
// cout<<"触碰到世界边界"<<endl;
// 此处有BUG:不能够这样,必须重新设置一下位置
if(strstr(szName,"myplayer") != NULL) //判断碰到世界边界的坦克是否为我方坦克
{
//处理超出边界的情况
// cout<<"触碰到边界"<<endl;
if(iColSide==0)
{
m_pTankPlayer->SetSpritePositionX(-26+2);
}else if(iColSide==1)
{
m_pTankPlayer->SetSpritePositionX( 26-2);
}else if(iColSide==3)
{
m_pTankPlayer->SetSpritePositionY( 22-2);
}else if(iColSide==2)
{
m_pTankPlayer->SetSpritePositionY(-22+2);
}
m_pTankPlayer->SetSpriteLinearVelocity(0,0);
// 不先处理了,需要判断四个方向
// float x = m_pTankPlayer->GetSpritePositionX();
// float y = m_pTankPlayer->GetSpritePositionY();
// m_pTankPlayer->SetSpritePosition(x-0.01,y-0.01);
}else if(strstr(szName,"enemy") != NULL)
{
CWeapon* pEnemy = FindWeaponByName(szName);
if(iColSide==0)
{
pEnemy->SetSpritePositionX(-26+2);
}else if(iColSide==1)
{
pEnemy->SetSpritePositionX( 26-2);
}else if(iColSide==3)
{
pEnemy->SetSpritePositionY( 22-2);
}else if(iColSide==2)
{
pEnemy->SetSpritePositionY(-22+2);
}
pEnemy->SetSpriteLinearVelocity(0.f,0.f);
pEnemy->OnMove(pEnemy->GetDir());
}
else if(strstr(szName,"bullet") != NULL)
{
CWeapon* pBullet = FindWeaponByName(szName);
pBullet->SetHp(0);
}else if(strstr(szName,"myfriend")!=NULL)
{
if(iColSide==0)
{
m_friend_Tank->SetSpritePositionX(-26+2);
}else if(iColSide==1)
{
m_friend_Tank->SetSpritePositionX( 26-2);
}else if(iColSide==3)
{
m_friend_Tank->SetSpritePositionY( 22-2);
}else if(iColSide==2)
{
m_friend_Tank->SetSpritePositionY(-22+2);
}
m_friend_Tank->SetSpriteLinearVelocity(0.f,0.f);
}
// cout<<"此时坦克的速度是"<<m_pTankPlayer->GetSpeedY()<<" "<<m_pTankPlayer->GetSpeedX()<<endl;
}
//处理子弹事件
void CGameMain::AddBullet( int iDir,float fPosX,float fPosY ,int iOwner)
{
char* szName = CSystem::MakeSpriteName("bullet",m_iBulletNum);//创建坦克名字
CBullet* pBullet = new CBullet(szName);
if(iOwner == 1)
{
pBullet->SetOwner(1);//1表示我方坦克发射的子弹
}
else
{
pBullet->SetOwner(0); //0表示地方坦克发射的子弹
}
pBullet->CloneSprite("bullet");
pBullet->SetSpriteWorldLimit(WORLD_LIMIT_NULL,-26, -22, 26, 22); //设置世界边界
pBullet->SetSpritePosition(fPosX,fPosY);
pBullet->SetSpriteCollisionSend(true); //设置接收碰撞
pBullet->OnMove(iDir);
m_iBulletNum++; //子弹个数加1
m_vWeapon.push_back(pBullet);
}
void CGameMain::LoadMap()
{
char* szName;
int i,j;
float x,y;
for(i=0;i<11;i++)
{
for(j=0;j<13;j++)
{
if(g_iMap[i][j]==1)
{
szName = CSystem::MakeSpriteName("wall",j+i*13+i);//重新起名
CWeapon* pWall = new CWeapon(szName);//新建对象
pWall->CloneSprite("wall"); //克隆墙块
pWall->SetSpriteCollisionActive(0,1); //设置为接受碰撞
pWall->SetSpriteCollisionResponse(COL_RESPONSE_CUSTOM);
x =float(-24+4*j);
y =float(-20+4*i);
pWall->SetSpritePosition(x,y);
m_vWeapon.push_back(pWall);
}
}
}
}
CWeapon* CGameMain::FindWeaponByName(const char* szName)//根据名字查找到对象
{
for(int i=0; i<m_vWeapon.size(); i++)
{
if(strcmp(szName,m_vWeapon[i]->GetName()) == 0)
{
return m_vWeapon[i];
}
}
}
void CGameMain::DeleteWeaponByName(const char* szName)//根据名字把精灵从容器中删除
{
for(vector<CWeapon*>::iterator it=m_vWeapon.begin();it!=m_vWeapon.end();)
{
CWeapon* cw =*it;
if(strcmp(szName,cw->GetName()) == 0)
{
m_vWeapon.erase(it);
cw->DeleteSprite();
delete cw;
break;
}
else
{
it++;
}
}
}
void CGameMain::AddTankEnemy(float fDeltaTime)
{
m_fTankEnemyTime += fDeltaTime;
if(m_fTankEnemyTime > 5)
{
char* szName = CSystem::MakeSpriteName("enemy",m_iTankEnemyNumber);
CTankEnemy* m_pTankEnemy = new CTankEnemy(szName);
m_pTankEnemy->CloneSprite("enemy");
m_pTankEnemy->Init();
m_iTankEnemyNumber++;
m_vWeapon.push_back(m_pTankEnemy); //把创建的敌方坦克插入到容器中
m_fTankEnemyTime=0.f;
m_iEnemy++;
}
}
void CGameMain::DeleteAllSprite()
{
int n=m_vWeapon.size();
while(m_vWeapon.size()!=0)
{
vector<CWeapon*>::iterator itr=m_vWeapon.begin();
CWeapon* cw = *itr;
m_vWeapon.erase(itr);
cw->DeleteSprite();
delete cw;
}
}
Main.cpp
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
#include "CommonClass.h"
#include "LessonX.h"
///
//
// 主函数入口
//
//
int PASCAL WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 初始化游戏引擎
if( !CSystem::InitGameEngine( hInstance, lpCmdLine ) )
return 0;
// To do : 在此使用API更改窗口标题
CSystem::SetWindowTitle("坦克大战");
// 引擎主循环,处理屏幕图像刷新等工作
while( CSystem::EngineMainLoop() )
{
// 获取两次调用之间的时间差,传递给游戏逻辑处理
float fTimeDelta = CSystem::GetTimeDelta();
// 执行游戏主循环
g_GameMain.GameMainLoop( fTimeDelta );
};
// 关闭游戏引擎
CSystem::ShutdownGameEngine();
return 0;
}
//==========================================================================
//
// 引擎捕捉鼠标移动消息后,将调用到本函数
// 参数 fMouseX, fMouseY:为鼠标当前坐标
//
void CSystem::OnMouseMove( const float fMouseX, const float fMouseY )
{
// 可以在此添加游戏需要的响应函数
g_GameMain.OnMouseMove(fMouseX, fMouseY);
}
//==========================================================================
//
// 引擎捕捉鼠标点击消息后,将调用到本函数
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
//
void CSystem::OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )
{
// 可以在此添加游戏需要的响应函数
g_GameMain.OnMouseClick(iMouseType, fMouseX, fMouseY);
}
//==========================================================================
//
// 引擎捕捉鼠标弹起消息后,将调用到本函数
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
//
void CSystem::OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY )
{
// 可以在此添加游戏需要的响应函数
g_GameMain.OnMouseUp(iMouseType, fMouseX, fMouseY);
}
//==========================================================================
//
// 引擎捕捉键盘按下消息后,将调用到本函数
// 参数 iKey:被按下的键,值见 enum KeyCodes 宏定义
// 参数 iAltPress, iShiftPress,iCtrlPress:键盘上的功能键Alt,Ctrl,Shift当前是否也处于按下状态(0未按下,1按下)
//
void CSystem::OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress )
{
// 可以在此添加游戏需要的响应函数
g_GameMain.OnKeyDown(iKey, bAltPress, bShiftPress, bCtrlPress);
}
//==========================================================================
//
// 引擎捕捉键盘弹起消息后,将调用到本函数
// 参数 iKey:弹起的键,值见 enum KeyCodes 宏定义
//
void CSystem::OnKeyUp( const int iKey )
{
// 可以在此添加游戏需要的响应函数
g_GameMain.OnKeyUp(iKey);
}
//===========================================================================
//
// 引擎捕捉到精灵与精灵碰撞之后,调用此函数
// 精灵之间要产生碰撞,必须在编辑器或者代码里设置精灵发送及接受碰撞
// 参数 szSrcName:发起碰撞的精灵名字
// 参数 szTarName:被碰撞的精灵名字
//
void CSystem::OnSpriteColSprite( const char *szSrcName, const char *szTarName )
{
// 可以在此添加游戏需要的响应函数
g_GameMain.OnSpriteColSprite(szSrcName, szTarName);
}
//===========================================================================
//
// 引擎捕捉到精灵与世界边界碰撞之后,调用此函数.
// 精灵之间要产生碰撞,必须在编辑器或者代码里设置精灵的世界边界限制
// 参数 szName:碰撞到边界的精灵名字
// 参数 iColSide:碰撞到的边界 0 左边,1 右边,2 上边,3 下边
//
void CSystem::OnSpriteColWorldLimit( const char *szName, const int iColSide )
{
// 可以在此添加游戏需要的响应函数
g_GameMain.OnSpriteColWorldLimit(szName, iColSide);
}
CommonClass.h(里面加了一两个方法)
/
//
//
//
//
/
#ifndef _COMMON_CLASS_H_
#define _COMMON_CLASS_H_
//
#include <windows.h>
/
//
// 全局变量、宏定义
#define MAX_NAME_LEN 128 // 名字长度
/
//
// Sprite精灵与世界边界碰撞响应定义( 碰撞之后API OnSpriteColWorldLimit 将被调用 )
enum EWorldLimit
{
WORLD_LIMIT_OFF, // 关闭与世界边界的碰撞
WORLD_LIMIT_NULL, // 碰撞之后引擎不做任何处理,由各游戏自己处理响应
WORLD_LIMIT_RIGID, // 刚性物理碰撞反应
WORLD_LIMIT_BOUNCE, // 反弹模式
WORLD_LIMIT_CLAMP, // 小幅反弹,逐渐停止模式(比如篮球落地)
WORLD_LIMIT_STICKY, // 碰撞之后静止
WORLD_LIMIT_KILL, // 碰撞之后精灵将被删除
WORLD_LIMIT_INVALID, // 无效值
};
/
//
/// 精灵与精灵之间、精灵与地图中其它精灵之间的碰撞响应( 碰撞之后API OnSpriteColSprite 将被调用 )
enum ECollisionResponse
{
COL_RESPONSE_OFF, // 关闭碰撞响应(不调用OnSpriteColSprite)
COL_RESPONSE_RIGID, // 刚性物理碰撞响应
COL_RESPONSE_BOUNCE, // 反弹模式
COL_RESPONSE_CLAMP, // 小幅反弹,逐渐停止模式(比如篮球落地)
COL_RESPONSE_STICKY, // 碰撞之后静止
COL_RESPONSE_KILL, // 碰撞之后精灵将被删除
COL_RESPONSE_CUSTOM, // 碰撞之后引擎不做任何处理,由各游戏自己处理响应
COL_RESPONSE_INVALID, // 无效值
};
//================================================================================
//
// 鼠标按键值定义
enum MouseTypes
{
MOUSE_LEFT = 0, // 左键
MOUSE_RIGHT = 1, // 右键
MOUSE_MIDDLE = 2 // 中键
};
/
//
// 键盘KEY值定义
enum KeyCodes
{
KEY_NULL = 0x000, ///< Invalid KeyCode
KEY_BACKSPACE = 0x001,
KEY_TAB = 0x002,
KEY_ENTER = 0x003,
KEY_CONTROL = 0x004,
KEY_ALT = 0x005,
KEY_SHIFT = 0x006,
KEY_PAUSE = 0x007,
KEY_CAPSLOCK = 0x008,
KEY_ESCAPE = 0x009,
KEY_SPACE = 0x00a,
KEY_PAGE_DOWN = 0x00b,
KEY_PAGE_UP = 0x00c,
KEY_END = 0x00d,
KEY_HOME = 0x00e,
KEY_LEFT = 0x00f,
KEY_UP = 0x010,
KEY_RIGHT = 0x011,
KEY_DOWN = 0x012,
KEY_PRINT = 0x013,
KEY_INSERT = 0x014,
KEY_DELETE = 0x015,
KEY_HELP = 0x016,
KEY_0 = 0x017,
KEY_1 = 0x018,
KEY_2 = 0x019,
KEY_3 = 0x01a,
KEY_4 = 0x01b,
KEY_5 = 0x01c,
KEY_6 = 0x01d,
KEY_7 = 0x01e,
KEY_8 = 0x01f,
KEY_9 = 0x020,
KEY_A = 0x021,
KEY_B = 0x022,
KEY_C = 0x023,
KEY_D = 0x024,
KEY_E = 0x025,
KEY_F = 0x026,
KEY_G = 0x027,
KEY_H = 0x028,
KEY_I = 0x029,
KEY_J = 0x02a,
KEY_K = 0x02b,
KEY_L = 0x02c,
KEY_M = 0x02d,
KEY_N = 0x02e,
KEY_O = 0x02f,
KEY_P = 0x030,
KEY_Q = 0x031,
KEY_R = 0x032,
KEY_S = 0x033,
KEY_T = 0x034,
KEY_U = 0x035,
KEY_V = 0x036,
KEY_W = 0x037,
KEY_X = 0x038,
KEY_Y = 0x039,
KEY_Z = 0x03a,
KEY_TILDE = 0x03b,
KEY_MINUS = 0x03c,
KEY_EQUALS = 0x03d,
KEY_LBRACKET = 0x03e,
KEY_RBRACKET = 0x03f,
KEY_BACKSLASH = 0x040,
KEY_SEMICOLON = 0x041,
KEY_APOSTROPHE = 0x042,
KEY_COMMA = 0x043,
KEY_PERIOD = 0x044,
KEY_SLASH = 0x045,
KEY_NUMPAD0 = 0x046,
KEY_NUMPAD1 = 0x047,
KEY_NUMPAD2 = 0x048,
KEY_NUMPAD3 = 0x049,
KEY_NUMPAD4 = 0x04a,
KEY_NUMPAD5 = 0x04b,
KEY_NUMPAD6 = 0x04c,
KEY_NUMPAD7 = 0x04d,
KEY_NUMPAD8 = 0x04e,
KEY_NUMPAD9 = 0x04f,
KEY_MULTIPLY = 0x050,
KEY_ADD = 0x051,
KEY_SEPARATOR = 0x052,
KEY_SUBTRACT = 0x053,
KEY_DECIMAL = 0x054,
KEY_DIVIDE = 0x055,
KEY_NUMPADENTER = 0x056,
KEY_F1 = 0x057,
KEY_F2 = 0x058,
KEY_F3 = 0x059,
KEY_F4 = 0x05a,
KEY_F5 = 0x05b,
KEY_F6 = 0x05c,
KEY_F7 = 0x05d,
KEY_F8 = 0x05e,
KEY_F9 = 0x05f,
KEY_F10 = 0x060,
KEY_F11 = 0x061,
KEY_F12 = 0x062,
KEY_F13 = 0x063,
KEY_F14 = 0x064,
KEY_F15 = 0x065,
KEY_F16 = 0x066,
KEY_F17 = 0x067,
KEY_F18 = 0x068,
KEY_F19 = 0x069,
KEY_F20 = 0x06a,
KEY_F21 = 0x06b,
KEY_F22 = 0x06c,
KEY_F23 = 0x06d,
KEY_F24 = 0x06e,
KEY_NUMLOCK = 0x06f,
KEY_SCROLLLOCK = 0x070,
KEY_LCONTROL = 0x071,
KEY_RCONTROL = 0x072,
KEY_LALT = 0x073,
KEY_RALT = 0x074,
KEY_LSHIFT = 0x075,
KEY_RSHIFT = 0x076,
KEY_WIN_LWINDOW = 0x077,
KEY_WIN_RWINDOW = 0x078,
KEY_WIN_APPS = 0x079,
KEY_OEM_102 = 0x080,
KEY_MAC_OPT = 0x090,
KEY_MAC_LOPT = 0x091,
KEY_MAC_ROPT = 0x092,
KEY_BUTTON0 = 0x0100,
KEY_BUTTON1 = 0x0101,
KEY_BUTTON2 = 0x0102,
KEY_BUTTON3 = 0x0103,
KEY_BUTTON4 = 0x0104,
KEY_BUTTON5 = 0x0105,
KEY_BUTTON6 = 0x0106,
KEY_BUTTON7 = 0x0107,
KEY_BUTTON8 = 0x0108,
KEY_BUTTON9 = 0x0109,
KEY_BUTTON10 = 0x010A,
KEY_BUTTON11 = 0x010B,
KEY_BUTTON12 = 0x010C,
KEY_BUTTON13 = 0x010D,
KEY_BUTTON14 = 0x010E,
KEY_BUTTON15 = 0x010F,
KEY_BUTTON16 = 0x0110,
KEY_BUTTON17 = 0x0111,
KEY_BUTTON18 = 0x0112,
KEY_BUTTON19 = 0x0113,
KEY_BUTTON20 = 0x0114,
KEY_BUTTON21 = 0x0115,
KEY_BUTTON22 = 0x0116,
KEY_BUTTON23 = 0x0117,
KEY_BUTTON24 = 0x0118,
KEY_BUTTON25 = 0x0119,
KEY_BUTTON26 = 0x011A,
KEY_BUTTON27 = 0x011B,
KEY_BUTTON28 = 0x011C,
KEY_BUTTON29 = 0x011D,
KEY_BUTTON30 = 0x011E,
KEY_BUTTON31 = 0x011F,
KEY_ANYKEY = 0xfffe
};
//
//
// 类:CSprite
// 所有精灵的基类。包括下面的静态精灵,动态精灵,文字,特效等均由此类继承下去
// 一般的图片精灵从本类继承下去即可。只有特殊的精灵,比如带动画的精灵,才需要从动态精灵继承下去
//
class CSprite
{
private:
char m_szName[MAX_NAME_LEN]; // 精灵名字
public:
// 构造函数,需要传入一个非空的精灵名字字符串。如果传入的是地图里摆放好的精灵名字,则此类即与地图里的精灵绑定
// 如果传入的是一个新的精灵名字,则需要调用成员函数 CloneSprite,复制一份精灵对象实例,才与实际的地图精灵关联起来
// szCloneName : 预先存在于场景中,需要克隆的精灵名字
CSprite( const char *szName );
CSprite();
CSprite( const char *szName, const char *szCloneName );
virtual ~CSprite();
// GetName
// 返回值:返回精灵名字
const char *GetName();
// CloneSprite:复制(创建)一个精灵。精灵的创建方式:先在地图中摆放一个精灵做为模板,设置好各项参数,然后在代码里使用此函数克隆一个实例
// 返回值:true表示克隆成功,false克隆失败。失败的原因可能是在地图中未找到对应名字的精灵
// 参数 szSrcName:地图中用做模板的精灵名字
//
bool CloneSprite( const char *szSrcName );
// DeleteSprite:在地图中删除与本对象实例关联的精灵
//
void DeleteSprite();
// SetSpriteVisible:设置精灵隐藏或者显示(可见不可见)
// 参数 bVisible:true 可见 false不可见
//
void SetSpriteVisible( const bool bVisible );
// IsSpriteVisible:获取该精灵当前是否可见
//
bool IsSpriteVisible();
// SetSpriteEnable:禁止或者启用该精灵。被禁止的精灵将不参与任何响应,包括不移动,没有碰撞等,仅仅是在地图中显示
// 参数 bEnable:true启用 false禁止
//
void SetSpriteEnable( const bool bEnable );
// SetSpriteScale:设置精灵的缩放值
// 参数 fScale:缩放值。大于0的值
//
void SetSpriteScale( const float fScale );
// IsPointInSprite:判断某个坐标点是否位于精灵内部
// 参数 fPosX:X坐标点
// 参数 fPosY:Y坐标点
//
bool IsPointInSprite( const float fPosX, const float fPosY );
// SetSpritePosition:设置精灵位置
// 参数 fPosX:X坐标
// 参数 fPosY:Y坐标
//
void SetSpritePosition( const float fPosX, const float fPosY );
// SetSpritePositionX:只设置精灵X坐标
// 参数 fPosX:X坐标
//
void SetSpritePositionX( const float fPosX );
// SetSpritePositionY:只设置精灵Y坐标
// 参数 fPosY:Y坐标
//
void SetSpritePositionY( const float fPosY );
// GetSpritePositionX:获取精灵X坐标
// 返回值:精灵的X坐标
//
float GetSpritePositionX();
// GetSpritePositionY:获取精灵Y坐标
// 返回值:精灵的Y坐标
//
float GetSpritePositionY();
// GetSpriteLinkPointPosX:获取精灵链接点X坐标。链接点是依附于精灵的一个坐标点,可以在编辑器里增加或者删除
// 参数 iId:链接点序号,第一个为1,后面依次递加
//
float GetSpriteLinkPointPosX( const int iId );
// GetSpriteLinkPointPosY:获取精灵链接点Y坐标。链接点是依附于精灵的一个坐标点,可以在编辑器里增加或者删除
// 参数 iId:链接点序号,第一个为1,后面依次递加
//
float GetSpriteLinkPointPosY( const int iId );
// SetSpriteRotation:设置精灵的旋转角度
// 参数 fRot:旋转角度,范围0 - 360
//
void SetSpriteRotation( const float fRot );
// GetSpriteRotation:获取精灵的旋转角度
// 返回值:精灵的旋转角度
//
float GetSpriteRotation();
// SetSpriteAutoRot:设置精灵按照指定速度自动旋转
// 参数 fRotSpeed:旋转速度
//
void SetSpriteAutoRot( const float fRotSpeed );
// SetSpriteWidth:设置精灵外形宽度
// 参数 fWidth:宽度值,大于0
//
void SetSpriteWidth( const float fWidth );
// GetSpriteWidth:获取精灵外形宽度
// 返回值:精灵宽度值
//
float GetSpriteWidth();
// SetSpriteHeight:设置精灵外形高度
// 参数 fHeight:精灵高度值
//
void SetSpriteHeight( const float fHeight );
// GetSpriteHeight:获取精灵外形高度
// 返回值:精灵高度值
//
float GetSpriteHeight();
// SetSpriteFlipX:设置精灵图片X方向翻转显示
// 参数 bFlipX:true 翻转 false不翻转(恢复原来朝向)
//
void SetSpriteFlipX( const bool bFlipX );
// GetSpriteFlipX:获取当前精灵图片X方向是否是翻转显示
// 返回值:true 翻转 false不翻转
//
bool GetSpriteFlipX();
// SetSpriteFlipY:设置精灵图片Y方向翻转显示
// 参数 bFlipY:true 翻转 false不翻转(恢复原来朝向)
//
void SetSpriteFlipY( const bool bFlipY );
// GetSpriteFlipY:获取当前精灵图片Y方向是否是翻转显示
// 返回值:true 翻转 false不翻转
//
bool GetSpriteFlipY();
// SetSpriteFlip:同时设置精灵翻转X及Y方向
// 参数 bFlipX:true 翻转 false不翻转(恢复原来朝向)
// 参数 bFlipY:true 翻转 false不翻转(恢复原来朝向)
//
void SetSpriteFlip( const bool bFlipX, const bool bFlipY );
// SetSpriteLifeTime:设置精灵的生命时长,时间到了之后将自动被删除
// 参数 fLifeTime:生命时长,单位 秒
//
void SetSpriteLifeTime( const float fLifeTime );
// GetSpriteLifeTime:获取精灵生命时长
// 返回值:生命时长,单位 秒
//
float GetSpriteLifeTime();
// SpriteMoveTo:让精灵按照给定速度移动到给定坐标点
// 参数 fPosX:移动的目标X坐标值
// 参数 fPosY:移动的目标Y坐标值
// 参数 fSpeed:移动速度
// 参数 bAutoStop:移动到终点之后是否自动停止
//
void SpriteMoveTo( const float fPosX, const float fPosY, const float fSpeed, const bool bAutoStop );
// SpriteRotateTo:让精灵按照给定速度旋转到给定的角度
// 参数 fRotation:给定的目标旋转值
// 参数 fRotSpeed:旋转速度
// 参数 bAutoStop:旋转到终点之后是否自动停止
//
void SpriteRotateTo( const float fRotation, const float fRotSpeed, const bool bAutoStop );
// SetSpriteWorldLimit:设置精灵的世界边界坐标限制及碰撞模式
// 参数 Limit:碰撞到世界边界之后的响应模式,如果为OFF,则是关闭世界边界碰撞。其它值见 EWorldLimit
// 参数 fLeft:边界的左边X坐标
// 参数 fTop:边界的上边Y坐标
// 参数 fRight:边界的右边X坐标
// 参数 fBottom:边界的下边Y坐标
//
void SetSpriteWorldLimit( const EWorldLimit Limit, const float fLeft, const float fTop, const float fRight, const float fBottom );
// SetSpriteWorldLimitMode:设置精灵的世界边界碰撞模式
// 参数 Limit:碰撞到世界边界之后的响应模式,如果为OFF,则是关闭世界边界碰撞。其它值见 EWorldLimit
//
void SetSpriteWorldLimitMode( const EWorldLimit Limit );
// SetSpriteWorldLimitMin:设置精灵的世界边界上边及左边坐标限制
// 参数 fLeft:边界的左边X坐标
// 参数 fTop:边界的上边Y坐标
//
void SetSpriteWorldLimitMin( const float fLeft, const float fTop );
// SetSpriteWorldLimitMax:设置精灵的世界边界下边及右边坐标限制
// 参数 fRight:边界的右边X坐标
// 参数 fBottom:边界的下边Y坐标
//
void SetSpriteWorldLimitMax( const float fRight, const float fBottom );
// GetSpriteWorldLimitLeft:获取精灵世界边界左边界限制
//
float GetSpriteWorldLimitLeft();
// GetSpriteWorldLimitTop:获取精灵世界边界上边界限制
//
float GetSpriteWorldLimitTop();
// GetSpriteWorldLimitRight:获取精灵世界边界右边界限制
//
float GetSpriteWorldLimitRight();
// GetSpriteWorldLimitBottom:获取精灵世界边界下边界限制
//
float GetSpriteWorldLimitBottom();
// SetSpriteCollisionSend:设置精灵是否可以发送(产生)碰撞
// 精灵的碰撞方式为:当A移动中碰上B时,如果A是可以产生碰撞的,B是可以接受碰撞的,则这2个物体会产生碰撞,精灵碰撞的API将被调用。否则无碰撞发生
// 参数 bSend:true 可以产生 false 不产生
//
void SetSpriteCollisionSend( const bool bSend );
// SetSpriteCollisionReceive:设置精灵是否可以接受碰撞
// 精灵的碰撞方式为:当A移动中碰上B时,如果A是可以产生碰撞的,B是可以接受碰撞的,则这2个物体会产生碰撞,精灵碰撞的API将被调用。否则无碰撞发生
// 参数 bReceive:true 可以接受 false 不接受
//
void SetSpriteCollisionReceive( const bool bReceive );
// SetSpriteCollisionActive:同时设置精灵是否可以产生及接受碰撞
// 精灵的碰撞方式为:当A移动中碰上B时,如果A是可以产生碰撞的,B是可以接受碰撞的,则这2个物体会产生碰撞,精灵碰撞的API将被调用。否则无碰撞发生
// 参数 bSend:true 可以产生 false 不产生
// 参数 bReceive:true 可以接受 false 不接受
//
void SetSpriteCollisionActive( const bool bSend, const bool bReceive );
// SetSpriteCollisionPhysicsSend:设置精灵是否可以发送(产生)物理碰撞
// 参数 bSend:true 可以产生 false 不产生
//
void SetSpriteCollisionPhysicsSend( const bool bSend );
// SetSpriteCollisionPhysicsReceive:设置精灵是否可以接受物理碰撞
// 参数 bReceive:true 可以接受 false 不接受
//
void SetSpriteCollisionPhysicsReceive( const bool bReceive );
// GetSpriteCollisionSend:获取精灵当前是否是可以产生碰撞
// 返回值:true 可以产生 false 不产生
//
bool GetSpriteCollisionSend();
// GetSpriteCollisionReceive:获取精灵当前是否是可以接受碰撞
// 返回值:true 可以接受 false 不接受
//
bool GetSpriteCollisionReceive();
// SetSpriteCollisionResponse:设置精灵与精灵的碰撞响应模式
// 参数 Response:响应模式,如果为OFF,则为关闭碰撞响应,碰撞API将不会被调用。其它值见 ECollisionResponse
//
void SetSpriteCollisionResponse( const ECollisionResponse Response );
// SetSpriteCollisionMaxIterations:设置精灵碰撞之后的最大反弹次数
// 参数 iTimes:反弹次数
//
void SetSpriteCollisionMaxIterations( const int iTimes );
// SetSpriteForwardMovementOnly:设置精灵是否只能朝前移动
// 参数 bForward:true 只能朝前移动 false 可以朝其他方向移动
//
void SetSpriteForwardMovementOnly( const bool bForward );
// GetSpriteForwardMovementOnly:获取精灵当前是否只能朝前移动
// 返回值:true 只能朝前移动 false 可以朝其它方向移动
//
bool GetSpriteForwardMovementOnly();
// SetSpriteForwardSpeed:设置精灵向前的速度
// 参数 fSpeed:速度
//
void SetSpriteForwardSpeed( const float fSpeed );
// SetSpriteImpulseForce:设置精灵瞬间推力
// 参数 fForceX:X方向推力大小
// 参数 fForceY:Y方向推力大小
// 参数 bGravitic:是否计算重力
//
void SetSpriteImpulseForce( const float fForceX, const float fForceY, const bool bGravitic );
// SetSpriteImpulseForcePolar:按角度朝向设置精灵瞬间推力
// 参数 fPolar:角度朝向
// 参数 fForce:推力大小
// 参数 bGravitic:是否计算重力
//
void SetSpriteImpulseForcePolar( const float fPolar, const float fForce, const bool bGravitic );
// SetSpriteConstantForceX:设置精灵X方向常量推力
// 参数 fForceX:X方向推力大小
//
void SetSpriteConstantForceX( const float fForceX );
// SetSpriteConstantForceY:设置精灵Y方向常量推力
// 参数 fForceY:Y方向推力大小
//
void SetSpriteConstantForceY( const float fForceY );
// SetSpriteConstantForceGravitic:精灵在计算常量推力的时候,是否计算重力
// 参数 bGravitic:是否计算重力
//
void SetSpriteConstantForceGravitic( const bool bGravitic );
// SetSpriteConstantForce:设置精灵常量推力
// 参数 fForceX:X方向推力大小
// 参数 fForceY:Y方向推力大小
// 参数 bGravitic:是否计算重力
//
void SetSpriteConstantForce( const float fForceX, const float fForceY, const bool bGravitic );
// SetSpriteConstantForcePolar:按角度朝向设置精灵常量推力
// 参数 fPolar:角度朝向
// 参数 fForce:推力大小
// 参数 bGravitic:是否计算重力
//
void SetSpriteConstantForcePolar( const float fPolar, const float fForce, const bool bGravitic );
// StopSpriteConstantForce:停止精灵常量推力
//
void StopSpriteConstantForce();
// SetSpriteForceScale:按倍数缩放精灵当前受的推力
// 参数 fScale:缩放值
//
void SetSpriteForceScale( const float fScale );
// SetSpriteAtRest:暂停/继续精灵的各种受力计算
// 参数 bRest:true 暂停 false 继续
//
void SetSpriteAtRest( const bool bRest );
// GetSpriteAtRest:获取精灵当前是否在暂停中
// 返回值:true 暂停中 false 正常
//
bool GetSpriteAtRest( );
// SetSpriteFriction:设置精灵摩擦力
// 参数 fFriction:摩擦力大小
//
void SetSpriteFriction( const float fFriction );
// SetSpriteRestitution:设置精灵弹力
// 参数 fRestitution:弹力值大小
//
void SetSpriteRestitution( const float fRestitution );
// SetSpriteMass:设置精灵质量
// 参数 fMass:质量大小
//
void SetSpriteMass( const float fMass );
// GetSpriteMass:获取精灵质量
// 返回值 :质量大小
//
float GetSpriteMass();
// SetSpriteAutoMassInertia:开启或者关闭精灵惯性
// 参数 bStatus:true 开启 false 关闭
//
void SetSpriteAutoMassInertia( const bool bStatus );
// SetSpriteInertialMoment:设置精灵惯性大小
// 参数 fInert:惯性大小
//
void SetSpriteInertialMoment( const float fInert );
// SetSpriteDamping:设置精灵衰减值
// 参数 fDamp:衰减值大小
//
void SetSpriteDamping( const float fDamp );
// SetSpriteImmovable:设置精灵是否不可移动
// 参数 bImmovable:true 不可以移动 false 可以移动
//
void SetSpriteImmovable( const bool bImmovable );
// GetSpriteImmovable:获取精灵当前是否不可以移动
// 返回值:true 不可以移动 false 可以移动
//
bool GetSpriteImmovable();
// SetSpriteLinearVelocity:设置精灵移动速度
// 参数 fVelX:X方向速度
// 参数 fVelY:Y方向速度
//
void SetSpriteLinearVelocity( const float fVelX, const float fVelY );
// SetSpriteLinearVelocityX:设置精灵X方向移动速度
// 参数 fVelX:X方向速度
//
void SetSpriteLinearVelocityX( const float fVelX );
// SetSpriteLinearVelocityY:设置精灵Y方向移动速度
// 参数 fVelY:Y方向速度
//
void SetSpriteLinearVelocityY( const float fVelY );
// SetSpriteLinearVelocityPolar:按角度朝向设置精灵移动速度
// 参数 fSpeed:移动速度
// 参数 fPolar:角度朝向
//
void SetSpriteLinearVelocityPolar( const float fSpeed, const float fPolar );
// SetSpriteAngularVelocity:设置精灵角度旋转速度
// 参数 fAngular:角度旋转速度
//
void SetSpriteAngularVelocity( const float fAngular );
// SetSpriteMinLinearVelocity:设置精灵最小速度
// 参数 fMin:最小速度值
//
void SetSpriteMinLinearVelocity( const float fMin );
// SetSpriteMaxLinearVelocity:设置精灵最大速度
// 参数 fMax:最大速度值
//
void SetSpriteMaxLinearVelocity( const float fMax );
// SetSpriteMinAngularVelocity:设置精灵最小角速度
// 参数 fMin:最小角速度
//
void SetSpriteMinAngularVelocity( const float fMin );
// SetSpriteMaxAngularVelocity:设置精灵最大角速度
// 参数 fMax:最大角速度
//
void SetSpriteMaxAngularVelocity( const float fMax );
// GetSpriteLinearVelocityX:获取精灵X方向速度
// 返回值:X方向速度
//
float GetSpriteLinearVelocityX();
// GetSpriteLinearVelocityY:获取精灵Y方向速度
// 返回值:Y方向速度
//
float GetSpriteLinearVelocityY();
// SpriteMountToSprite:将一个精灵绑定到另一个精灵上,暂时的成为另一个精灵的一部分,跟随其运动等
// 参数 szDstName:承载绑定的母体精灵名字
// 参数 fOffSetX:绑定偏移X
// 参数 fOffsetY:绑定偏移Y
// 返回值:返回一个绑定ID
//
int SpriteMountToSprite( const char *szDstName, const float fOffSetX, const float fOffsetY );
// SpriteMountToSpriteLinkPoint:将一个精灵绑定到另一个精灵上,绑定位置为指定的链接点,暂时的成为另一个精灵的一部分,跟随其运动等
// 参数 szDstName:承载绑定的母体精灵名字
// 参数 iPointId:链接点序号
// 返回值:返回一个绑定ID
//
int SpriteMountToSpriteLinkPoint( const char *szDstName, const int iPointId );
// SetSpriteMountRotation:设置精灵的绑定朝向,即相对于母体的朝向
// 参数 fRot:角度朝向,0 - 360
//
void SetSpriteMountRotation( const float fRot );
// GetSpriteMountRotation:获取精灵的绑定朝向,即相对于母体的朝向
// 返回值:角度朝向
//
float GetSpriteMountRotation();
// SetSpriteAutoMountRotation:设置精灵绑定之后自动旋转
// 参数 fRot:旋转速度
//
void SetSpriteAutoMountRotation( const float fRot );
// GetSpriteAutoMountRotation:获取精灵绑定之后的自动旋转值
// 返回值:旋转速度
//
float GetSpriteAutoMountRotation();
// SetSpriteMountForce:绑定至另一个精灵时,附加的作用力
// 参数 fFroce:作用力
//
void SetSpriteMountForce( const float fForce );
// SetSpriteMountTrackRotation:绑定的精灵是否跟随母体旋转
// 参数 bTrackRotation:true 跟随 false 不跟随
//
void SetSpriteMountTrack