望望窗外,单日人数过两万了,心塞,挺住。吃点水饺,埋头写作。

这是多年前写的一个格斗小游戏,类似拳皇的玩法。今天把代码贴出来。


一个人制作的格斗游戏


//按 WSAD 键移动。
//按 X 键切换蹲起状态。

//按 U键 左手攻击(轻攻击)、按 J键 右手攻击(重攻击)、按 I键 左腿攻击(轻攻击)、按 K键 右腿攻击(重攻击)、
//按攻击键时同时按住W攻击上路,同时按S攻击下路,否则默认攻击中路。

//按 O键 如果必杀能量足够可以释放必杀技。
//必杀能量不足时可以通过连续按键来释放必杀技,必杀技分 
//↓→A 、↓←A 、 →↓→A 、 ↙↓↘A 、 ↓→↓→A 。(A 代表四个攻击键中的某一个)

//按 L键 防御。同时按住W防御上路,同时按S防御下路,否则默认防御中路。
//由于防御难度太大,未按路数键(方向键)时有几率自动判断防御路数,随着防御状态持续时间加长,此几率变小。
//中了必杀技的前1秒内,按闪进加防御(两次相同方向键+L)可以打断必杀。

//按 同一方向键连续两次 闪进。根据闪进能量大小持续时间不同,闪进中不会和敌人发生推挤。

//攻击判断:被防御到正确路数则攻击无法命中,
//          处于跳起状态时无法命中处于站蹲状态的敌方下路,同理处于蹲状态时无法命中处于跳状态的敌方上路

//游戏中有3个人物:1p、2p和AI。
//1p 为玩家1键盘控制,也可以在左下角勾选自动挂机。
//2p 为玩家2键盘控制,也可以在左下角勾选自动挂机。 2p默认为敌对方,可以通过左下角勾选盟友来改变。
//AI 为电脑控制,调试时可以在右侧勾选禁用某些状态。
//联机时2p按键同1p,同机对打时2p按键对应为小键盘↙↓↘、456 123 0 . 。

//人物动作:
//(pose站、蹲、跳) X (road上、中、下) X (attack左手、右手、左腿、右腿) = 46种攻击
//(pose站、蹲、跳) X (road上、中、下) = 9种被击
//(pose站、蹲、跳) X (待机、行走、闪避、跳跃、防御、死亡) = 18种常态
//每种状态做2种动画,共约 (46+9+18)*2 = 146种动作变化
//必杀技 X 若干

//站立待机状态按12~9键触发可以播放特殊动作

//红蓝两队 各有一个半场。 可以冲到对方半场打砸各种物品。也要防守自方物品。

//可以捡起物品做武器持手中或扔击(任意时刻也可以被对方打碎,未捡取状态也能被脚踢飞)。
//被擒拿 攻击防御动作失效 

随便配了几个必杀技: 每个必杀技需要连续按一系列按键才能触发,可以设置攻击、被击动作和全屏特效。必杀动作都是固定预制好的,可以做的很花哨。全屏特效就是max导出的单个特效文件。

"",
8,

ID51001,  "轰斧阳" animCaster"standing_superskill01",animTarget"standing_beSuperskill01","data/sound/gladiator/superSkill01.wav"
inputStream["↓,→,↓,U,0,"],  attackDis18,  attackAng60,  defendDis30,  defendAng60,  

ID51002,  "决战奥义" animCaster"standing_superskill02",animTarget"standing_beSuperskill02","data/sound/gladiator/superSkill02.wav"
inputStream["↓,→,↓,I,0,"],  attackDis20,  attackAng60,  defendDis30,  defendAng60,  

ID51003,  "超级闪电踢" animCaster"standing_superskill03",animTarget"standing_beSuperskill03","data/sound/gladiator/SuperSkill03.mp3"
inputStream["↓,→,↓,J,0,"],  attackDis20,  attackAng60,  defendDis30,  defendAng60,  

ID51004,  "天地返" animCaster"standing_superskill01",animTarget"standing_beSuperskill01","data/sound/gladiator/superSkill01.wav"
inputStream["↓,→,↓,K,0,"],  attackDis20,  attackAng60,  defendDis30,  defendAng60,  

ID51005,  "百贰拾八式" animCaster"standing_superskill03",animTarget"standing_beSuperskill03","data/sound/gladiator/SuperSkill03.mp3"
inputStream["↓,↙,↓,U,0,"],  attackDis20,  attackAng60,  defendDis30,  defendAng60,  
    
ID51006,  "地狱极乐落" animCaster"standing_superskill02",animTarget"standing_beSuperskill02",,"data/sound/gladiator/superSkill02.wav"
inputStream["↓,↙,↓,I,0,"],  attackDis20,  attackAng60,  defendDis30,  defendAng60,  

ID51007,  "出云投" animCaster"standing_superskill01",animTarget"standing_beSuperskill01","data/sound/gladiator/superSkill01.wav"
inputStream["↓,↙,↓,J,0,"],  attackDis20,  attackAng60,  defendDis30,  defendAng60,  

ID51008,  "超裂破弹" animCaster"standing_superskill02",animTarget"standing_beSuperskill02","data/sound/gladiator/superSkill02.wav"
inputStream["↓,↙,↓,K,0,"],  attackDis20,  attackAng60,  defendDis30,  defendAng60,  

"success",

 电脑跑不动了,在以前的视频里截了张图。

java做拳皇 拳皇wing代码_Email

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/Gladiator/GladiatorCommon.h
//  @Brief:     GladiatorCommon
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 

#ifndef  __GladiatorCommon__H__
#define  __GladiatorCommon__H__

#include "MiniCommon/MiniCommon.h"
#include "AI/Entity/GameStyle.h"

namespace GladiatorGame
{
	enum Direction
	{
		Front45=1,
		Front90=2,
		Front180=4,
		Back90=8,
		Left90=16,
		Right90=32,
	};

	enum GladiatorCharacterState
	{
		GS_None,            // 
		GS_Stand,           //站立待机
		GS_Jump,            //跳
		GS_Walk,            //移动
		GS_Forward,         //闪进突破、闪避 闪进中不会和敌人碰撞
		GS_Defend,          //防守
		GS_LightPunch,      //轻拳
		GS_HeavyPunch,      //重拳
		GS_LightKick,       //轻踢
		GS_HeavyKick,       //重踢
		GS_BeBeaten,        //被击打
		GS_SuperSkill,      //必杀技:todo特效绑定
		GS_BeSuperSkill,    //被必杀
		GS_Catch,           //擒拿  ?和superskill没多大区别 没有发送原点偏移时才适合播放脱离动作  或者设置新的位置时两人距离不能太远
		GS_BeCatch,         //被擒拿 攻击防御动作失效 被普通击打播不倒地动作
		GS_EscapeCatch,     //摆脱擒拿
		GS_BeEscapeCatch,   //被摆脱擒拿
		GS_Show,            //秀
		GS_Dead,            //死亡
		
		GS_Screen,          //掩护
		GS_ShootAfter,      //破招 投掷对手 投掷大招 投掷道具
		GS_Victory,         //
		GS_Lose,            //
		GS_MaxNum,
	};
	const char* GladiatorCharacterStateToString(int enumeration);

#define RegisterAllStateFun(ObjClass) \
	RegisterStateFun(ObjClass,GS_None            );\
	RegisterStateFun(ObjClass,GS_Stand           );\
	RegisterStateFun(ObjClass,GS_Jump            );\
	RegisterStateFun(ObjClass,GS_Walk            );\
	RegisterStateFun(ObjClass,GS_Forward         );\
	RegisterStateFun(ObjClass,GS_LightPunch      );\
	RegisterStateFun(ObjClass,GS_HeavyPunch      );\
	RegisterStateFun(ObjClass,GS_LightKick       );\
	RegisterStateFun(ObjClass,GS_HeavyKick       );\
	RegisterStateFun(ObjClass,GS_Defend          );\
	RegisterStateFun(ObjClass,GS_SuperSkill      );\
	RegisterStateFun(ObjClass,GS_BeSuperSkill    );\
	RegisterStateFun(ObjClass,GS_BeBeaten        );\
	RegisterStateFun(ObjClass,GS_Catch           );\
	RegisterStateFun(ObjClass,GS_BeCatch         );\
	RegisterStateFun(ObjClass,GS_Show            );\
	RegisterStateFun(ObjClass,GS_Dead            );\

	//秀 站立待机状态可以秀的特殊动作
	//按12~9键触发,盟友必杀释放成功时没必要自动触发,因为镜头看不见,且可能正在和另一个玩家打斗中。
	enum ShowAnim
	{
		SA_Celebrate,       //庆祝 
		SA_Annoyed,         //败恼
		SA_Defiant,         //挑衅  嗑药
		SA_PassReq,         //挥手请求支援
		SA_Num,
	};
	const char* ShowAnimToString(int enumeration);

	enum KeyEvent
	{
		K_NULL   = -1,
		K_UP     = 0,
		K_DOWN   = 1,
		K_LEFT   = 2,
		K_RIGHT  = 3,
		K_SQUAT  = 4,
		K_JUMP   = 5,
		K_PUNCHA = 6,
		K_PUNCHB = 7,
		K_KICKA  = 8,
		K_KICKB  = 9,
		K_ENERGY = 10,
		K_DEFEND = 11,
		K_RAPID  = 12,
		K_NUM    = 13,
	};	
	const char* KeyEventToString(int enumeration);


	enum KeyStream
	{
		S_NULL   = 0,
		S_UP     = 1,
		S_DOWN   = 2,
		S_LEFT   = 4,
		S_RIGHT  = 8,
		S_UPL    = 5,
		S_UPR    = 9,
		S_DOWNL  = 6,
		S_DOWNR  = 10,
		S_PUNCHA = 11,
		S_PUNCHB = 12,
		S_KICKA  = 13,
		S_KICKB  = 14,
		S_DEFEND = 15,
		S_NUM    = 16,
	};	

	//路数
	enum GladiatRoadType
	{
		Road_Up = 0,  //上路
		Road_Middle,  //中路
		Road_Down,    //下路
		Road_Num,
	};
	const char* GladiatRoadToString(int enumeration);

	//位置层
	enum GladiatPoseType
	{
		Standing = 0,  //立Straight
		Squatting,     //蹲
		Jumpping,      //跳
		GladiatPoseNum,
	};
	const char* GladiatPoseToString(int enumeration);

	//能力属性
	enum GladiatAbility
	{
		Stat_PunchPower= 0,	//拳力
		Stat_KickPower,	    //脚力
		Stat_Footwork ,     //步法 
		Stat_MartialArt,	//武术 
		Stat_Slipping,		//打滑 
	};

	//招数的属性(用于克制)
	enum GladiatPropty
	{
		FP_Metal = 0,  //金
		FP_Wood,      //木
		FP_Water,     //水
		FP_Fire,      //上空路
		FP_Earth,
	};

	enum GladiatorTeamState
	{
		TS_None,
		TS_Attack,
		TS_Defend,
	};

	//enum MovieType
	//{
	//	MT_None,
	//	MT_EnterCourt,
	//	MT_ExitCourt,
	//	MT_PerfectAfter,
	//  MT_Win,
	//	MT_Lose,
	//};

	enum GladiatorGameState
	{
		GameS_None,
		GameS_Movie,
		GameS_Playing,
		GameS_Num,
	};

	enum GladiatOccupationType
	{
		OT_Forward=0,
		OT_Center,
		OT_Guard,
		OT_PowerFoward,
		OT_SmallFoward,
		OT_ShootingGuard,
		OT_PointGuard,
	};

	//enum RecordType
	//{
	//	Kill,
	//	Perfect,
	//	Screen,
	//	SupperSkill,
	//	RecordNum
	//};

	//enum SoundType
	//{
	//	ST_GoodJob,
	//	ST_LightHit,
	//	ST_ScreenMe,
	//	ST_Sorry,
	//	ST_Yell,
	//	ST_NUM
	//};

	//
	enum GladiatPlayerType
	{
		Player1P = 0,  //1p
		Player2P,     //
		PlayerNum,
	};

	class GladiatorHalfCourt
	{
	public:
		GladiatorHalfCourt(){};
		void SetPos(vec3& zeroPos,vec3& rimPos,vec3& southLeftCornerPos,float dist3Point);
		vec3 m_zeroPos;
		vec3 m_rimPos;
		vec3 m_rimGroundPos;
		vec3 m_leftCornerPos;
		vec3 m_rightCornerPos;

		vec3 m_startPosAttackThree[3];
		vec3 m_startPosDefendThree[3];

		vec3 m_startPosAttackFive[5];
		vec3 m_startPosDefendFive[5];

		float m_dist3Point;
		float m_distCloseUp;
		float m_distMiddle;

		HalfCourtType m_type;
	};
};

using namespace GladiatorGame;			   

enum MiniGladiatCmd
{
	GCMD_GladiatorMove,       //移动
	GCMD_ChangeOpp,  //切换目标
	GCMD_ChangeState,//切换状态
	GCMD_Anim,      //播放动画
};


//连续按键间隔
#define StreamTime 0.6f
static const int MaxKeyStreamSize = 5;
#define MoveForce 400.0f//20.0f 加速过程不适合动作游戏 
#define ForwardForce 400.0f



class GladiatorCharacter;

class GladiatorSuperSkillStyle:public Style
{
public:
	DeclareStyleEnum(GladiatorSuperSkillStyle          ,51001);
	virtual ~GladiatorSuperSkillStyle(){}

	//条件 技能是否可以触发依赖于自身状态 按键 气等,与对手状态无关, 但是对手可以防住
	//K_DOWN,K_RIGHT,K_KICKB, K_NULL,K_NULL,
	KeyStream m_inputStream[MaxKeyStreamSize];//连续按键流

	float    m_needMana; //需要的气
	float    m_defendTime; //对方防守的有效时间 太晚就防守不住 ?用帧事件来通知

//	FightActionStyle m_actionStyle;   
//	bool             m_effectRoad[Road_Max]; //可以进攻或防守的路数
//	float            m_effectRoadValue[Road_Max]; //可以进攻或防守的各路 成功几率
//	FightActionProp  m_prop;
//
//	bool     m_initiative; //主动出发动作
	float    m_attackDis;//攻击距离
	float    m_attackAng;//攻击扇形角度

	float    m_defendDis;//防守距离
	float    m_defendAng;//防守扇形角度

	String m_soundName;
	//动作
	String m_animCasterName;//攻击者动作
	String m_animTargetName;//目标动作 ,单一固定

	//camera  change view between caster and target

	//根据攻击的拳脚位置 hit事件自动选择组合比较复杂?

//	virtual bool CanCast(LogicCharacter* caster,LogicCharacter* target,Gladiator* gladiator);
//	virtual bool DoCast(LogicCharacter* attacker,LogicCharacter* target);
//	virtual bool DoDamage(LogicCharacter* attacker,LogicCharacter* target);
	virtual bool Load(File& file);
	virtual bool Save(File& file);
};


特化
//class SuperSkillStyleKickBackswing:public SuperSkillStyle
//{
//public:
//};


