This commit is contained in:
MuHua-123
2025-07-22 16:35:23 +08:00
parent a7eb4f7bbb
commit 1adce62b71
21 changed files with 379 additions and 106 deletions
@@ -9,24 +9,29 @@ public class BattleCharacter : DataAttribute {
/// <summary> 角色数据 </summary>
public readonly DataCharacter character;
/// <summary> 归属队伍 </summary>
public int team;
/// <summary> 角色名字 </summary>
public string name;
/// <summary> 战斗等级 </summary>
public int level;
/// <summary> 生命点 </summary>
public int hitPoint;
/// <summary> 护甲等级 </summary>
public int armorClass;
/// <summary> 战场位置 </summary>
public int position;
/// <summary> 先攻顺序 </summary>
public int sequence;
/// <summary> 护甲等级 </summary>
public int armorClass;
/// <summary> 生命点 </summary>
public Vector2Int hitPoint;
public BattleCharacter(DataCharacter character) {
public BattleCharacter(DataCharacter character, int team) {
this.character = character;
Cover(character);
this.team = team;
name = character.name;
level = character.Level;
hitPoint = character.HitPoint;
position = 1;
hitPoint = new Vector2Int(character.HitPoint, character.HitPoint);
armorClass = character.ArmorClass;
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 59e1aa3dad18b83438571f22a94d78af
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,41 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 阶段类型
/// </summary>
public enum PhaseType {
,
,
,
,
,
}
/// <summary>
/// 阶段
/// </summary>
public interface IPhase {
/// <summary> 开始阶段 </summary>
public void StartPhase();
/// <summary> 更新阶段 </summary>
public void UpdatePhase();
/// <summary> 退出阶段 </summary>
public void QuitPhase();
}
/// <summary>
/// 战斗阶段
/// </summary>
public abstract class BattlePhase : IPhase {
/// <summary> 模拟器 </summary>
public readonly BattleSimulator simulator;
/// <summary> 战斗队列 </summary>
public BattleQueue BattleQueue => simulator.battleQueue;
public BattlePhase(BattleSimulator simulator) => this.simulator = simulator;
public abstract void StartPhase();
public abstract void UpdatePhase();
public abstract void QuitPhase();
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ee046dc0d64f6184c966baba17876ec9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,30 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 行动阶段
/// </summary>
public class PhaseAction : BattlePhase {
public PhaseAction(BattleSimulator simulator) : base(simulator) { }
public override void StartPhase() {
// throw new System.NotImplementedException();
}
public override void UpdatePhase() {
// 选择行动目标,没有行动目标则进入结算阶段
if (!BattleQueue.Dequeue(out BattleCharacter character)) { simulator.Transition(PhaseType.); return; }
// 判断是否可以行动
// 选择一个目标
// 对目标进行攻击
// TODO:记录器
// Debug.Log($"正式回合:{roundCount}");
}
public override void QuitPhase() {
// throw new System.NotImplementedException();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad6c0033db83a3c4fa9d92f3f1912d5f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 突袭阶段
/// </summary>
public class PhaseAssault : BattlePhase {
public PhaseAssault(BattleSimulator simulator) : base(simulator) { }
public override void StartPhase() {
throw new System.NotImplementedException();
}
public override void UpdatePhase() {
throw new System.NotImplementedException();
}
public override void QuitPhase() {
throw new System.NotImplementedException();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 620e71ced51f8e94997a198ac8b1e6c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 结束阶段
/// </summary>
public class PhaseFinish : BattlePhase {
public PhaseFinish(BattleSimulator simulator) : base(simulator) { }
public override void StartPhase() {
throw new System.NotImplementedException();
}
public override void UpdatePhase() {
throw new System.NotImplementedException();
}
public override void QuitPhase() {
throw new System.NotImplementedException();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 357207f5d09ca394e84210d51916507b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,27 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 正式阶段
/// </summary>
public class PhaseFormal : BattlePhase {
/// <summary> 回合计数 </summary>
public int roundCount;
public PhaseFormal(BattleSimulator simulator) : base(simulator) { }
public override void StartPhase() {
// throw new System.NotImplementedException();
}
public override void UpdatePhase() {
roundCount++;
BattleQueue.UpdateQueue();
simulator.Transition(PhaseType.);
// TODO:记录器
Debug.Log($"正式回合:{roundCount}");
}
public override void QuitPhase() {
// throw new System.NotImplementedException();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 066680fafb7f9cf4dbac4f7291e682cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,26 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 先攻阶段
/// </summary>
public class PhaseInitiative : BattlePhase {
public PhaseInitiative(BattleSimulator simulator) : base(simulator) { }
public override void StartPhase() {
// throw new System.NotImplementedException();
}
public override void UpdatePhase() {
BattleQueue.ForEach(obj => obj.sequence = Dice.Roll20(obj.DexModifier));
BattleQueue.OrderByDescending(c => c.sequence);
// TODO:需要添加突袭阶段
simulator.Transition(PhaseType.);
// TODO:记录器
Debug.Log("先攻");
}
public override void QuitPhase() {
// throw new System.NotImplementedException();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4fc0f8aced9d5f04f879b8300fd02e47
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+11 -10
View File
@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@@ -20,20 +21,20 @@ public class BattleQueue {
public void Add(BattleCharacter character) {
characters.Add(character);
}
/// <summary> 先攻:d20 + 敏捷调整值 </summary>
public void Sequence() {
characters.ForEach(obj => obj.sequence = Dice.Roll20(obj.DexModifier));
/// <summary> 遍历角色 </summary>
public void ForEach(Action<BattleCharacter> action) {
characters.ForEach(action);
}
/// <summary> 排序:大到小 </summary>
public void OrderByDescending() {
characters = characters.OrderByDescending(c => c.sequence).ToList();
// /// <summary> 排序:大到小 </summary>
public void OrderByDescending(Func<BattleCharacter, int> func) {
characters = characters.OrderByDescending(func).ToList();
}
/// <summary> 回合 </summary>
public void Reset() {
/// <summary> 更新队列 </summary>
public void UpdateQueue() {
queue = new Queue<BattleCharacter>(characters);
}
/// <summary> 当前行动者 </summary>
public bool Current(out BattleCharacter battle) {
/// <summary> 取出一个 </summary>
public bool Dequeue(out BattleCharacter battle) {
battle = queue.Count > 0 ? queue.Dequeue() : null;
return battle != null;
}
@@ -10,97 +10,41 @@ using UnityEngine;
/// </summary>
public class BattleSimulator {
// 先攻判断
// 艾薇拉(18) → 哥布林射手(15) → 托尔吉(7) → 哥布林战士(5)
// 突袭轮
// 哥布林射手 使用短弓射击(23)对艾薇拉(AC12)造成了 5穿刺伤害
// 正式回合1
// ‌艾薇拉 施放纠缠术‌(法术豁免DC14),哥布林射手(敏捷豁免6)被束缚
// ‌艾薇拉 躲至矿石掩体后(AC提升至14)
// 哥布林射手 试图挣脱藤蔓(力量豁免‌3‌)失败了
// 哥布林射手 使用多重射击,第一箭(劣势2)对托尔吉(AC14)未命中,第二箭(劣势9)对托尔吉(AC14)未命中
// 托尔吉 使用狂暴‌(附赠动作开启)→ 获得力量加成与抗性
// 托尔吉 移动至哥布林战士前面
// 托尔吉 使用巨斧猛击(19)对哥布林战士(AC12) 造成了 14钝击伤害
// 哥布林战士死亡
// 正式回合2
// ‌艾薇拉 施放奥术飞弹‌(法术豁免DC14),哥布林射手(敏捷豁免6)受到了 10奥术伤害
// 哥布林射手死亡
/// <summary> 回合计数 </summary>
public int roundCount;
/// <summary> 行动间隔 </summary>
public float interval;
/// <summary> 最大间隔 </summary>
public float maxInterval = 1f;
/// <summary> 当前行动 </summary>
public Action currentAction;
/// <summary> 队伍1 </summary>
public BattleTeam team1;
/// <summary> 队伍2 </summary>
public BattleTeam team2;
/// <summary> 战斗队列 </summary>
public BattleQueue battleQueue = new BattleQueue();
public BattleSimulator(List<DataCharacter> cha1, List<DataCharacter> cha2) {
List<BattleCharacter> bCha1 = new List<BattleCharacter>();
cha1.ForEach(obj => bCha1.Add(new BattleCharacter(obj)));
List<BattleCharacter> bCha2 = new List<BattleCharacter>();
cha2.ForEach(obj => bCha2.Add(new BattleCharacter(obj)));
/// <summary> 当前阶段 </summary>
public IPhase currentPhase;
/// <summary> 阶段字典 </summary>
public Dictionary<PhaseType, IPhase> dictionary = new Dictionary<PhaseType, IPhase>();
team1 = new BattleTeam(bCha1);
team2 = new BattleTeam(bCha2);
public BattleSimulator(BattleTeam team1, BattleTeam team2) {
battleQueue.Add(team1.battles);
battleQueue.Add(team2.battles);
battleQueue.Add(bCha1);
battleQueue.Add(bCha2);
battleQueue.Sequence();
battleQueue.OrderByDescending();
currentAction = UpdateRound;
dictionary.Add(PhaseType., new PhaseInitiative(this));
dictionary.Add(PhaseType., new PhaseAssault(this));
dictionary.Add(PhaseType., new PhaseFormal(this));
dictionary.Add(PhaseType., new PhaseAction(this));
dictionary.Add(PhaseType., new PhaseFinish(this));
}
public void Update() {
if (interval > 0) { interval -= Time.deltaTime; return; }
currentAction?.Invoke();
currentPhase?.UpdatePhase();
}
/// <summary> 更新回合 </summary>
public void UpdateRound() {
roundCount++;
battleQueue.Reset();
Debug.Log($"正式回合 {roundCount}");
interval = maxInterval;
currentAction = SelectActionTarget;
/// <summary> 阶段过渡 </summary>
public void Transition(PhaseType phaseType) {
// 检查阶段字典中是否存在指定的阶段类型
if (dictionary.TryGetValue(phaseType, out IPhase newPhase)) {
// 如果存在则更新当前阶段
currentPhase?.QuitPhase();
currentPhase = newPhase;
currentPhase?.StartPhase();
Debug.Log($"战斗阶段已转换为: {phaseType}");
}
/// <summary> 选择行动对象 </summary>
public void SelectActionTarget() {
if (!battleQueue.Current(out BattleCharacter character)) {
currentAction = UpdateRound; return;
else {
// 不存在时输出警告信息
Debug.LogWarning($"阶段字典中不存在 {phaseType} 对应的阶段实现");
}
Debug.Log($"当前 {character.name}({character.sequence}) 行动");
interval = maxInterval;
currentAction = SelectActionTarget;
}
public void SelectAttackTarget(BattleCharacter character) {
}
}
/// <summary>
/// 战斗队伍
/// </summary>
public class BattleTeam {
public List<BattleCharacter> characters;
public BattleTeam(List<BattleCharacter> characters) {
this.characters = characters;
}
}
@@ -0,0 +1,33 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 战斗队伍
/// </summary>
public class BattleTeam {
/// <summary> 队伍名字 </summary>
public string name;
/// <summary> 原始数据 </summary>
public List<DataCharacter> characters = new List<DataCharacter>();
/// <summary> 战斗数据 </summary>
public List<BattleCharacter> battles = new List<BattleCharacter>();
/// <summary> 添加角色 </summary>
public void Add(List<DataCharacter> list) {
characters.AddRange(list);
}
/// <summary> 添加角色 </summary>
public void Add(DataCharacter obj) {
characters.Add(obj);
}
/// <summary> 删除角色 </summary>
public void Remove(DataCharacter character) {
characters.Remove(character);
}
/// <summary> 战斗初始化 </summary>
public void Initial(int id) {
characters.ForEach(obj => battles.Add(new BattleCharacter(obj, id)));
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60ddd9f20d0d1bd49a6b68d86ccc904a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+25
View File
@@ -0,0 +1,25 @@
### 战斗流程示例
#### 先攻判断
- 艾薇拉(18) → 哥布林射手(15) → 托尔吉(7) → 哥布林战士(5)
#### 突袭轮
- 哥布林射手 使用短弓射击(23)对艾薇拉(AC12)造成了 5穿刺伤害
#### 正式回合1
- 艾薇拉 施放纠缠术(法术豁免DC14),哥布林射手(敏捷豁免6)被束缚
- 艾薇拉 躲至矿石掩体后(AC提升至14)
- 哥布林射手 试图挣脱藤蔓(力量豁免3)失败了
- 哥布林射手 使用多重射击,第一箭(劣势2)对托尔吉(AC14)未命中,第二箭(劣势9)对托尔吉(AC14)未命中
- 托尔吉 使用狂暴(附赠动作开启)→ 获得力量加成与抗性
- 托尔吉 移动至哥布林战士前面
- 托尔吉 使用巨斧猛击(19)对哥布林战士(AC12) 造成了 14钝击伤害
- 哥布林战士死亡
#### 正式回合2
- 艾薇拉 施放奥术飞弹(法术豁免DC14),哥布林射手(敏捷豁免6)受到了 10奥术伤害
- 哥布林射手死亡
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: dc4066f5b83586a47bc6bc8ce0115d1d
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -8,18 +8,25 @@ using MuHua;
/// </summary>
public class ManagerSimulator : ModuleSingle<ManagerSimulator> {
public List<DataCharacter> cha1 = new List<DataCharacter>();
public List<DataCharacter> cha2 = new List<DataCharacter>();
/// <summary> 队伍1 </summary>
public BattleTeam team1;
/// <summary> 队伍2 </summary>
public BattleTeam team2;
public BattleSimulator battleSimulator;
protected override void Awake() => NoReplace(false);
private void Start() {
cha1.Add(RandomCharacter("艾薇拉"));
cha1.Add(RandomCharacter("托尔吉"));
cha2.Add(RandomCharacter("哥布林射手"));
cha2.Add(RandomCharacter("哥布林战士"));
battleSimulator = new BattleSimulator(cha1, cha2);
team1 = new BattleTeam();
team1.Add(RandomCharacter("艾薇拉"));
team1.Add(RandomCharacter("托尔吉"));
team2 = new BattleTeam();
team2.Add(RandomCharacter("哥布林射手"));
team2.Add(RandomCharacter("哥布林战士"));
battleSimulator = new BattleSimulator(team1, team2);
}
private void Update() {
battleSimulator.Update();