ARPG游戏的战斗模式

  • 一般ARPG游戏的战斗模式
    • 请求服务器开始战斗,校验合法则开始加载战场资源
    • 玩家操控角色施放技能
      • 本质就是控制角色播放动作
      • 对应时间点播放技能特效与音效
    • 计算攻击范围与伤害
    • 保留相应运算结果,战斗数据发往服务器校验
    • 结果合法则发放关卡奖励

战斗逻辑框架

战斗逻辑框架

Controller用于表现层(继承MonoBehaviour),EntityBase用于逻辑层

进入战斗副本的流程

首先从服务器发出的战斗回应信息通过FubenSys处理

1
2
3
4
5
6
7
8
9
10
public void RspFBFight(GameMsg msg)
{
RspFBFight data = msg.rspFBFight;

GameRoot.Instance.SetPlayerDataByFBFight(data);//扣除玩家体力

MainCitySys.Instance.mainCityWnd.SetWndState(false);//关掉主城UI
SetFubenWndState(false);//关掉副本选择UI
BattleSys.Instance.StartBattle(data.fbid);
}

BattleSys开始准备战斗系统必要的组件

1
2
3
4
5
6
7
8
9
10
public void StartBattle(int mapid)
{
GameObject go = new GameObject
{
name = "BattleRoot"
};
go.transform.SetParent(GameRoot.Instance.transform);
BattleMgr battleMgr = go.AddComponent<BattleMgr>();//准备BattleMgr
battleMgr.InitMgr(mapid);
}

BattleMgr

加载地图、加载角色的操作由BattleMgr来完成,BattleMgr每次进入战斗场景都会由BattleSys单独创建,一旦退出战斗场景它就会一并消除。

BattleMgr还负责控制角色移动,释放角色技能的逻辑,我们在UI层控制角色时通过BattleSys做一个周转来调用到BattleMgr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
    public class BattleMgr : MonoBehaviour
{
ResSvc resSvc;
AudioSvc audioSvc;

StateMgr stateMgr;
SkillMgr skillMgr;
MapMgr mapMgr;
public void InitMgr(int mapid)
{
resSvc = ResSvc.Instance;
audioSvc = AudioSvc.Instance;

//初始化各管理器
stateMgr = gameObject.AddComponent<StateMgr>();
stateMgr.InitMgr();
skillMgr = gameObject.AddComponent<SkillMgr>();
skillMgr.InitMgr();


MapCfg mapCfg = resSvc.GetMapCfg(mapid);
resSvc.AsyncLoadScene(mapCfg.sceneName, () =>
{
//初始化地图数据
GameObject mapRoot = GameObject.FindGameObjectWithTag("MapRoot");
mapMgr = mapRoot.GetComponent<MapMgr>();
mapMgr.InitMgr();
//调整地图内的物体,防止美术人员误操作
mapRoot.transform.localPosition = Vector3.zero;
mapRoot.transform.localScale = Vector3.one;

Camera.main.transform.position = mapCfg.mainCamPos;
Camera.main.transform.localEulerAngles = mapCfg.mainCamRota;

LoadPlayer(mapCfg);

audioSvc.PlayBGMusic(Constants.BGHuangYe);
});


}
private void LoadPlayer(MapCfg mapCfg)
{
GameObject player = resSvc.LoadPrefab(PathDefine.AssassinBattlePlayerPrefab);//在战斗场景使用的是不同的PlayerPrefab
player.transform.position = mapCfg.playerBornPos;
player.transform.localEulerAngles= mapCfg.playerBornRota;
player.transform.localScale = Vector3.one;
}

public void SetSelfPlayerMoveDir(Vector2 dir)
{
//设置玩家移动
}
public void ReqReleaseSkill(int skillId)
{
switch(skillId)
{
case 0:
ReleaseNormalAtk();
break;
case 1:
ReleaseSkill1();
break;
case 2:
ReleaseSkill2();
break;
case 3:
ReleaseSkill3();
break;
}
}
private void ReleaseNormalAtk()
{

}
private void ReleaseSkill1()
{

}
private void ReleaseSkill2()
{

}
private void ReleaseSkill3()
{

}
}