#endif

 玩家基类:

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/Gladiator/Gladiator.h
//  @Brief:     Gladiator
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 

#ifndef  __Gladiator__H__
#define  __Gladiator__H__

#include "AI/Entity/LogicCharacter.h"
#include "Gladiator/GladiatorCommon.h"
#include "Render/Texture.h"
#include "Rpg/MiniGame.h"

//攻击流程:A开始击打B,此时A播放攻击动作并同步给其它玩家,B动作不受影响,也可能同时发动攻击动作,并同步。
//          A或B的客户端各自更新,看谁的hittime先到达。比如B客户端上角色A的hittime先到达则先判断A攻击B是否成功,成功的话发消息。
//          如果延迟的原因hittime同时到达,则A和B各自都可能被攻击成功。
//          攻击成功与否交给被攻击roleB所在客户端判断,roleA客户端不判断,以免互相同步进入死循环。 如果被攻击的是robot同样交给robot所在客户端即host来判断是否成功。
struct GladiatorCharacterStyle:public CharacterStyle
{
public:
	DeclareStyleEnum(GladiatorCharacterStyle          ,214);
	virtual bool Load(File& file);
	virtual bool Save(File& file);
	float m_attackSpeed;
	float m_attackPoint;

	int   m_defendPoint;
	int   m_hpPoint;
	
};

class GladiatorCharacterBanner:public Banner
{
public:
	GladiatorCharacterBanner();
	virtual ~GladiatorCharacterBanner(){}
	virtual void Init();
	virtual void Render();
	//GuiDlg m_uiBanner;
	TexturePtr m_textureOccupation;
};


class GladiatorTeam;
class GladiatorItem;
class GladiatorCharacter: public LogicCharacter, public MiniPlayer//,public StateClass<GladiatorCharacter,GS_MaxNum>
{
public:
	GladiatorCharacter();
	~GladiatorCharacter();
	virtual void Free();
	virtual void Update();
	virtual void Render();
	//virtual void RenderBannerUI();


	virtual bool SetStyle(Style* style);
	//virtual GladiatorCharacterStyle*  GetStyle();
	//virtual RoleBanner* GetBanner( BannerSlot slot );

	virtual void OnAnimCallBack(const char* frameName);
	virtual void UpdateMovement();

	void  UpdateCommonPre();
	void  UpdateCommonAfter();

	//获得某帧时攻击位置(手或脚上的tag attackor)
	bool  GetAttackorPosOnFrame(const char*frame,vec3& out,bool localCoord);

	//根据脚的位置来调整自己的站立位置
	void  SetPosByFoot(const char*frame);
//	void  PlaySound_(SoundType type,bool loopFlag = false);

	void  SetDebugStr(const char* str,const Color& color);

	<<状态
	DeclareStateFun(GS_None            );       
	DeclareStateFun(GS_Stand           );       
	DeclareStateFun(GS_Jump            );       
	DeclareStateFun(GS_Walk            );       
	DeclareStateFun(GS_Forward         );
	DeclareStateFun(GS_LightPunch      );      
	DeclareStateFun(GS_HeavyPunch      );      
	DeclareStateFun(GS_LightKick       );       
	DeclareStateFun(GS_HeavyKick       );   
	DeclareStateFun(GS_Defend          );  
	DeclareStateFun(GS_SuperSkill      ); 
	DeclareStateFun(GS_BeSuperSkill    ); 
	DeclareStateFun(GS_BeBeaten        ); 
	DeclareStateFun(GS_Catch           ); 
	DeclareStateFun(GS_BeCatch         ); 
	DeclareStateFun(GS_Show            ); 
	DeclareStateFun(GS_Dead            );
	//typedef StateClass<GladiatorCharacter,GS_MaxNum> ThisStateClass;
	typedef bool (GladiatorCharacter::*StateFun)();
	static StateFun m_stateFun[GS_MaxNum][StateFun_Num];
	virtual bool RouteCallStateFun(int state,StateFunType fun);
	virtual bool TryChangeState(GladiatorCharacterState state);
	bool PostChangeState(GladiatorCharacterState state);
	bool   m_stateSwitch[GS_MaxNum];
	>>

	virtual void  SetOppositeMan(GladiatorCharacter* oppositeMan);
	void  SetTeam(GladiatorTeam* team);
	GladiatorTeam* GetTeam() const;
	GladiatorTeam* GetAwayTeam() const;

	void  CollideOtherMan(GladiatorCharacter* man);

	//int  GetStat(StatType stat) const { return m_stat[stat]; }
	//void SetStat(StatType stat,int val) { m_stat[stat] = val; }

	//职业
	GladiatOccupationType GetOccupation() const;
	void SetOccupation(GladiatorGame::GladiatOccupationType val);
	void OnChangeHP(int change,int current);
	int  ChangeHP(float hp);
	//void AddRecord(RecordType type,int value);

	int  EquipWeapon(int entityID);
	int  UnEquipWeapon(int entityID);


	//!着陆
	virtual bool      GetHeightAt     (vec3& pos,float top=500,float bot=500) const;

//protected:
	GladiatPoseType  m_poseType;
	GladiatRoadType  m_roadType;
	ShowAnim         m_showAnim;

	int              m_changeOppsiteState;
//protected:
	GladiatorSuperSkillStyle* m_superSkillStyle;

	bool  m_hitSuccess ;
	bool  m_superSkillSuccess;

	//能量
	float  m_defendEnergy;
	float  m_forwardEnergy;

	GladiatOccupationType  m_occupation;
	GladiatorTeam*  m_myTeam;
	GladiatorTeam*  m_awayTeam;
	GladiatorCharacter*      m_oppositeMan;

	GladiatorItem*  m_item;
//	int             m_record[RecordNum];
//	int             m_stat[StatNum];

	//方位
	float m_distToTeamLeader;
//	float m_distToBallLevel;
	float m_distToOppMan;
//	int m_dirToAwayRim;
//	int m_dirToOppMan;

	int   m_maxHP;
	float m_hp;
	int   m_maxMP;
	float m_mp;
	int   m_ap;
	int   m_dp;

	float m_baseHpRecover;
	float m_baseMpRecover;
	//无敌
	bool  m_noHurt;

	//冲刺特效
	class Ghost
	{
	public:
		Ghost():m_life(0){}
		vec3 m_pos;
		float m_life;
	};
#define MaxGhost 8
	Ghost m_ghosts[MaxGhost];
	int   m_lastGhost;

	//
	MovieClip* m_modelFightLight;
	MovieClip* m_modelFightBlood;
	MovieClip* m_modelDefend;

	//super skill 一次性加载不释放 ?必杀技太多?以提高速度
	MovieClip* m_modelSuperSkill;

	//僵直时间:攻击命中,防御成功,攻击互抵时候双方角色瞬间动作静止的时间。增强打击感。不在动作文件里定死,因为不命中时不停顿。要即时动态调节。
	float  m_haltTime;
	float  m_animSpeed;
	bool   m_walkRight;

	//是否播放必杀技的屏幕特效
	char   m_superScreenEffect;


	//调试
	String debugStr;
	float  debugStrTime;
	Color  debugStrColor;
};


#endif

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/Gladiator/Gladiator.cpp
//  @Brief:     Gladiator
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 
#include "General/Pch.h"
#include "General/File.h"
#include "AI/Navigation/SteeringSystem.h"
#include "General/Timer.h"
#include "General/StringUtil.h"
#include "Gladiator/GladiatorCharacter.h"
#include "Gladiator/GladiatorItem.h"
#include "Gladiator/MiniGameGladiator.h"
#include "Gladiator/GladiatorRobot.h"
#include "Render/MC_Misc.h"
#include "Render/Font.h"
#include "Render/RendDriver.h"
#include "Rpg/RpgGame.h"
#include "Rpg/Weapon.h"
#include "Sound/ChannelSound.h"
#include "General/Pce.h"
#include "Rpg/GameUtil.h"

namespace GladiatorGame
{
	const char* GladiatorCharacterStateToString(int enumeration)
	{
		const char* stateName[] =
		{
			"None",            // 
			"Stand",           //站立
			"Jump",            //跳
			"Walk",            //移动
			"Forward",         //快速闪进突破
			"Defend",          //防守
			"LightPunch",      //
			"HeavyPunch",      //
			"LightKick",       //
			"HeavyKick",       //
			"BeBeaten",        //被击打
			"SuperSkill",      //必杀技
			"BeSuperSkill",    //被必杀
			"Catch",           //擒拿
			"BeCatch",         //被擒拿
			"EscapeCatch",     //摆脱擒拿
			"BeEscapeCatch",   //被摆脱擒拿
			"Show",            //秀
			"Dead",            //

			"Screen",          //掩护

			"ShootAfter",      //破招

			"Victory",         //
			"Lose",            //
			
			"GS_MaxNum",
		};
		if (enumeration<=GS_MaxNum && enumeration>=0)
		{
			return stateName[enumeration];
		}
		return "error state";
	}


	const char* KeyEventToString(int enumeration)
	{
		const char* enumName[K_NUM] =
		{
			"K_UP",//0,
			"K_DOWN",//1,
			"K_LEFT",//2,
			"K_RIGHT",//3,
			"K_SQUAT",//4,
			"K_JUMP",//5,
			"K_PUNCHA",//6,
			"K_PUNCHB",//7,
			"K_KICKA",//8,
			"K_KICKB",//9,
			"K_ENERGY",//10,
			"K_DEFEND",//11,
			"K_RAPID",
		};
		if (enumeration<=K_NUM && enumeration>=0)
		{
			return enumName[enumeration];
		}
		return "error enum";
	}


	const char* GladiatRoadToString(int enumeration)
	{
		const char* enumName[Road_Num] =
		{
			"Up",//-1,
			"Middle",//0,
			"Down",//1,
		};
		if (enumeration<=Road_Num && enumeration>=0)
		{
			return enumName[enumeration];
		}
		return "error enum";
	}

	const char* GladiatPoseToString(int enumeration)
	{
		const char* enumName[GladiatPoseNum] =
		{
			"Standing",//-1,
			"Squatting",//0,
			"Jumpping",//1,
		};
		if (enumeration<=GladiatPoseNum && enumeration>=0)
		{
			return enumName[enumeration];
		}
		return "error enum";
	}

	const char* ShowAnimToString(int enumeration)
	{
		const char* enumName[SA_Num] =
		{
			"Celebrate",//-1,
			"Annoyed",//0,
			"Defiant",//1,
			"PassReq",//1,
		};
		if (enumeration<=SA_Num && enumeration>=0)
		{
			return enumName[enumeration];
		}
		return "error enum";
	}
};


#define InWaterDis 1
#define UndeadTime 2


CheckStyleEnum(GladiatorSuperSkillStyle)
bool GladiatorSuperSkillStyle::Load(File& file)
{
	ID = file.ReadInt();
	name = file.ReadString();
	m_animCasterName = file.ReadString();
	m_animTargetName = file.ReadString();
	m_soundName = file.ReadString();

	const char* streamEditName[S_NUM]=
	{
		"0",  //S_NULL   = 0,
		"↑",  //S_UP     = 1,
		"↓",  //S_DOWN   = 2,
		"error",
		"←",  //S_LEFT   = 4,
		"↖",  //S_UPL    = 5,
		"↙",  //S_DOWNL  = 6,
		"error",
		"→",  //S_RIGHT  = 8,
		"↗",  //S_UPR    = 9,
		"↘",  //S_DOWNR  = 10,
		"U",  //S_PUNCHA = 11,
		"J",  //S_PUNCHB = 12,
		"I",  //S_KICKA  = 13,
		"K",  //S_KICKB  = 14,
	};		 
	char buf[64];
	file.ReadString(buf,64);
	
	std::string stream[MaxKeyStreamSize+10];
	int size = SplitStringByOne(buf, ",",stream,64);
	
	for (int j=0;j<MaxKeyStreamSize;j++)
	{
		m_inputStream[j] = S_NULL;
		if (j<size)
		{
			for (int i=0;i<S_NUM;i++)
			{
				if (strstr(stream[j].c_str(),M2U(streamEditName[i]).c_str()))
				{
					m_inputStream[j] = (KeyStream)i;
					break;
				}
			}
		}
	}

	m_attackDis = file.ReadFloat();
	m_attackAng = file.ReadFloat();

	m_defendDis = file.ReadFloat();
	m_defendAng = file.ReadFloat();
	return true;
}

bool GladiatorSuperSkillStyle::Save(File& file)
{
	//attackDis30,  attackAng60,  defendDis30,  defendAng60, 
	return true;
}

CheckStyleEnum(GladiatorCharacterStyle)

bool GladiatorCharacterStyle::Load( File& file )
{
	name = file.ReadString();
	ID = file.ReadInt();

	file.ReadString(modelName,128);
	file.ReadString(boneStyle,128);
	UnifyPath(modelName);

	file >> m_hpPoint;
	file >> m_attackSpeed;
	file >> m_attackPoint;
	file >> m_defendPoint;

	file >> radius >> scale;
	file >> maxSpeed >> maxTurnSpeed >> alarmDistance;

#ifdef _DEBUG
	//maxSpeed *= 10;
#endif
	return true;
}

bool GladiatorCharacterStyle::Save( File& file )
{
	int space = 6;
	file.WriteString(name.c_str(),name.length(),20);
	file.WriteString(description.c_str(),description.length(),20);
	file.Fprintf("id");
	file.WriteInt(ID,space);

	file.WriteString(modelName);
	file.WriteString(boneStyle);
	file.Fprintf("\n");

	file.Fprintf("hpPoint");
	file.WriteFloat(m_hpPoint,space);
	file.Fprintf("atSpeed");
	file.WriteFloat(m_attackSpeed,space);
	file.Fprintf("atPoint");
	file.WriteFloat(m_attackPoint,space);
	file.Fprintf("defPoint");
	file.WriteFloat(m_defendPoint,space);
	file.Fprintf("\n");

	file.Fprintf("rad");
	file.WriteInt(radius,space);
	file.Fprintf("scale");
	file.WriteInt(scale,space);
	file.Fprintf("speed");
	file.WriteInt(maxSpeed,space);
	file.Fprintf("turn");
	file.WriteInt(maxTurnSpeed,space);
	file.Fprintf("attackDis");
	file.WriteInt(attackDistance,space);

	return true;
	return true;
}



