望望窗外,单日人数过两万了,心塞,挺住。吃点水饺,埋头写作。
这是多年前写的一个格斗小游戏,类似拳皇的玩法。今天把代码贴出来。
一个人制作的格斗游戏
//按 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",
电脑跑不动了,在以前的视频里截了张图。
//========================================================
// @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 同步问题
完