GladiatorCharacterBanner::GladiatorCharacterBanner()
{
	m_bubbleColor.r = 1;
	m_bubbleColor.g = 0.2f;
	m_bubbleColor.b = 0;
	m_bubbleColor.a = 1;
}
void GladiatorCharacterBanner::Init()
{
	//Monster* monster = dynamic_cast<Monster*> (m_owner);
	if (m_owner)
	{
		char buf[128];
		const char* str = m_owner->GetStyle()->name.c_str();
		sprintf_s(buf,"%s-lv%d",str,18);
		GenNameFastWords(buf,Color(1.0f,1.0f,1.0f,1.0f));
	}

	Banner::Init();

	GladiatorCharacter* role = dynamic_cast<GladiatorCharacter*> (m_owner);
	if (role)
	{
		if (role->GetTeam()&&role->GetTeam()->GetType()==TeamRed)
		{
			switch(role->GetOccupation())
			{
			case OT_Forward:
				G_TextureMgr->AddTexture(m_textureOccupation,"data/gui/minigame/gladiator/pos_f_red.png");
				break;
			case OT_Center:
				G_TextureMgr->AddTexture(m_textureOccupation,"data/gui/minigame/gladiator/pos_c_red.png");
				break;
			case OT_Guard:
				G_TextureMgr->AddTexture(m_textureOccupation,"data/gui/minigame/gladiator/pos_g_red.png");
				break;
			default:
				G_TextureMgr->AddTexture(m_textureOccupation,"data/gui/minigame/gladiator/pos_f_red.png");
				break;
			}
		}
		else
		{
			switch(role->GetOccupation())
			{
			case OT_Forward:
				G_TextureMgr->AddTexture(m_textureOccupation,"data/gui/minigame/gladiator/pos_f_blue.png");
				break;
			case OT_Center:
				G_TextureMgr->AddTexture(m_textureOccupation,"data/gui/minigame/gladiator/pos_c_blue.png");
				break;
			case OT_Guard:
				G_TextureMgr->AddTexture(m_textureOccupation,"data/gui/minigame/gladiator/pos_g_blue.png");
				break;
			default:
				G_TextureMgr->AddTexture(m_textureOccupation,"data/gui/minigame/gladiator/pos_f_blue.png");
				break;
			} 
		}
	}
	//
	m_texBack = NULL;
}

void GladiatorCharacterBanner::Render()
{
	GladiatorCharacter* role = dynamic_cast<GladiatorCharacter*> (m_owner);

	//
	if (m_texBack==NULL && role && role->GetTeam())
	{
		if (role->GetTeam()->GetType()==TeamRed)
		{
			G_TextureMgr->AddTexture(m_texBack,"data/minigame/ShapeAttack/banner_red.png");
		}
		else
		{
			G_TextureMgr->AddTexture(m_texBack,"data/minigame/ShapeAttack/banner_blue.png");
		}
	}


	G_RendDriver->SetRenderStateEnable(RS_DEPTH_TEST,false);
	G_RendDriver->SetRenderStateEnable(RS_TEXTURE_2D,true);
	G_RendDriver->Color4f(1.0f, 1.0f, 1.0f,1); 

	//绘制back
	if(m_texBack)
	{
		m_texBack->Bind();
		DrawTextureRect(RectF(-5.0f,-2,10,3));
	}

	//3d y正向上
	if (m_texBloodRed && m_texBloodGreen)
	{
		float y = -1.8f;
		//绘制血条 红
		m_texBloodRed->Bind();
		DrawTextureRect(RectF(-4.9f,y,9.8f,0.75f));

		//绘制血条 绿
		m_texBloodGreen->Bind();
		DrawTextureRect(RectF(-4.85f,y,9.7f*m_hpPersent,0.75f));
	}

	//绘制职业
	if(m_textureOccupation)
	{
		float y = -1.2f;
		m_textureOccupation->Bind();
		DrawTextureRect(RectF(-4.9f,y,2,2));
	}

	//绘制名字
	if (m_fastWordsName
		&&m_fastWordsName->m_texture)
	{
		G_FontMgr->SetColor(Color(1,1,1,1));
		m_fastWordsName->m_texture->Bind();
		float width = m_fastWordsName->m_rect.width/16.0f*1.6f;
		DrawTextureRect(RectF(-2.5f,0.7f,width,-1.6f));
	}

	//	//调试
	//sprintf_s(buf,"%s",GladiatorStateToString(role->GetState()));
	//sprintf_s(buf,"%s",role->GetRenderCharacter()->GetCurAnimName());
	//if (!role->debugStr.empty())
	//{
	//	height += 15.0f;
	//	G_RendDriver->Color3f(role->debugStrColor.r, role->debugStrColor.g, role->debugStrColor.b); 
	//	G_FontMgr->GetFontDesc().fontSize = 10;
	//	G_FontMgr->Text3DAtPos(vec3(-2.0f,height,0),role->debugStr.c_str());
	//	G_FontMgr->GetFontDesc().fontSize = 16;
	//}

	G_RendDriver->SetRenderStateEnable(RS_DEPTH_TEST,true);

	return;

}

static bool G_ChangeStandOnAnimEnd[GS_MaxNum];

GladiatorCharacter::StateFun GladiatorCharacter::m_stateFun[GS_MaxNum][StateFun_Num]={};

GladiatorCharacter::GladiatorCharacter()
:m_poseType(Standing)
,m_modelFightLight(NULL)
,m_modelFightBlood(NULL)
,m_modelDefend(NULL)
,m_hitSuccess(false)
,m_occupation(OT_Forward)
,m_hp(100)
,m_maxHP(100)
,m_mp(0)
,m_maxMP(100)
,m_lastGhost(0)
,m_oppositeMan(NULL)
,m_myTeam(NULL)
,m_awayTeam(NULL)
,m_haltTime(0)
,m_showAnim(SA_Celebrate)
,m_walkRight(false)
,m_item(NULL)
,m_changeOppsiteState(-1)
,m_superScreenEffect(1)
{

	for (int i=0;i<GS_MaxNum;i++)
	{
		G_ChangeStandOnAnimEnd[i] = false;
	}

	G_ChangeStandOnAnimEnd[GS_LightPunch] = true;
	G_ChangeStandOnAnimEnd[GS_HeavyPunch] = true;
	G_ChangeStandOnAnimEnd[GS_LightKick] = true;
	G_ChangeStandOnAnimEnd[GS_HeavyKick] = true;
	G_ChangeStandOnAnimEnd[GS_BeBeaten] = true;
	G_ChangeStandOnAnimEnd[GS_SuperSkill] = true;
	G_ChangeStandOnAnimEnd[GS_BeSuperSkill] = true;
	G_ChangeStandOnAnimEnd[GS_Show] = true;
	G_ChangeStandOnAnimEnd[GS_Dead] = true;

	RegisterAllStateFun(GladiatorCharacter);
	//RegisterStateFun(None            );  
	//RegisterStateFun(Stand           );  
	//RegisterStateFun(Jump            );  
	//RegisterStateFun(Walk            );
	//RegisterStateFun(Forward         );
	//RegisterStateFun(LightPunch      );  
	//RegisterStateFun(HeavyPunch      );      
	//RegisterStateFun(LightKick      );       
	//RegisterStateFun(HeavyKick      ); 
	//RegisterStateFun(Defend      );    
	//RegisterStateFun(SuperSkill     );   
	//RegisterStateFun(BeSuperSkill     ); 
	//RegisterStateFun(BeBeaten       );    
	//RegisterStateFun(Catch      );  
	//RegisterStateFun(BeCatch      );   
	//RegisterStateFun(Dead      ); 

	m_curState = GS_None;
	m_stateAccumTime = 0;

	//预测提前量 因为目标转向太快 跟随者可能会振动
	m_steering->SetLookAheadWeight(0);
}

GladiatorCharacter::~GladiatorCharacter()
{
	Free();
}

bool GladiatorCharacter::SetStyle( Style* style )
{
	LogicCharacter::SetStyle(style);
	m_steering->SteeringOff(SteeringSystem::Separation);
	m_brakingRate = 0.5f;

	//todo 不更新顶点来提速
	GetRenderCharacter()->SetFrustumSkipEnable(false);

	m_curState = GS_Stand;
	m_postState = -1;

	//状态开关
	for (int i=0;i<GS_MaxNum;i++)
	{
		m_stateSwitch[i] = 1;
	}

	if (m_modelFightLight==NULL)
	{
		LoadConfig loader(LoadConfig::GenDonotReShrinkBound,true,true);
		m_modelFightLight = new RendSys::MovieClip;
		m_modelFightLight->LoadFromFile("data/effect/gladiatorEffect/gladiatorLight.movie",&loader);
		m_modelFightLight->Advance();
		m_modelFightLight->SetVisible(false,Recursive);
	}
	if (m_modelFightBlood==NULL)
	{
		LoadConfig loader(LoadConfig::GenDonotReShrinkBound,true,true);
		m_modelFightBlood = new RendSys::MovieClip;
		m_modelFightBlood->LoadFromFile("data/effect/gladiatorEffect/gladiatorBlood.movie",&loader);
		m_modelFightBlood->Advance();
		m_modelFightBlood->SetVisible(false,Recursive);
	}
	if (m_modelDefend==NULL)
	{
		LoadConfig loader(LoadConfig::GenDonotReShrinkBound,true,true);
		m_modelDefend = new RendSys::MovieClip;
		m_modelDefend->LoadFromFile("data/effect/gladiatorEffect/gladiatorDefend.movie",&loader);
		m_modelDefend->Advance();
		m_modelDefend->SetVisible(false,Recursive);
	}
	if (m_item ==NULL)
	{
		m_item = new GladiatorItem;
		m_item->SetNowController(this);
		m_item->Init();
	}
	m_hitSuccess = false;


	if(!GetRenderCharacter()->GetBanner(Slot_FootBanner))
	{
		GladiatorCharacterBanner* banner = new GladiatorCharacterBanner;
		banner->SetOwner(this);
		banner->Init();
		GetRenderCharacter()->MountBanner(Slot_FootBanner,banner);
	}

	Banner* banner = GetRenderCharacter()->GetBanner(Slot_HeadBanner);
	if(banner == NULL)
	{
		banner = new Banner();
		GetRenderCharacter()->MountBanner(Slot_HeadBanner,banner);
	}
	banner->m_drawBloodBar = false;
	banner->SetOwner(this);
	banner->Init();
	banner->m_bubbleColor.r = 1;
	banner->m_bubbleColor.g = 0.5f;
	banner->m_bubbleColor.b = 0.3f;
	banner->m_bubbleColor.a = 1;

	//GetHeightAt(m_pos);
	return true;
}

//GladiatorCharacterStyle* GladiatorCharacter::GetStyle()
//{
//	return dynamic_cast<GladiatorCharacterStyle*>(m_entityStyle);
//}

//RoleBanner* GladiatorCharacter::GetBanner( BannerSlot slot )
//{
//
//}

void GladiatorCharacter::Free()
{
	LogicCharacter::Free();
	if(m_modelFightLight)
		m_modelFightLight->FreeMovie();
	SafeDelete(m_modelFightLight);

	if(m_modelFightBlood)
		m_modelFightBlood->FreeMovie();
	SafeDelete(m_modelFightBlood);
	
	if(m_modelDefend)
		m_modelDefend->FreeMovie();
	SafeDelete(m_modelDefend);

	SafeDelete(m_item);
}

void GladiatorCharacter::UpdateCommonPre()
{
	if (m_oppositeMan)
	{
		vec3 dif = m_oppositeMan->GetPos()-m_pos;
		m_distToOppMan = dif.Length();
		if (IsInState(GS_Forward)==false&&m_distToOppMan<50)
		{
			RotHeadingTowardPos(m_oppositeMan->GetPos(),false,true);
		}
		else
		{
			UpdateHeadBySpeed();
		}
	}
	else
	{
		m_distToOppMan = 9999;
		UpdateHeadBySpeed();
	}

	m_distToTeamLeader = (m_pos-m_myTeam->m_teamLeader->GetPos()).Length();

	for (int i=0;i<G_GladiatorGame->GetAllPlayerNum();i++)
	{
		CollideOtherMan(dynamic_cast<GladiatorCharacter*>(G_GladiatorGame->GetPlayerFromIndex(i)));
	}
}
//碰撞处理
void GladiatorCharacter::CollideOtherMan(GladiatorCharacter* man)
{
	if (man == this)
	{
		return;
	}
	//对方也是站立状态 挤退
	vec3 dir = man->GetPos()-m_pos;
	float distance = dir.Length();
	dir.Normalize();
	//if(distance<10)
	//{
	//	vec3 pos;
	//	distance = 10-distance;
	//	//if (man->IsInState(GS_Stand)
	//	//	||man->IsInState(GS_Defend))
	//	{
	//		pos = GetPos()-distance*dir;
	//		if(m_logicMap)
	//			m_logicMap->GetHeightUpWater(pos,20,3000);
	//		SetPos(pos);
	//	}
	//	m_distToOppMan = 10;
	//}

	//不穿透更好
	//if (IsInState(GS_Forward)||man->IsInState(GS_Forward))
	//{
	//	return;
	//}

	if(distance<10)
	{
		vec3 pos;
		distance = 10-distance;
		if (IsInState(GS_Stand) || man->IsInState(GS_Defend))
		{
			//我方后退
			pos = GetPos()-distance*dir;
			GetHeightAt(pos,20,3000);
			SetPos(pos);
		}
		else if (man->IsInState(GS_Stand) || IsInState(GS_Defend))
		{
			//敌方后退
			pos = man->GetPos()+distance*dir;
			GetHeightAt(pos,20,3000);
			man->SetPos(pos);
			//非此原因引起振动
			//enemy->UpdateToRenderChar();
			//this->RotateFacingTowardPosition(pos);
			//this->UpdateToRenderChar();
		}
		else
		{
			//各退一半
			//pos = GetPos()-distance/2*dir;

			//这个距离一次可能退出不完全 但多次后基本退出完毕
			//dirnew 和speed平行和dir同向
			vec3 dirnew= m_speed*(m_speed.Dot(dir));
			dirnew.Normalize();
			dirnew+= dir*0.8f;//稍微偏向以便绕过 0.8越大越容易绕过
			//dirnew = dir; //不是引起振动的原因,但是会很快绕过无法发送推挤
			dirnew.Normalize();
			pos = GetPos()-distance/2*dirnew;
			GetHeightAt(pos,20,3000);
			this->SetPos(pos);


			//pos = enemy->GetPos()+distance/2*dir;
			dirnew= man->m_speed*(man->m_speed.Dot(dir));
			dirnew.Normalize();
			dirnew+= dir*0.8f;
			//dirnew = dir;
			dirnew.Normalize();
			pos = man->GetPos()+distance/2*dirnew;
			GetHeightAt(pos,20,3000);
			man->SetPos(pos);
		}
	}
}

void GladiatorCharacter::Update()
{
	//if(m_postState>0)
	//{
	//	TryChangeState((GladiatorCharacterState)m_postState);
	//	m_postState = -1;
	//}
	UpdateCommonPre();

	//放在UpdateCommonPre后面,有可能动画回调要用上面更新的一些数据
	//放在StateFun_Update前面,后面要用最新的位置
	LogicCharacter::Update();

	if(GS_None<m_curState&&m_curState<GS_MaxNum)
	{
		RouteCallStateFun(m_curState,StateFun_Update);
		m_stateAccumTime += G_Timer->GetStepTime();
	}

	UpdateCommonAfter();

}
void GladiatorCharacter::UpdateCommonAfter()
{
	
	m_mp+=G_Timer->GetStepTimeLimited()*1.0f;
	if (m_mp>m_maxMP)
	{
		m_mp = m_maxMP;
	}

	GladiatorCharacterBanner* banner = dynamic_cast<GladiatorCharacterBanner*>(GetBanner(Slot_FootBanner));
	if(banner) 
		banner->SetHp(m_hp,(float)m_hp/m_maxHP);
	Banner* banner2 = dynamic_cast<Banner*>(GetBanner(Slot_HeadBanner));
	if(banner2) 
		banner2->SetHp(m_hp,(float)m_hp/m_maxHP);

	m_item->Update();

	if (m_modelFightLight&&m_hitSuccess)
	{
		bool lastVisible = m_modelFightLight->IsVisible();
		bool visible = false;
		Frame* frame = m_modelFightLight->GetProgramFrame();
		//frame->m_rot.y = m_direction;
		if (IsInState(GS_LightPunch))
		{
			m_renderCharacter->GetBoneMatrix("Bip01 L Hand",&frame->m_pos);
			visible = true;
		}
		else if (IsInState(GS_HeavyPunch))
		{
			m_renderCharacter->GetBoneMatrix("Bip01 R Hand",&frame->m_pos);
			visible = true;
		}
		else if (IsInState(GS_LightKick))
		{
			m_renderCharacter->GetBoneMatrix("Bip01 L Foot",&frame->m_pos);
			visible = true;
		}
		else if (IsInState(GS_HeavyKick))
		{
			m_renderCharacter->GetBoneMatrix("Bip01 R Foot",&frame->m_pos);
			visible = true;
		}

		m_modelFightLight->SetVisible(visible,Recursive);
		if (visible==true)
		{
			if (lastVisible==false)
			{
				m_modelFightLight->GotoAndPlay(0,Recursive);
			}

			//frame->m_scale = m_scale;
			frame->CalQuatMatrix();
			m_modelFightLight->SetProgramFrame(frame);
			m_modelFightLight->Advance();
		}
	}

	if(m_modelFightBlood->IsVisible())
	{
		//	m_modelFightBlood->SetVisible(true,Recursive);
		Frame* frame = m_modelFightBlood->GetProgramFrame();
		//frame->m_rot.y = m_direction;
		m_renderCharacter->GetBoneMatrix("Bip01 Head",&frame->m_pos);
		frame->CalQuatMatrix();
		m_modelFightBlood->SetProgramFrame(frame);
		m_modelFightBlood->Advance();
	}

	//只是jump状态更新是不够的,因为可能没落地就转成了攻击态,?jump状态应该分立?
	if (m_bJumping == false && m_poseType==Jumpping)
	{
		m_poseType = Standing;
	}

	if (m_haltTime>0)
	{
		m_haltTime -= G_Timer->GetStepTimeLimited();
		if (m_haltTime<0)
		{
			m_renderCharacter->SetAnimSpeed(m_animSpeed);
		}
		else
		{
			m_renderCharacter->SetAnimSpeed(0);
		}
	}
	//LogicCharacter::Update(); 在前面调用,但位置,面向可能已经改变了
	UpdateToRenderChar();

}


bool GladiatorCharacter::RouteCallStateFun(int state,StateFunType fun)
{
	//stateFun 不能为virtual 否则调用的是派生方法
	if(m_stateFun[state][fun])
	{
		return (this->*m_stateFun[state][fun])();
	}
	else
	{
		if (fun==StateFun_Check)
		{
			return true;
		}
	}
	return false;
}


void GladiatorCharacter::Render()
{
	if (IsInState(GS_Forward))
	{
		for (int i=0;i<MaxGhost;i++)
		{
			if (m_ghosts[i].m_life>0)
			{
				//if ((Rand()%50<m_ghosts[i].m_life*100))
				{
					m_renderCharacter->SetPos(m_ghosts[i].m_pos);
					//m_renderCharacter->SetDirection(RAD2DEG*atan2f(m_heading.x,m_heading.z));
					//??time
					m_renderCharacter->Update();
					//m_renderCharacter->m_mainModel->setop()
					//G_RendDriver->Color4f(1,1,1,m_ghosts[i].m_life/0.5f);
					m_renderCharacter->Render();
				}
			}
		}
	}

	//G_RendDriver->Color4f(1,1,1,1);
	m_renderCharacter->SetPos(m_pos);
	m_renderCharacter->SetDirection(RAD2DEG*atan2f(m_heading.x,m_heading.z));
	m_renderCharacter->Update();

	LogicCharacter::Render();
	m_modelFightLight->RendClip();
	m_modelFightBlood->RendClip();
	m_modelDefend->RendClip();

	m_item->Render();
}

void GladiatorCharacter::OnAnimCallBack( const char* frameName )
{
	LogicCharacter::OnAnimCallBack(frameName);

	if (stricmp(frameName,"ShootOut") == 0)
	{
		//m_state = MS_Move;
		//m_stateType = N_RUN_DEFENCE_BACK_1;
		//子弹脱手
	}
	else if (stricmp(frameName,"SnSiu") == 0)
	{
		//舞棍嗖嗖声
		m_sound->PlaySound__("data/sound/Basket/Block_01.mp3");
	}
	else if (stricmp(frameName,"SnBlock") == 0)
	{
		//被推挤
		m_sound->PlaySound__("data/sound/Basket/Block_01.mp3");
	}

	else if (stricmp(frameName,"SnCatch") == 0)
	{
		//被catch者切换状态
		m_sound->PlaySound__("data/sound/Basket/Catch_01.mp3");
	}

	else if (stricmp(frameName,"SnSkid") == 0)
	{
		//滑到
		m_sound->PlaySound__("data/sound/Basket/Skid_01.mp3");
	}
	//else if (stricmp(frameName,"SnLanding") == 0)
	//{
	//	//move to jump exit
	//	m_sound->PlaySound__("data/sound/gladiator/Landing01.mp3");
	//}
	//else if (stricmp(frameName,"SnJump") == 0)
	//{
	//	//move to jump enter
	//	m_sound->PlaySound__("data/sound/gladiator/jump01.wav");
	//}
	else if (stricmp(frameName,"SnPass") == 0)
	{
		m_sound->PlaySound__("data/sound/Basket/pass_01.mp3");
	}
	else if (stricmp(frameName,"SnYell") == 0)
	{
		//m_sound->PlaySound__("data/sound/gladiator/yell.mp3");
	}
	else if (stricmp(frameName,"SnFellGround") == 0)
	{
		//击飞后着地
		m_sound->PlaySound__("data/sound/gladiator/fellground_01.mp3");
		//地上加一滩血或坑
	}
	//else if (stricmp(frameName,"EfLightStart") == 0)
	//{
	//}
	//else if (stricmp(frameName,"EfLightEnd") == 0)
	//{
	//}
	//else if (stricmp(frameName,"EfBloodStart") == 0)
	//{
	//}
	//else if (stricmp(frameName,"EfBloodEnd") == 0)
	//{
	//}
	else if (stricmp(frameName,"AcHit") == 0)
	{
		//判断轻击重击 是否击中播放不同的声音
		//击中播放光效
		//被击中这切换bettean状态
		if (IsInState(GS_LightPunch)
			||IsInState(GS_HeavyPunch)
			||IsInState(GS_LightKick)
			||IsInState(GS_HeavyKick))
		{

			//联机:触发此回调的有可能是other,如果other的对手是role或robot才执行攻击判断。 other打other不处理状态转换,而是等待其它客户端同步过来。
			//      触发此回调的有可能是role,role的对手不可能是role,可能是robot才执行攻击判断。 role打other不处理状态转换,而是等待其它客户端同步过来。
			//      触发此回调的有可能是robot,robot的对手是role或robot才执行攻击判断。 
			//单机:的因为没有other,所以攻击判断肯定会处理。
			if (m_oppositeMan
				&& dynamic_cast<GladiatorRobot*>(m_oppositeMan))
			{
				m_oppositeMan->SetOppositeMan(this); //被打的人目标可能不匹配
				m_hitSuccess = m_oppositeMan->TryChangeState(GS_BeBeaten);
				//如果对手被逼到边界则自己后退
				//MoveFrontLocal(-MoveSpeed);

				if(m_item->GetState()==GI_Catched)
				{
					m_item->StartShoot(m_oppositeMan);
				}
			}
		}
	}
	else if (stricmp(frameName,"AcContinueHit") == 0)
	{
	}
	else if (stricmp(frameName,"AnimEnd") == 0 || stricmp(frameName,"end") == 0)
	{
		if (IsInState(GS_Dead))
		{
			m_hp = m_maxHP;
		}

		if (G_ChangeStandOnAnimEnd[m_curState])
		{
			//动作结束  还跳在空中的情况很少见,统一返回站立态?
			if (m_bJumping==true)
			{
				TryChangeState(GS_Jump);
			}
			else
			{
				TryChangeState(GS_Stand);
			}	
		}
	}
}

void GladiatorCharacter::UpdateMovement()
{
	if (m_haltTime>0)
		return;
	
	UpdateSpeedPos();
	//转向
	//UpdateHeadBySpeed();
	UpdateLanding();
	
}

bool GladiatorCharacter::GetAttackorPosOnFrame(const char*frame,vec3& out,bool localCoord)
{
	vec3 ballPos;
	return m_renderCharacter->GetBoneMatrix("attackor",&ballPos,NULL,frame);
}

void GladiatorCharacter::SetPosByFoot(const char*frame)
{
	//float needtime = m_renderCharacter->GetFrameTime(frame);
	//vec3 predictBallPos;
	//G_BasketBall->PredictPosAfterTime(needtime,predictBallPos);
	//vec3 ballPos;
	//GetBallPosOnFrame(frame,ballPos,false);
	//SetPos(m_pos + predictBallPos - ballPos);
}

bool GladiatorCharacter::TryChangeState(GladiatorCharacterState state)
{
	if (m_curState==state)
	{
		return false;
	}
	if(GS_None>=state||state>=GS_MaxNum)
	{
		return false;
	}
	//开关
	if(m_stateSwitch[state] == false)
	{
		return false;
	}
	//条件
	if(RouteCallStateFun(state,StateFun_Check)==false)
	{
		return false;
	}
	//
	m_lastState = m_curState;
	m_lastStateType = m_curStateType;

	RouteCallStateFun(m_curState,StateFun_Exit);

	m_stateAccumTime = 0;
	m_curState = state;
	m_hitSuccess = false;
	//力度清零
	ClearMoveForce();
	//速度不清零 可以继续减速滑步 除了必杀状态速度要清零

	m_modelFightLight->SetVisible(false,Recursive);
	m_modelFightBlood->SetVisible(false,Recursive);

	RouteCallStateFun(m_curState,StateFun_Enter);
	if (m_changeOppsiteState>0)
	{
		//保证oppsite的state_enter在this_enter之后,又不能延迟一帧,导致节外生枝
		if (m_oppositeMan)
		{
			bool res = m_oppositeMan->TryChangeState((GladiatorCharacterState)m_changeOppsiteState);
			Assert(res==true,"opposite man not be state!");
		}
		m_changeOppsiteState = -1;
	}
	if (IsInState(GS_BeBeaten)==false)
	{
		m_animSpeed = 18;
		m_renderCharacter->SetAnimSpeed(m_animSpeed);
	}
	else
	{
		//m_renderCharacter->SetAnimSpeed(m_animSpeed);
	}
	
	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_NoneStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_NoneStateEnter()
{
	return true;
}
bool GladiatorCharacter::GS_NoneStateExit()
{
	return true;
}
bool GladiatorCharacter::GS_NoneStateUpdate()
{
	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_StandStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_StandStateEnter()
{
	if (m_poseType==Standing)
	{
		m_renderCharacter->PlayAnim("standing_standby01");
	}
	else
	{
		m_renderCharacter->PlayAnim("squatting_Standby01");
	}
	ClearMoveForce();
	//? 继续滑步没意义 不是慢停
	m_speed = vec3(0,0,0);
	return true;
}
bool GladiatorCharacter::GS_StandStateExit()
{
	return true;
}
bool GladiatorCharacter::GS_StandStateUpdate()
{
	if (m_hp<=0)
	{
		TryChangeState(GS_Dead);
	}
	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_WalkStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_WalkStateEnter()
{
	if (m_poseType==Squatting)
	{
		m_renderCharacter->PlayAnim("squatting_Walk01");
	}
	else 
	{
		m_renderCharacter->PlayAnim("standing_Walk01");
	}
	
	m_sound->PlaySound__("data/sound/event_run.wav",true);
	return true;
}
bool GladiatorCharacter::GS_WalkStateExit()
{
	m_sound->StopSound();
	return true;
}
bool GladiatorCharacter::GS_WalkStateUpdate()
{
	//派生类中切换了打击必杀等 但还调用到这里?
	if (IsInState(GS_Walk)==false)
	{
		return false;
	}

	//24 帧 两步 40米
	m_animSpeed = m_speed.Length()*0.5f; //*24/40
	if (m_animSpeed<5) //停步时播放速度稍慢而不是无限慢,脚步到位就停
	{
		m_animSpeed = 5;
	}
	else if (m_animSpeed>25)
	{
		m_animSpeed = 25;
	}

	vec3 normalSpeed = m_speed;
	normalSpeed.Normalize();

	if (m_walkRight==false)
	{
		//前后走
		if(m_speed.Dot(m_heading)>0)
		{
			//前进
			//m_renderCharacter->SetAnimSpeed(18);
			m_renderCharacter->SetAnimSpeed(m_animSpeed);
		}
		else
		{
			//后退 倒播
			//m_renderCharacter->SetAnimSpeed(-18);
			m_renderCharacter->SetAnimSpeed(-m_animSpeed);
		}

		//只做了站立态右行动作
		if (m_poseType == Standing)
		{
			if (fabs(normalSpeed.Dot(m_heading))<cos(DEG2RAD*50))
			{
				m_walkRight = true;
				if (m_poseType == Squatting)
				{
					//m_renderCharacter->PlayAnim("squatting_Walk01");
				}
				else
				{
					m_renderCharacter->PlayAnim("standing_WalkRight01");
				}
			}
		}

	}
	else
	{
		//左右走
		if(m_speed.Dot(m_headingRight)>0)
		{
			//右进
			//m_renderCharacter->SetAnimSpeed(18);
			m_renderCharacter->SetAnimSpeed(m_animSpeed);
		}
		else
		{
			//左退 倒播
			//m_renderCharacter->SetAnimSpeed(-18);
			m_renderCharacter->SetAnimSpeed(-m_animSpeed);
		}
		if (fabs(normalSpeed.Dot(m_headingRight))<cos(DEG2RAD*50))
		{
			m_walkRight = false;
			if (m_poseType == Squatting)
			{
				m_renderCharacter->PlayAnim("squatting_Walk01");
			}
			else
			{
				m_renderCharacter->PlayAnim("standing_Walk01");
			}
		}
	}

	//if(IsInState(GS_Walk))
	{
		//选择距离较近的做对手
		for (int i=0;i<m_awayTeam->m_manNum;i++)
		{
			GladiatorCharacter* enemy = m_awayTeam->m_mans[i];
			if (enemy!=m_oppositeMan)
			{
				float dis1 = (m_pos - enemy->GetPos()).Length();
				if (enemy->IsInState(GS_SuperSkill)==false
					&&enemy->IsInState(GS_BeSuperSkill)==false
					//&&enemy->IsInState(GS_Catch)==false
					&&enemy->IsInState(GS_BeCatch)==false
					&&enemy->IsInState(GS_Dead)==false
					&&dis1<m_distToOppMan*0.7f)
				{
					SetOppositeMan(enemy);
				}
			}
		}
		//如果不是队长 还不能离队长太远
	}
	return true;
}


//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_ForwardStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_ForwardStateEnter()
{
	SetMaxSpeed(GetStyle()->maxSpeed*3);

	//todo 根据方位判断是前进还是撤退
	char buf[256];
	if (m_poseType==Squatting)
	{
		sprintf(buf,"squatting_Forward%02d",Rand()%2+1);
		m_renderCharacter->PlayAnim(buf);
	}
	else
	{
		sprintf(buf,"standing_Forward%02d",Rand()%2+1);
		m_renderCharacter->PlayAnim(buf);
	}
	if (m_lastStateType==GS_BeSuperSkill)
	{
		m_sound->PlaySound__("data/sound/gladiator/escapeSuper.wav");
	}
	else
	{
		m_sound->PlaySound__("data/sound/gladiator/forward.wav");
	}
	return true;
}
bool GladiatorCharacter::GS_ForwardStateExit()
{
	SetMaxSpeed(GetStyle()->maxSpeed);

	for (int i=0;i<MaxGhost;i++)
	{
		m_ghosts[i].m_life = 0;
		m_ghosts[i].m_pos = vec3();
	}
	m_lastGhost = 0;
	return true;
}
bool GladiatorCharacter::GS_ForwardStateUpdate()
{
	for (int i=0;i<MaxGhost;i++)
	{
		if (m_ghosts[i].m_life>0)
		{
			m_ghosts[i].m_life-=G_Timer->GetStepTime();
		}
	}
#define GostLifeMax 0.3f

	if (m_ghosts[m_lastGhost].m_life<0.0f)
	{
		m_ghosts[m_lastGhost].m_life = GostLifeMax;
		m_ghosts[m_lastGhost].m_pos = GetPos();
	}
	else if ((m_pos-m_ghosts[m_lastGhost].m_pos).LengthSq()>16/*100.0f*/)
	{
		m_lastGhost++;
		m_lastGhost%=MaxGhost;
		m_ghosts[m_lastGhost].m_life = GostLifeMax;
		m_ghosts[m_lastGhost].m_pos = GetPos();
	}


	if (m_stateAccumTime>0.5f)
	{
		TryChangeState(GS_Stand);
	}
	return true;
}


//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_JumpStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_JumpStateEnter()
{
	m_renderCharacter->PlayAnim("jumpping_Standby01");
	Jump(100);
	m_sound->PlaySound__("data/sound/gladiator/jump01.wav");
	return true;
}
bool GladiatorCharacter::GS_JumpStateExit()
{
	m_sound->PlaySound__("data/sound/gladiator/Landing01.mp3");
	return true;
}
bool GladiatorCharacter::GS_JumpStateUpdate()
{
	//跳跃中变为攻击态,攻击完变stand,如果这时后还没落地,切换下蹲不能起作用
	if (m_bJumping == false)
	{
		TryChangeState(GS_Stand);
		m_poseType = Standing;
	}
	return true;
}


//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_LightPunchStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_LightPunchStateEnter()
{
	char buf[256];
	//Standing_PunchLeftUp01
	sprintf(buf,"%s_PunchLeft%s%02d",GladiatPoseToString(m_poseType),GladiatRoadToString(m_roadType),1);
	m_renderCharacter->PlayAnim(buf);
	m_sound->PlaySound__("data/sound/gladiator/punchUnHit.wav");
	return true;
}
bool GladiatorCharacter::GS_LightPunchStateExit()
{
	return true;
}
bool GladiatorCharacter::GS_LightPunchStateUpdate()
{
	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_HeavyPunchStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_HeavyPunchStateEnter()
{
	char buf[256];
	//Standing_PunchLeftUp01
	sprintf(buf,"%s_PunchRight%s%02d",GladiatPoseToString(m_poseType),GladiatRoadToString(m_roadType),1);
	m_renderCharacter->PlayAnim(buf);
	m_sound->PlaySound__("data/sound/gladiator/punchUnHit.wav");
	return true;
}
bool GladiatorCharacter::GS_HeavyPunchStateExit()
{
	return true;
}
bool GladiatorCharacter::GS_HeavyPunchStateUpdate()
{
	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_LightKickStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_LightKickStateEnter()
{
	char buf[256];
	//Standing_PunchLeftUp01
	sprintf(buf,"%s_KickLeft%s%02d",GladiatPoseToString(m_poseType),GladiatRoadToString(m_roadType),1);
	m_renderCharacter->PlayAnim(buf);
	m_sound->PlaySound__("data/sound/gladiator/punchUnHit.wav");
	return true;
}
bool GladiatorCharacter::GS_LightKickStateExit()
{
	return true;
}
bool GladiatorCharacter::GS_LightKickStateUpdate()
{
	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_HeavyKickStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_HeavyKickStateEnter()
{
	char buf[256];
	//Standing_PunchLeftUp01
	sprintf(buf,"%s_KickRight%s%02d",GladiatPoseToString(m_poseType),GladiatRoadToString(m_roadType),1);
	m_renderCharacter->PlayAnim(buf);
	m_sound->PlaySound__("data/sound/gladiator/punchUnHit.wav");
	return true;
}
bool GladiatorCharacter::GS_HeavyKickStateExit()
{
	return true;
}
bool GladiatorCharacter::GS_HeavyKickStateUpdate()
{
	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_DefendStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_DefendStateEnter()
{
	char buf[256];
	//Standing_s_DefendUp01
	sprintf(buf,"%s_Defend%s%02d",GladiatPoseToString(m_poseType),GladiatRoadToString(m_roadType),1);
	m_renderCharacter->PlayAnim(buf);

	m_modelDefend->SetVisible(true,Recursive);
	m_modelDefend->GotoAndPlay(0,Recursive);

	//更新一下
	GS_DefendStateUpdate();

	m_sound->PlaySound__("data/sound/gladiator/defend01.wav");
	return true;
}
bool GladiatorCharacter::GS_DefendStateExit()
{
	m_modelDefend->SetVisible(false,Recursive);
	return true;
}
bool GladiatorCharacter::GS_DefendStateUpdate()
{
	//	m_modelDefend->SetVisible(true,Recursive);
	Frame* frame = m_modelDefend->GetProgramFrame();
	frame->m_rot.y = RAD2DEG*atan2f(m_heading.x,m_heading.z);
	frame->m_rot.x = 0;
	vec3 pos = m_pos;
	switch(m_poseType)
	{
	case Squatting:
		switch(m_roadType)
		{
		case Road_Up:
			pos.y += 5;
			frame->m_rot.x = -15;
			break;
		case Road_Middle:
			pos.y += 2;
			break;
		case Road_Down:
			pos.y += 0;
			frame->m_rot.x = 5;
			break;
		}
		break;
	default:
		switch(m_roadType)
		{
		case Road_Up:
			pos.y += 10;
			frame->m_rot.x = -15;
			break;
		case Road_Middle:
			pos.y += 5;
			break;
		case Road_Down:
			pos.y += 0;
			frame->m_rot.x = 5;
			break;
		}
		break;
	}
	
	frame->m_pos = pos;
	frame->CalQuatMatrix();
	m_modelDefend->SetProgramFrame(frame);
	m_modelDefend->Advance();

	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_SuperSkillStateCheck()
{
	if(m_oppositeMan == NULL)
		return false;
	if(m_oppositeMan->IsInState(GS_Defend))
		return false;
	if(m_oppositeMan->IsInState(GS_SuperSkill))
		return false;
	if(m_oppositeMan->IsInState(GS_BeSuperSkill))
		return false;
	if(m_oppositeMan->IsInState(GS_Show))
		return false;
	if(m_oppositeMan->IsInState(GS_Dead))
		return false;

	//距离不满足
	if ((m_pos-m_oppositeMan->GetPos()).Length()>m_superSkillStyle->m_attackDis)
	{
		return false;
	}

	if (m_superSkillStyle==NULL)
	{
		Assert(0,"m_superSkillStyle==NULL");
		return false;
	}

	return true;
}
bool GladiatorCharacter::GS_SuperSkillStateEnter()
{
	if (m_superSkillStyle==NULL
		|| m_oppositeMan==NULL)
	{
		TryChangeState(GS_Stand);
		return false;
	}

	m_oppositeMan->SetSpeed(vec3(0,0,0));
	m_oppositeMan->ClearMoveForce();
	m_speed = vec3(0,0,0);
	ClearMoveForce();
	//
	RotHeadingTowardPos(m_oppositeMan->GetPos(),false,true);

	m_mp -= 40;
	if (m_mp<0)
	{
		m_mp = 0;
	}

	if ((this==G_GladiatorGame->m_cameraGladiator||m_oppositeMan==G_GladiatorGame->m_cameraGladiator)
		&&m_superScreenEffect==1)
	{
		//已经同步
		G_GladiatorGame->PlayScreenEffect((m_superSkillStyle->ID/*-51001*/)%ScreenEffectNum);
	}

	m_renderCharacter->PlayAnim(m_superSkillStyle->m_animCasterName.c_str());

	//else if (m_fightPos==Jumpping)
	//{
	//	m_renderCharacter->PlayAnim("jumpping_SuperSkill");
	//}

	m_oppositeMan->m_superSkillStyle = m_superSkillStyle;
	m_oppositeMan->SetOppositeMan(this); //被打的人目标可能不匹配
	m_oppositeMan->RotHeadingTowardPos(GetPos(),false,true);
	m_oppositeMan->m_superScreenEffect = m_superScreenEffect;

	//问题:BeSuperSkill时check失败,发现oppsite非SuperSkill状态。
	//解决:1,调试发现robot打robot时触发,SuperSkill消息遗漏。
	//      2,去掉itemstate消息死循环发送后,SuperSkill消息正常收到,但是在BeSuperSkill之后。
	//      3,改正发送顺序
	//host上robot打robot时,导致BeSuperSkill比SuperSkill先发送
	//(10427)CMD_GladiatorState roomSlot=5,oppSlot=1,state=BeSuperSkill
	//(10428)CMD_GladiatorState roomSlot=1,oppSlot=5,state=SuperSkill

	//role打other
	//攻击方延迟:接收方的一帧延迟+消息来回的两个ping  
	//被攻击方延迟:一帧延迟

	//role打robot
	//攻击方延迟:攻击方的一帧延迟  
	//被攻击方延迟:攻击方的一帧延迟+两次消息ping之差

	//延迟带来的问题:可能oppsite自己改了对手,或又被其它玩家必杀成功? 所以不能延迟必须把oppsite状态立即改掉?
	//m_oppositeMan->PostState(GS_BeSuperSkill);
	//m_oppositeMan->TryChangeState(GS_BeSuperSkill);
	m_changeOppsiteState = GS_BeSuperSkill;

	if (!m_superSkillStyle->m_soundName.empty())
	{
		m_sound->PlaySound__(m_superSkillStyle->m_soundName.c_str(),true);
	}
	else
	{
		m_sound->PlaySound__("data/sound/gladiator/SuperSkill.mp3",true);
	}

	//Assert(m_oppositeMan->IsInState(GS_BeSuperSkill),"opposite man not be besuperskill state!");
	//方向不对
	Assert(m_heading.Dot(m_oppositeMan->GetHeading())<-0.9f,"SuperSkill direction not faceing!");

	//LogicCharacter::Update(); 在前面调用,但位置,面向可能已经改变了
	//UpdateToRenderChar();//改动 Update里统一调用

	return true;
}
bool GladiatorCharacter::GS_SuperSkillStateExit()
{
	G_GladiatorGame->StopScreenEffect();
	m_superSkillStyle = NULL;
	vec3 pos;
	m_renderCharacter->GetBoneMatrix("Bip01",&pos);
	GetHeightAt(pos,20,3000);
	SetPos(pos);
	if (m_oppositeMan)
	{
		vec3 dif = m_oppositeMan->GetPos()-m_pos;
		m_distToOppMan = dif.Length();
		RotHeadingTowardPos(m_oppositeMan->GetPos(),false,true);
	}
	m_sound->StopSound();
	return true;
}
bool GladiatorCharacter::GS_SuperSkillStateUpdate()
{
	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_BeSuperSkillStateCheck()
{
	//对手已发动 说明自己状态已经符合
	if (m_superSkillStyle==NULL)
	{
		Assert(0,"m_superSkillStyle==NULL");
		return false;
	}
	//同时被两个人攻击时,oppositeMan会重新设置一下   但是状态同步回到其它客户端时呢?
	if(m_oppositeMan==NULL
		||m_oppositeMan->IsInState(GS_SuperSkill)==false)
	{
		Log::LogStrFormat("Assert GS_BeSuperSkillStateCheck opposite man not be superskill state\n");
		Assert(0,"opposite man not be superskill state!");
		return false;
	}
	//距离不满足
	if ((m_pos-m_oppositeMan->GetPos()).Length()>m_superSkillStyle->m_attackDis)
	{
		Assert(0,"SuperSkill distance too long!");
		return false;
	}
	return true;
}
bool GladiatorCharacter::GS_BeSuperSkillStateEnter()
{
	if (m_superSkillStyle==NULL
		||m_oppositeMan==NULL)
	{
		TryChangeState(GS_Stand);
		return false;
	}

	//可能目标发送改变
	RotHeadingTowardPos(m_oppositeMan->GetPos(),false,true);
	m_speed = vec3(0,0,0);
	ClearMoveForce();

	ChangeHP(-2);

	//? 根据攻击者的技能播放相应动作 并且逆向挂载

	m_renderCharacter->PlayAnim(m_superSkillStyle->m_animTargetName.c_str());

	//else if (m_fightPos==Jumpping)
	//{
	//	m_renderCharacter->PlayAnim("jumpping_BeSuperSkill");
	//}
	//m_sound->PlaySound__("data/sound/gladiator/SuperSkill.mp3");

	return true;
}
bool GladiatorCharacter::GS_BeSuperSkillStateExit()
{
	m_superSkillStyle = NULL;
	vec3 pos;
	m_renderCharacter->GetBoneMatrix("Bip01",&pos);
	GetHeightAt(pos,20,3000);
	SetPos(pos);
	if (m_oppositeMan)
	{
		vec3 dif = m_oppositeMan->GetPos()-m_pos;
		m_distToOppMan = dif.Length();
		RotHeadingTowardPos(m_oppositeMan->GetPos(),false,true);
	}
	m_sound->StopSound();
	return true;
}
bool GladiatorCharacter::GS_BeSuperSkillStateUpdate()
{
	if (m_stateAccumTime>0.5f)
	{
		if(RandHitSec(2.0f))
			ChangeHP(-1);
	}
	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_BeBeatenStateCheck()
{
	//if(this->IsInState(GS_Defend))
	//	return false;
	//必杀暂时不能打断 对于多个打一个要加上此判断 一对一的打对手只能同样处在必杀状态 无法发动普通攻击
	if(IsInState(GS_SuperSkill))
		return false;
	if(IsInState(GS_BeSuperSkill))
		return false;
	if(IsInState(GS_Show))
		return false;
	if(IsInState(GS_Dead))
		return false;
	if(IsInState(GS_BeBeaten))//暂时不能连击
		return false;
	if(m_oppositeMan==NULL)
		return false;
	if (m_oppositeMan->m_item->GetState()==GI_Shooting)
	{
		if(IsInState(GS_Defend))
		{
			//if(m_roadType==m_oppositeMan->m_roadType)
			//{
				return false;
			//}
		}
		else if (IsInState(GS_Jump))
		{
			return false;
		}
		vec3 dif = m_oppositeMan->m_item->GetPos()-m_pos;
		dif.y = 0;
		if(dif.Length()<10)
			return true;
	}

	//pose 不满足
	if ((m_poseType==Jumpping && m_oppositeMan->m_poseType==Squatting)
		||(m_poseType==Squatting && m_oppositeMan->m_poseType==Jumpping)
		)
	{
		return false;
	}

	//路数被防御 动作太快来不及反应,太慢没节奏感,所以要降低防守难度
	//动作攻击路数做的明显写,或者给予其它提示 比如上下箭头
	if(IsInState(GS_Defend))
	{
		if(m_roadType==m_oppositeMan->m_roadType)
		{
			return false;
		}
	}

	//距离不满足
	if ((m_pos-m_oppositeMan->GetPos()).Length()>20)
	{
		return false;
	}

	//验证对手状态
	if ((m_oppositeMan->IsInState(GS_LightPunch)
		||m_oppositeMan->IsInState(GS_HeavyPunch)
		||m_oppositeMan->IsInState(GS_LightKick)
		||m_oppositeMan->IsInState(GS_HeavyKick))==false)
	{
		if (m_oppositeMan->m_item->GetState()!=GI_Shooting)
		{
			Assert(0,"m_oppositeMan not in punch state && not shoot!");
			return false;
		}
	}
	return true;
}
bool GladiatorCharacter::GS_BeBeatenStateEnter()
{
	if (m_oppositeMan==NULL)
	{
		return false;
	}
	if (m_oppositeMan->IsInState(GS_HeavyPunch)
		||m_oppositeMan->IsInState(GS_HeavyKick))
	{
		ChangeHP(-6);
	}
	else
	{
		ChangeHP(-3);
	}

	m_oppositeMan->m_haltTime = 0.2f;
	m_haltTime = 0.2f;
	//可能目标发送改变
	RotHeadingTowardPos(m_oppositeMan->GetPos(),false,true);

	//如果没有被逼到边界则后退  僵直时间过后开始移动
	//MoveFrontLocal(-MoveSpeed);
	
	String animname;
	if (m_poseType==Standing)
	{
		if (m_oppositeMan->m_poseType==Jumpping)
		{
			animname = "standing_beBeatenUp";
		}
		else if (m_oppositeMan->m_poseType==Standing)
		{
			if (m_oppositeMan->IsInState(GS_LightPunch)
				||m_oppositeMan->IsInState(GS_HeavyKick)
				)
			{
				animname = "standing_beBeatenUp";
			}
			else
			{
				animname = "standing_beBeatenMiddle";
			}
		}
		else if (m_oppositeMan->m_poseType==Squatting)
		{
			animname = "standing_beBeatenDown";
		}
	}
	else if (m_poseType==Jumpping)
	{
		if (m_oppositeMan->m_poseType==Jumpping)
		{
			animname = "jumpping_BeBeatenMiddle";
		}
		else if (m_oppositeMan->m_poseType==Standing)
		{
			animname = "jumpping_BeBeatenDown";
		}
		else if (m_oppositeMan->m_poseType==Squatting)
		{
			//距离不够无法攻击
		}
	}
	else if (m_poseType==Squatting)
	{
		if (m_oppositeMan->m_poseType==Jumpping)
		{
			//距离不够无法攻击
		}
		else if (m_oppositeMan->m_poseType==Standing)
		{
			animname = "squatting_beBeatenUp";
		}
		else if (m_oppositeMan->m_poseType==Squatting)
		{
			
		}
	}

	if (animname.empty())
	{
		//??
		animname = "standing_beBeatenMiddle";
	}

	//被击打动作做成有长有短(通过条件帧速率实现?)
	if (animname.empty()==false)
	{
		char buf[256];
		sprintf(buf,"%s%02d",animname.c_str(),(Rand()%2)+1);
		m_renderCharacter->PlayAnim(buf);
		//m_renderCharacter->SetAnimSpeed(RandRange(30,50));
		m_animSpeed = RandRange(30,50);//30+10*RandRange(0,3);
		//m_renderCharacter->SetAnimSpeed(m_animSpeed);

		//飙血
		if (m_animSpeed<40)
		{
			m_modelFightBlood->SetVisible(true,Recursive);
		}
	}
	m_sound->PlaySound__("data/sound/gladiator/punchHit.wav");
	return true;
}
bool GladiatorCharacter::GS_BeBeatenStateExit()
{
	ClearMoveForce();
	return true;
}
bool GladiatorCharacter::GS_BeBeatenStateUpdate()
{
	if(m_haltTime<0)
	{
		//如果没有被逼到边界则后退  僵直时间过后开始移动
		MoveFrontLocal(-MoveForce);
	}
	return true;
}

//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_CatchStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_CatchStateEnter()
{
	//Gladiator::CatchStateEnter();
	return true;
}
bool GladiatorCharacter::GS_CatchStateExit()
{
	//Gladiator::CatchStateExit();
	return true;
}
bool GladiatorCharacter::GS_CatchStateUpdate()
{
	//Gladiator::CatchStateUpdate();
	return true;
}
//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_BeCatchStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_BeCatchStateEnter()
{
	ChangeHP(-6);
	if (m_poseType==Standing)
	{
		m_renderCharacter->PlayAnim("standing_beBeatenUp");
	}
	else if (m_poseType==Jumpping)
	{
		m_renderCharacter->PlayAnim("jumpping_BeBeatenMiddle");
	}
	else
	{
		m_renderCharacter->PlayAnim("standing_beBeatenUp");
	}
	return true;
}
bool GladiatorCharacter::GS_BeCatchStateExit()
{
	return true;
}
bool GladiatorCharacter::GS_BeCatchStateUpdate()
{
	return true;
}


//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_ShowStateCheck()
{
	bool state = false;
	if(IsInState(GS_Stand))
		state = true;
	if(IsInState(GS_Walk))
		state = true;
	if(IsInState(GS_Forward))
		state = true;
	if(IsInState(GS_Defend))//暂时不能连击
		state = true;

	//state 不满足
	if (state==false)
	{
		return false;
	}
	return true;
}
bool GladiatorCharacter::GS_ShowStateEnter()
{
	char buf[256];
	sprintf(buf,"Show_%s%02d",ShowAnimToString(m_showAnim),(Rand()%2)+1);
	m_renderCharacter->PlayAnim(buf);
	//m_sound->PlaySound__("data/sound/event_dead.wav");
	return true;
}
bool GladiatorCharacter::GS_ShowStateExit()
{
	return true;
}
bool GladiatorCharacter::GS_ShowStateUpdate()
{
	return true;
}


//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GS_DeadStateCheck()
{
	return true;
}
bool GladiatorCharacter::GS_DeadStateEnter()
{
	//目标应该没有切换
	if (m_oppositeMan)
	{
		//m_oppositeMan->PostState(GS_Show);
		m_oppositeMan->TryChangeState(GS_Show);
	}
	//G_RpgGame->BreakLifeSpellFromCaster(this);
	m_renderCharacter->PlayAnim("dead");
	m_sound->PlaySound__("data/sound/event_dead.wav");
	return true;
}
bool GladiatorCharacter::GS_DeadStateExit()
{
	return true;
}
bool GladiatorCharacter::GS_DeadStateUpdate()
{
	if(m_stateAccumTime>4.0f)
	{
		m_hp = m_maxHP;
		TryChangeState(GS_Stand);
	}
	return true;
}


GladiatorGame::GladiatOccupationType GladiatorCharacter::GetOccupation() const
{
	return m_occupation;
}
void GladiatorCharacter::SetTeam( GladiatorTeam* team)
{
	if (team==NULL)
	{
		return;
	}
	m_myTeam = team;
	if (m_myTeam->GetType()==TeamRed)
	{
		m_awayTeam = G_GladiatorGame->GetTeam(TeamBlue);
	}
	else if (m_myTeam->GetType()==TeamBlue)
	{
		m_awayTeam = G_GladiatorGame->GetTeam(TeamRed);
	}
	else
	{
		m_awayTeam=NULL;
		//Assert(0&&"error team type!");
	}
}

GladiatorTeam* GladiatorCharacter::GetTeam() const
{
	return m_myTeam;
}

GladiatorTeam* GladiatorCharacter::GetAwayTeam() const
{
	return m_awayTeam;
}

int  GladiatorCharacter::ChangeHP(float hp)
{
	//if (m_noHurt && hp<=0)
	//{
	//	return m_hp;
	//}

	m_hp+=hp;
	if(m_hp < 0)
	{
		m_hp = 0;
		//m_goal = DEAD;
		//TryChangeState(GS_Dead); 被击打动作播完 站立时死亡
	}

	if(m_hp > m_maxHP)
		m_hp = m_maxHP;

	OnChangeHP(hp,m_hp);
	return m_hp;
}

void GladiatorCharacter::OnChangeHP(int change,int current)
{
	if(current > 0)
	{
		Banner* banner = GetBanner(Slot_HeadBanner);
		if(banner)banner->AddBubbleNum(change);
	}
}

void GladiatorCharacter::SetOppositeMan(GladiatorCharacter* oppositeMan)
{
	m_oppositeMan = oppositeMan;
	m_steering->SetTargetEntity(m_oppositeMan);
}

int  GladiatorCharacter::EquipWeapon(int entityID)
{
	while (1)
	{
		WeaponStyle* weaponStyle = G_StyleMgr->GetStyle<WeaponStyle>(2001+Rand()%31);
		if(weaponStyle && 
			(weaponStyle->weaponSlot==WS_Lhand 
			||weaponStyle->weaponSlot==WS_Rhand
			||weaponStyle->weaponSlot==WS_Head)
		)
		{
			GameUtil::MountItem(GetRenderCharacter(),weaponStyle);
			break;
		}
	}
	m_sound->PlaySound__("data/sound/event_equip.wav");
	return true;
}

int  GladiatorCharacter::UnEquipWeapon(int entityID)
{
	GetRenderCharacter()->MountItem(WS_Lhand,NULL);
	GetRenderCharacter()->MountItem(WS_Rhand,NULL);
	GetRenderCharacter()->MountItem(WS_Head,NULL);
	m_sound->PlaySound__("data/sound/event_equip.wav");
	return true;
}


//==================^_^==================^_^==================^_^==================^_^
bool GladiatorCharacter::GetHeightAt(vec3& pos,float top/*=500*/,float bot/*=500*/) const
{
	if (G_GladiatorGame) 
	{	
		return G_GladiatorGame->GetHeightAt(pos,top,bot);
	}
	return false;
}

游戏类:

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/Gladiator/MiniGameGladiator.h
//  @Brief:     MiniGameGladiator
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 

#ifndef  __MiniGameGladiator__H__
#define  __MiniGameGladiator__H__

#include "Rpg/MiniGame.h"
#include "Gladiator/GladiatorTeam.h"

enum MiniGladiatorCmd
{
	CMD_GladiatorState,     //格斗者状态
	CMD_GladiatorMove ,     //位置移动
	CMD_OppositeChange,     //目标改变
	CMD_ItemState     ,     //飞镖道具状态
	CMD_GameOver      ,
	CMD_Restart       ,
};
const char* GladiatorCmdToString(int enumeration);

class GladiatorCharacter;
class GladiatorRobot;
class GladiatorRole;

class MiniGameGladiator:public MiniGame
{
public:
	MiniGameGladiator();
	virtual~MiniGameGladiator();
	virtual bool Start();
	virtual bool Stop();
	virtual bool Render();
	virtual void RenderUI();
	virtual bool Update();
	virtual bool Free();
	virtual bool KeepResource(bool once,int& circle,String& nextTip);

	//三种类型结构
	virtual MiniPlayer*  CreatePlayer();
	virtual MiniPlayer*  CreateRobot ();
	virtual MiniPlayer*  CreateRole  ();

	void  PlayScreenEffect(int id);
	void  StopScreenEffect();

	GladiatorCharacter* GetPlayerFromIndex(int index);
	GladiatorCharacter* GetPlayerFromSlot(int roomSlot);

	//处理游戏网络命令包
	virtual int  ProcessPacketCmd(PacketBase* packet);
	//virtual const char* CmdToString(const char* stream,int len);

public:
	RectF  m_groundRect;
	GladiatorRole*  m_myRolePlayer;
	GladiatorCharacter* m_cameraGladiator;

	float   m_deadAccumeTime;

	GladiatorTeam* GetTeam(TeamType teamtype);
	GladiatorTeam  m_teams[TeamNum];
	GladiatorHalfCourt   m_court[CourtNum];

#define  ScreenEffectNum  4
	RendSys::MovieClip* m_screenEffect[ScreenEffectNum];
	int    m_screenEffectID;

};

extern MiniGameGladiator* G_GladiatorGame;

#endif

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/Gladiator/MiniGameGladiator.cpp
//  @Brief:     MiniGameGladiator
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 
#include "General/Pch.h"
#include "AI/Navigation/SteeringSystem.h"
#include "General/General.h"
#include "General/StringUtil.h"
#include "General/Timer.h"
#include "General/List.cpp"
#include "General/Window.h"
#include "Gladiator/GladiatorCharacter.h"
#include "Gladiator/GladiatorRole.h"
#include "Gladiator/GladiatorRobot.h"
#include "Gladiator/GladiatorTeam.h"
#include "Gladiator/MiniGameGladiator.h"
#include "Gladiator/GladiatorItem.h"
#include "Gladiator/MiGladiator_PlayGui.h"
#include "Gui/GuiMgr.h"
#include "Gui/RpgGuis.h"
#include "Render/Camera.h"
#include "Render/Font.h"
#include "Render/RendDriver.h"
#include "Render/SceneMgr.h"
#include "Render/MC_Misc.h"
#include "Render/Terrain.h"
#include "Rpg/RpgGame.h"
#include "Rpg/Weapon.h"
#include "Rpg/SyncGameInfo.h"
#include "Rpg/NpcStyle.h"
#include "Rpg/RoleStyle.h"
#include "Rpg/GameUtil.h"
#include "Sound/SoundListener.h"
#include "Sound/SoundManager.h"
#include "Sound/ChannelSound.h"
#include "Net/PacketList.h"
#include "General/Pce.h"

//#define InWaterDis 1
#define UndeadTime 2

MiniGameGladiator* G_GladiatorGame = NULL;

class CameraCtrlerGladiator:public CameraCtrlerTarget
{
public:
	CameraCtrlerGladiator();
	virtual void  Update();
};

CameraCtrlerGladiator::CameraCtrlerGladiator()
{
}

void CameraCtrlerGladiator::Update()
{
	if (G_GladiatorGame==NULL)
	{
		m_toBeRemove = true;
		return;
	}
	CheckBoderRot(-HALFPI/8,HALFPI/3);
	CheckWheelDis(20,100);

	Camera* camera = G_Camera;
	float time = G_Timer->GetStepTime();
	GladiatorCharacter* role = G_GladiatorGame->m_cameraGladiator;//m_myGladiator1p;
	if (role==NULL)
	{
		return;
	}
	GladiatorCharacter* enemy = role->m_oppositeMan;
	//如果cameraGladiator的敌人的敌人不是自己,而是另一个玩家,且距离很近,可能做变相运动, 此时eyepos设置在cameraGladiator和敌人之间的某个点会产生振动。
	if (enemy
		/*&&(enemy->m_oppositeMan==role)*/
		&&((role->GetPos()-enemy->GetPos()).Length()<100||role->IsInState(GS_BeSuperSkill) || role->IsInState(GS_SuperSkill))
		)
	{
		vec3 rolePos = role->GetPos();
		vec3 enemyPos = enemy->GetPos();


		
		{
			float heightlimit = 9;//17 CHARACTER_HEIGHT=15
			//被必杀技时视点调节
			vec3 bipPos;
			if (role->IsInState(GS_BeSuperSkill) || role->IsInState(GS_SuperSkill))
			{
				//使用"camera tag"可能切换角度 造成不适
				role->m_renderCharacter->GetBoneMatrix("Bip01",&bipPos);
				rolePos.x = bipPos.x;
				rolePos.z = bipPos.z;
				//调整高度 不要飞出屏幕
				if (bipPos.y-rolePos.y > heightlimit)
				{
					rolePos.y = bipPos.y-heightlimit;
				}
			}
			if (enemy->IsInState(GS_BeSuperSkill) || enemy->IsInState(GS_SuperSkill))
			{
				enemy->m_renderCharacter->GetBoneMatrix("Bip01",&bipPos);
				enemyPos.x = bipPos.x;
				enemyPos.z = bipPos.z;
				//调整高度 不要飞出屏幕
				if (bipPos.y-enemyPos.y > heightlimit)
				{
					enemyPos.y = bipPos.y-heightlimit;
				}
			}
		}


		
		//rotate 尽量使得敌人和主角都在视野中
		vec3 enemy2Role = enemyPos - rolePos;
		float dis2Role = enemy2Role.Length();
		if (dis2Role>5)
		{
			float maxAng = HALFPI- sqrt((/*disEnemy2Eye*/dis2Role-5)/50)*(HALFPI*2/3);
			if (maxAng<HALFPI/3)
			{
				maxAng = HALFPI/3;
			}

			vec3 enemy2Eye = enemyPos - camera->GetEyePos();
			enemy2Eye.y = 0;
			enemy2Eye.Normalize();

			vec3 cameraHead = G_Camera->GetHeadDir();
			cameraHead.y = 0;
			cameraHead.Normalize();
			//0~pi
			float angEnemyCamera = acosf(cameraHead.Dot(enemy2Eye));
			if (angEnemyCamera>maxAng)
			{
				mat4 mat;
				if (G_Camera->GetLeftDir().Dot(enemy2Eye)<0)
				{
					mat.FromRotateY((angEnemyCamera-maxAng));
				}
				else
				{
					mat.FromRotateY(-(angEnemyCamera-maxAng));
				}
				vec3 dir = G_Camera->GetHeadDir();
				dir = mat*dir;
				camera->SetDir(dir,vec3(0,1,0));
			}
		}


		//==================^_^
		vec3 tarPos;
		{
			enemy2Role.Normalize();
			//eyepos在主角和敌人之间的某个点
			float dis = dis2Role/2;
			if (dis>10)
			{
				dis=10;
			}

			//if (role->IsInState(GS_BeBeaten) || role->IsInState(GS_BeSuperSkill))
			//{
			//	//被击中时自己后退,视点相对敌人不动。否则会造成自己不动而敌人后退的假象。
			//	//但是假如视点相对敌人不动,bebeaten结束切到stand状态时会有个突变,所以这个做法也有问题
			//	tarPos = enemy->GetPos()-enemy2Role*dis +vec3(0,GetTarEntity()->GetRadius()*1.5f,0);
			//}
			//else
			{
				tarPos = rolePos + enemy2Role*dis + vec3(0,GetTarEntity()->GetRadius()*1.5f,0);
			}
			//加上身高 使人物偏下
			SetTarPos(tarPos);
		}
		camera->SetEyePos(tarPos - camera->GetHeadDir()*m_distToTar);
	}
	else
	{
		vec3 tarPos = role->GetPos() + vec3(0,GetTarEntity()->GetRadius()*1.5f,0);
		SetTarPos(tarPos);
		camera->SetEyePos(tarPos - camera->GetHeadDir()*m_distToTar);
	}

	//collide
	//if(!G_GuiMgr->IsHoadingInput())
	{
		//CheckSceneCollide(G_ShapeGame->m_movieSceneCollide);
		CheckSceneCollide(G_RpgMap->GetCollideMovie());
	}
}

const char* GladiatorCmdToString(int enumeration)
{
	switch(enumeration)
	{
	case CMD_GladiatorState:return "CMD_GladiatorState";		
	case CMD_GladiatorMove :return "CMD_GladiatorMove";		
	case CMD_OppositeChange:return "CMD_OppositeChange";		
	case CMD_ItemState     :return "CMD_ItemState";		
	case CMD_GameOver      :return "CMD_GameOver";		
	case CMD_Restart       :return "CMD_Restart";		
	default                :return "CMD_unknow";
	}
	return "CMD_unknow";
}

MiniGameGladiator::MiniGameGladiator()
:m_deadAccumeTime(0)
,m_cameraGladiator(NULL)
,m_screenEffectID(-1)
{
	CmdEnumToString = GladiatorCmdToString;
	G_GladiatorGame = this;

	//这里不要new character 否则退出小游戏会出错?
	m_myRolePlayer = NULL;
	
	for (int i=0;i<ScreenEffectNum;i++)
	{
		m_screenEffect[i] = NULL;
	}
	
}

MiniGameGladiator::~MiniGameGladiator()
{
	MiniGameGladiator::Free();
	G_GladiatorGame = NULL;
}

extern List<SkeletonPtr>   m_keepAnim;
bool MiniGameGladiator::Start()
{
	m_myRolePlayer = NULL;
	if(!MiniGame::Start())
		return false;


	if (m_movieScene == NULL)
	{
		LoadConfig loader(LoadConfig::GenDonotReShrinkBound,true,true);
		m_movieScene = new RendSys::MovieClip;
		m_movieScene->LoadFromFile("data/minigame/gladiator/scene.movie",&loader);
		m_movieScene->Advance();

		Frame frame;
		frame.SetPos(m_startPos);
		m_movieScene->SetProgramFrame(&frame);
		m_movieScene->Advance();
	}
	if (m_movieCollide == NULL)
	{
		LoadConfig loader(LoadConfig::GenReShrinkBound,false,false);
		m_movieCollide = new RendSys::MC_Frame;
		m_movieCollide->LoadFromFile("data/minigame/gladiator/scene_collide.movie",&loader);

		Frame frame;
		frame.SetPos(m_startPos);
		m_movieCollide->SetProgramFrame(&frame);
		m_movieCollide->Advance();
	}

	m_deadAccumeTime = 0;

	//场地
	m_court[SouthCourt].m_type = SouthCourt;
	//m_court[SouthCourt].SetPos(m_startPos,rimPos,leftCornerPos,100);

	m_court[NorthCourt].m_type = NorthCourt;
	//m_court[NorthCourt].SetPos(m_startPos,rimPos,leftCornerPos,100);

	//?单独隐藏G_MyRole及参加了小游戏的RoleOther; 还是隐藏所有的rpg世界包括npc monster,否则monster乱入时,是打还是不打?? 
	//?如果不隐藏且可以和monster交互,则gladitorRole是否要继承rpgRole的类以便和monster发生关系??另外继承了之后是否移动同步之类功能可以复用??

	//玩家
	for(int i = 0; i < m_allPlayerNum; i++)
	{
		MyRoomPlayerInfo* playerInfo = G_SyncMyRoomInfo->GetPlayerFromIndex(i);
		if(playerInfo)
		{
			GladiatorCharacter* character = dynamic_cast<GladiatorCharacter*>(m_miniPlayer[i]);
			if(dynamic_cast<GladiatorRobot*>(character))
			{
				dynamic_cast<GladiatorRobot*>(character)->m_hideAccumeTime = RandRange(1.0f,3.0f);
			}

			//体形
			CharacterStyle* playerStyle = NULL;//= G_StyleMgr->GetStyle<GladiatorCharacterStyle>(50001~50004);
			if (playerInfo->isAI)
			{
				//只能选man型,否则动作不全
				playerStyle = G_StyleMgr->GetStyle<NpcStyle>(playerInfo->style);
			}
			else
			{
				playerStyle = G_StyleMgr->GetStyle<RoleStyle>(playerInfo->style);
			}
			if (playerStyle)
			{
				character->SetStyle(playerStyle);
			}

			//武器
			dynamic_cast<GladiatorCharacter*>(m_miniPlayer[i])->GetRenderCharacter()->MountItem(-1,NULL);
			GameUtil::MountItem(dynamic_cast<GladiatorCharacter*>(m_miniPlayer[i])->GetRenderCharacter(),playerInfo->weaponNum,playerInfo->weaponStyle);
		}

		m_miniPlayer[i]->Start();
	}


	//队伍
	m_teams[TeamRed] .SetSide(TeamRed,&m_court[SouthCourt],&m_court[NorthCourt]);
	m_teams[TeamBlue].SetSide(TeamBlue,&m_court[NorthCourt],&m_court[SouthCourt]);
	m_teams[TeamRed] .Start();
	m_teams[TeamBlue].Start();
	//分队
	for (int i=0;i<MaxRoomPlayer/2;i++)
	{
		GladiatorCharacter* character = GetPlayerFromSlot(i);
		if(character)
		{
			m_teams[TeamRed].m_mans[m_teams[TeamRed].m_manNum++] = character; 
			character->SetTeam(&m_teams[TeamRed]);
			character->SetOppositeMan(GetPlayerFromSlot(i+MaxRoomPlayer/2));
			vec3 pos = m_startPos+vec3((i/3)*30,5,(i%3)*30);
			character->GetHeightAt(pos);
			character->SetPos(pos);
			if(dynamic_cast<GladiatorRobot*>(character))
				dynamic_cast<GladiatorRobot*>(character)->m_homePos = pos;
		}
	}
	for (int i=MaxRoomPlayer/2;i<MaxRoomPlayer;i++)
	{
		GladiatorCharacter* character = GetPlayerFromSlot(i);
		if(character)
		{
			m_teams[TeamBlue].m_mans[m_teams[TeamBlue].m_manNum++] = character; 
			character->SetTeam(&m_teams[TeamBlue]);
			character->SetOppositeMan(GetPlayerFromSlot(i-MaxRoomPlayer/2));
			vec3 pos = m_startPos+vec3((i/3)*30,5,(i%3)*30);
			character->GetHeightAt(pos);
			character->SetPos(pos);
			if(dynamic_cast<GladiatorRobot*>(character))
				dynamic_cast<GladiatorRobot*>(character)->m_homePos = pos;
		}
	}
	m_teams[TeamRed].SetTeamLeader(GetPlayerFromSlot(0));
	m_teams[TeamBlue].SetTeamLeader(GetPlayerFromSlot(MaxRoomPlayer/2));


	//摄像机
	if (m_myRolePlayer)
	{
		m_cameraGladiator = m_myRolePlayer;
	}
	else
	{
		m_cameraGladiator = (GladiatorCharacter*)m_miniPlayer[0];
	}


	//设置摄像机
	CameraCtrlerGladiator* ctrler = new CameraCtrlerGladiator;
	ctrler->SetDistToTar(30);
	ctrler->SetTarEntity(m_cameraGladiator);
	G_Camera->PopCtrler();
	G_Camera->PushCtrler(ctrler);
	G_Camera->SetEuler(0, -10, 0);
	//片头摄像机
	PushIntroCamera();

	//role
	G_MyRole->SetExternState(new CharacterState);
	G_MyRole->SetPos(m_startPos);

	//进入miniplaygui,(选人、选关卡都已在房间里进行完毕)。
	if(GetStyle()) G_GuiMgr->PushGui(GetStyle()->playGUI.c_str(),GL_DIALOG);
 	return true; 
}
MiniPlayer* MiniGameGladiator::CreatePlayer()
{
	return new GladiatorCharacter;
}

MiniPlayer* MiniGameGladiator::CreateRobot()
{
	return new GladiatorRobot;
}

MiniPlayer* MiniGameGladiator::CreateRole()
{
	m_myRolePlayer = new GladiatorRole(Player1P);
	return m_myRolePlayer;
}
GladiatorCharacter* MiniGameGladiator::GetPlayerFromIndex(int index)
{
	return dynamic_cast<GladiatorCharacter*>(MiniGame::GetPlayerFromIndex(index));
}

GladiatorCharacter* MiniGameGladiator::GetPlayerFromSlot(int roomSlot)
{
	return dynamic_cast<GladiatorCharacter*>(MiniGame::GetPlayerFromSlot(roomSlot));
}

bool MiniGameGladiator::Stop()
{
	G_GuiMgr->PopGui("MiGladiator_PlayGui");
	G_Camera->PopCtrler();
	CameraCtrlerTarget* ctrlerTarget = G_Camera->IsCurCtrler<CameraCtrlerTarget>();
	if(ctrlerTarget)
		ctrlerTarget->SetTarEntity(G_MyRole);
	G_MyRole->SetExternState(NULL);
	
	//char buf[256];

	G_GuiMgr->PopGui("MiGladiator_PlayGui");
	
	{
		if (m_myRolePlayer && m_myRolePlayer->m_liveNum>0)
		{
			G_GuiMgr->GetGui<Rpg_ResultDialog>()->ShowResult(true);
		}
		else
		{
			G_GuiMgr->GetGui<Rpg_ResultDialog>()->ShowResult(false);
		}
		G_GuiMgr->PushGui("Rpg_ResultDialog",GL_DIALOGBOTTOM);
	}

	MiniGame::Stop();
	return true;
}

bool MiniGameGladiator::Render()
{
	MiniGame::Render();

	//屏幕特效介于 场景和人物中间
	//m_screenEffectID=1;
	if(m_screenEffectID>=0)
	{
		G_RendDriver->BeginUI(-512,-384,1024,768);
		//depth mask == false
		m_screenEffect[m_screenEffectID]->Advance();
		m_screenEffect[m_screenEffectID]->RendClip();
		G_RendDriver->EndUI();
	}

	for (int i=0;i<m_allPlayerNum;i++)
	{
		dynamic_cast<GladiatorCharacter*>(m_miniPlayer[i])->Render();
	}

	return true;
}

void MiniGameGladiator::RenderUI()
{
	MiniGame::RenderUI();
	G_RendDriver->BeginUI();

	char buf[256];
	分数: %d 
	if(m_myPlayer)
		sprintf(buf,TextData::GetText("T_PVB_TIP_04" ),m_myPlayer->m_score);
	//G_FontMgr->TextAtPos(vec2(200, 200),buf);
	剩余生命:%d
	//sprintf(buf,TextData::GetText("T_RACING_TIP_03" ),m_life);
	//G_FontMgr->TextAtPos(vec2(200, 230),buf);


#ifdef _DEBUG
	G_FontMgr->GetFontDesc().fontSize = 14;

	float x = 153;
	float y = 250;
	float h = 18;
	//==================^_^
	Color colors[] =
	{ 
		Color(1.0f,0.0f,0.0f,1.0f),
		Color(0.0f,0.0f,1.0f,1.0f),
		Color(0.6f,0.5f,0.0f,1.0f),
		Color(0.1f,0.3f,0.7f,1.0f)
	};
	//已经根据slot排序
	for (int i=0;i<m_allPlayerNum;i++)
	{
		GladiatorCharacter* character = dynamic_cast<GladiatorCharacter*>(m_miniPlayer[i]);
		if(character==NULL)
			continue;
		G_FontMgr->SetColor(colors[i]);

		if (character->GetPlayerInfo())
		{
			sprintf_s(buf,"%s",character->GetPlayerInfo()->playerName);
			G_FontMgr->TextAtPos(vec2(x, y),buf);
			y+= h;
		}
	

		sprintf_s(buf,"%s",GladiatorCharacterStateToString(character->GetState()));
		G_FontMgr->TextAtPos(vec2(x, y),buf);
		y+= h;

		sprintf_s(buf,"%s",character->GetRenderCharacter()->GetCurAnimName());
		G_FontMgr->TextAtPos(vec2(x, y),buf);
		y+= h;
	}

	G_FontMgr->GetFontDesc().fontSize = 16;
#endif
}

bool MiniGameGladiator::Update()
{
	MiniGame::Update();
	if (m_deadAccumeTime < UndeadTime)
	{
		m_deadAccumeTime += G_Timer->GetStepTime();
	}

	for (int i=0;i<m_allPlayerNum;i++)
	{
		m_miniPlayer[i]->Update();
	}

	if (m_myPlayer
		&&m_myPlayer->m_score > 30)
	{
		m_gameState = MS_End;
	}

	if (G_Keyboard->IsKeyPressed(DIK_RCONTROL)
		&&G_Keyboard->IsKeyDowning(DIK_M)
		)
	{
		if (m_screenEffectID<0)
		{
			PlayScreenEffect(rand()%4);
		}
		else
		{
			StopScreenEffect();
		}
	}
	return true;
}

bool MiniGameGladiator::Free()
{
	MiniGame::Free();
	for (int i=0;i<ScreenEffectNum;i++)
	{
		if(m_screenEffect[i])
			m_screenEffect[i]->FreeMovie();
		SafeDelete(m_screenEffect[i]);
	}
	return true;
}

bool MiniGameGladiator::KeepResource(bool once,int& circle,String& nextTip)
{
	static bool LoadedStyles = false;
	if (LoadedStyles==false)
	{
		/*  Gladiator50001
			*/
		LoadedStyles = true;
		G_StyleMgr->LoadStyles<GladiatorCharacterStyle>("data/Logic/Style/Gladiator.style",Enum_Style(GladiatorCharacterStyle));
		G_StyleMgr->LoadStyles<GladiatorSuperSkillStyle>("data/Logic/Style/gladiatorsuperskill.style",Enum_Style(GladiatorSuperSkillStyle));

		if(G_StyleMgr->GetStyleNum<WeaponStyle>()==0)
			G_StyleMgr->LoadStyles<WeaponStyle>("data/Logic/Style/Weapon.style",Enum_Style(WeaponStyle));
	}

	//keep Gladiator
	{
		PROFILEFUN("MiniGameGladiator::KeepResource(bool once,int& circle,String& nextTip);",0.0f,ALWAYSHIDE);
		StyleGroupRef styles(Enum_Style(GladiatorCharacterStyle));
		GladiatorCharacterStyle* it = (GladiatorCharacterStyle*)styles.GetFirst();
		while (it)
		{
			//Log::LogStr((*it).modelName);
			G_MovieClipMgr->KeepMovie((*it).modelName);
			G_RpgMap->KeepBoneStyle((*it).boneStyle);
			it = (GladiatorCharacterStyle*)styles.GetNext();
		}


		char* poseName[3] = 
		{
			"Standing",
			"Jumpping",
			"Squatting",
		};
		char* roadName[3] = 
		{
			"Up",
			"Middle",
			"Down",
		};
		char buf[256];
		for (int pose=0;pose<3;pose++)
		{
			for (int road=0;road<3;road++)
			{
				for (int i=0;i<1;i++)
				{
					//Standing_PunchLeftUp01
					sprintf(buf,"data/modelcharacter/commonman/commonman_%s_PunchLeft%s%02d.bone",poseName[pose],roadName[road],i+1);
					G_SkeletonMgr->KeepAnim(buf);
					sprintf(buf,"data/modelcharacter/commonman/commonman_%s_PunchRight%s%02d.bone",poseName[pose],roadName[road],i+1);
					G_SkeletonMgr->KeepAnim(buf);
					sprintf(buf,"data/modelcharacter/commonman/commonman_%s_KickLeft%s%02d.bone",poseName[pose],roadName[road],i+1);
					G_SkeletonMgr->KeepAnim(buf);
					sprintf(buf,"data/modelcharacter/commonman/commonman_%s_KickRight%s%02d.bone",poseName[pose],roadName[road],i+1);
					G_SkeletonMgr->KeepAnim(buf);
					sprintf(buf,"data/modelcharacter/commonman/commonman_%s_defend%s%02d.bone",poseName[pose],roadName[road],i+1);
					G_SkeletonMgr->KeepAnim(buf);
				}
				for (int i=0;i<2;i++)
				{
					//Standing_PunchLeftUp01
					sprintf(buf,"data/modelcharacter/commonman/commonman_%s_BeBeaten%s%02d.bone",poseName[pose],roadName[road],i+1);
					G_SkeletonMgr->KeepAnim(buf);
				}
			}

			for (int i=0;i<2;i++)
			{
				sprintf(buf,"data/modelcharacter/commonman/commonman_%s_Standby%02d.bone",poseName[pose],i+1);
				G_SkeletonMgr->KeepAnim(buf);
				sprintf(buf,"data/modelcharacter/commonman/commonman_%s_Walk%02d.bone",poseName[pose],i+1);
				G_SkeletonMgr->KeepAnim(buf);
				sprintf(buf,"data/modelcharacter/commonman/commonman_%s_WalkRight%02d.bone",poseName[pose],i+1);
				G_SkeletonMgr->KeepAnim(buf);
				sprintf(buf,"data/modelcharacter/commonman/commonman_%s_Forward%02d.bone",poseName[pose],i+1);
				G_SkeletonMgr->KeepAnim(buf);
			}
		}

		for (int super=0;super<4;super++)
		{
			sprintf(buf,"data/modelcharacter/commonman/commonman_Standing_superskill%02d.bone",super+1);
			G_SkeletonMgr->KeepAnim(buf);
			sprintf(buf,"data/modelcharacter/commonman/commonman_Standing_BeSuperskill%02d.bone",super+1);
			G_SkeletonMgr->KeepAnim(buf);
		}

		for (int show=0;show<SA_Num;show++)
		{
			for (int i=0;i<2;i++)
			{
				sprintf(buf,"data/modelcharacter/commonman/commonman_Show_%s%02d.bone",ShowAnimToString(show),i+1);
				G_SkeletonMgr->KeepAnim(buf);
			}
		}

		for (int screen=0;screen<ScreenEffectNum;screen++)
		{
			if (m_screenEffect[screen]==NULL)
			{
				LoadConfig loader(LoadConfig::GenDonotReShrinkBound,true,true);
				m_screenEffect[screen] = new RendSys::MovieClip;
				sprintf(buf,"data/effect/gladiatorEffect/gladiatorScreen%02d.movie",screen+1);
				m_screenEffect[screen]->LoadFromFile(buf,&loader);
				m_screenEffect[screen]->SetFrustumSkipEnable(false,Recursive);
				//不要遮蔽角色
				m_screenEffect[screen]->SetDepthMask(false,Recursive);
			}
		}

	}

	return true;
}

void MiniGameGladiator::PlayScreenEffect(int id)
{
	if (id<0||id>ScreenEffectNum)
	{
		return;
	}
	m_screenEffectID = id;
	m_screenEffect[m_screenEffectID]->GotoAndPlay(0,Recursive);
}

void MiniGameGladiator::StopScreenEffect()
{
	m_screenEffectID = -1;
}


GladiatorTeam* MiniGameGladiator::GetTeam(TeamType teamtype)
{
	return &m_teams[teamtype];
}

int  MiniGameGladiator::ProcessPacketCmd(PacketBase* packet)
{
	int cmd;
	packet->ReadValue(cmd);
	switch(cmd)
	{
	case CMD_GladiatorState:
		{
			int  roomSlot;
			int  oppositeSlot;
			vec3 pos;
			vec3 speed;
			vec3 heading;
			int  roadType;
			int  poseType;
			int  curState;
			int  curStateType;
			packet->ReadValue(roomSlot);
			packet->ReadValue(oppositeSlot);
			packet->ReadValue(curState);
			packet->ReadValue(curStateType);
			packet->ReadValue(roadType);
			packet->ReadValue(poseType);
			packet->ReadValue(pos);
			packet->ReadValue(speed);
			packet->ReadValue(heading);

//			int hitSuccess;
//			int superSkillSuccess;
			int superScreenEffect;
			int superSkillStyle;
			int showAnim;
			switch (curState)
			{
			case GS_LightPunch:      //轻拳
			case GS_HeavyPunch:      //重拳
			case GS_LightKick:       //轻踢
			case GS_HeavyKick:       //重踢
				//packet->ReadValue(hitSuccess);  //hitSuccess在打击点到来时才会决出??
				break;

			case GS_SuperSkill:       //必杀技
			case GS_BeSuperSkill:     //被必杀技
				//packet->ReadValue(superSkillSuccess);
				packet->ReadValue(superSkillStyle);
				packet->ReadValue(superScreenEffect);
				break;

			case GS_Show:
				packet->ReadValue(showAnim);
				break;
			}

			GladiatorCharacter* player = dynamic_cast<GladiatorCharacter*>(GetPlayerFromSlot(roomSlot));
			if (player)
			{
				player->SetPos(pos);
				player->SetSpeed(speed);
				player->SetHeading(heading);
				player->m_roadType = (GladiatorGame::GladiatRoadType)roadType;
				player->m_poseType = (GladiatorGame::GladiatPoseType)poseType;

				switch (curState)
				{
				case GS_LightPunch:      //轻拳
				case GS_HeavyPunch:      //重拳
				case GS_LightKick:       //轻踢
				case GS_HeavyKick:       //重踢
					//player-> = hitSuccess;
					break;

				case GS_SuperSkill:       //必杀技
				case GS_BeSuperSkill:     //被必杀技
					player->m_superSkillStyle = G_StyleMgr->GetStyle<GladiatorSuperSkillStyle>(superSkillStyle);
					player->m_superScreenEffect = superScreenEffect;
					break;

				case GS_Show:
					player->m_showAnim = (GladiatorGame::ShowAnim)showAnim;
					break;
				}

				GladiatorCharacter* oppositeMan = dynamic_cast<GladiatorCharacter*>(GetPlayerFromSlot(oppositeSlot));
				player->SetOppositeMan(oppositeMan);
				player->TryChangeState((GladiatorGame::GladiatorCharacterState)curState);
			}

			//Log::AddLogStrFormat("CMD_GladiatorState roomSlot=%d,oppSlot=%d,state=%s\n",roomSlot,oppositeSlot,GladiatorCharacterStateToString(curState));
			Log::LogStrFormat("(%d)CMD_GladiatorState roomSlot=%d,oppSlot=%d,state=%s\n",packet->m_debugID,roomSlot,oppositeSlot,GladiatorCharacterStateToString(curState));

		}
		break;
	case CMD_OppositeChange:
		{
			int  roomSlot;
			int  oppositeSlot;
			packet->ReadValue(roomSlot);
			packet->ReadValue(oppositeSlot);

			GladiatorCharacter* player = dynamic_cast<GladiatorCharacter*>(GetPlayerFromSlot(roomSlot));
			if (player)
			{
				GladiatorCharacter* oppositeMan = dynamic_cast<GladiatorCharacter*>(GetPlayerFromSlot(oppositeSlot));
				player->SetOppositeMan(oppositeMan);
			}

			Log::LogStrFormat("(%d)CMD_OppositeChange roomSlot=%d,oppSlot=%d\n",packet->m_debugID,roomSlot,oppositeSlot);
		}
		break;
	case CMD_GladiatorMove:
		{
			int  roomSlot;
			vec3 pos;
			vec3 speed;
			vec3 heading;
			int  roadType;
			int  poseType;
			packet->ReadValue(roomSlot);
			packet->ReadValue(pos);
			packet->ReadValue(speed);
			packet->ReadValue(heading);
			packet->ReadValue(roadType);
			packet->ReadValue(poseType);
			//
			GladiatorCharacter* player = dynamic_cast<GladiatorCharacter*>(GetPlayerFromSlot(roomSlot));
			if (player)
			{
				player->SetPos(pos);
				player->SetSpeed(speed);
				player->SetHeading(heading);
				player->m_roadType = (GladiatorGame::GladiatRoadType)roadType;
				player->m_poseType = (GladiatorGame::GladiatPoseType)poseType;
			}
			//Log::LogStrFormat("(%d)CMD_OppositeChange roomSlot=%d,oppSlot=%d\n",packet->m_debugID,roomSlot,oppositeSlot);
		}
		break;
	case CMD_ItemState:
		//出现时同步一下GI_Catched,剩下的阶段自己模拟?
		{
			int  roomSlot;
			int  state;
			packet->ReadValue(roomSlot);
			packet->ReadValue(state);
			GladiatorCharacter* player = dynamic_cast<GladiatorCharacter*>(GetPlayerFromSlot(roomSlot));
			if (player)
			{
				player->m_item->SetState((GladiatorItemState)state);
			}
			Log::LogStrFormat("(%d)CMD_ItemState roomSlot=%d,state=%d\n",packet->m_debugID,roomSlot,state);
		}
		break;
	}
	return 0;
}

//1 某玩家卡死  其它玩家不会退出
//2 host结束游戏 其它玩家DOWN机
//3 superskill 同步问题