public void Execute(StateMachine machine) { OnExecute(machine); StateMachine?.Execute(machine); if (BehaviourMachine != null) { machine.NodeResult = BehaviourMachine.Execute(machine); } }
public ApproachMachine() { DataStorage[PlayerPosition] = new Point(10, 10); DataStorage[GoalPosition] = new Point(0, 0); DataStorage[Switch] = false; var switchOffState = new State(); this[SwitchOff] = switchOffState; switchOffState.OnExecuteEvent = (machine, state) => { Debug.WriteLine($"SwitchOff"); if ((bool)machine.DataStorage[Switch]) { machine.NextStateName = SwitchOn; } }; var switchOnState = new State(); this[SwitchOn] = switchOnState; var behaviourMachine = new BehaviourMachine(); behaviourMachine.DataStorage.ReferTo(DataStorage, PlayerPosition); behaviourMachine.DataStorage.ReferTo(DataStorage, GoalPosition); switchOnState.OnExecuteEvent = (machine, state) => { Debug.WriteLine($"SwitchOn"); behaviourMachine.Execute(); }; var moveOrTeleportSelector = new SelectorNode(); behaviourMachine.RegisterRootNode(moveOrTeleportSelector); var moveDecorator = new DecoratorNode(); moveOrTeleportSelector.ChildNodes.Add(moveDecorator); moveDecorator.ConditionCallback = (machine, node) => { Debug.WriteLine($"move condition check"); var playerPosition = (Point)machine.DataStorage[PlayerPosition]; var goalPosition = (Point)machine.DataStorage[GoalPosition]; Debug.WriteLine($"P:{playerPosition} G:{goalPosition}"); return(!playerPosition.Equals(goalPosition)); }; var moveAction = new ActionNode(); moveDecorator.ChildNode = moveAction; moveAction.ActionCallback = (machine, node) => { Debug.WriteLine($"Move"); var playerPosition = (Point)machine.DataStorage[PlayerPosition]; var goalPosition = (Point)machine.DataStorage[GoalPosition]; var diffX = Math.Abs(playerPosition.X - goalPosition.X); var diffY = Math.Abs(playerPosition.Y - goalPosition.Y); if (diffX >= diffY) { playerPosition.X += playerPosition.X > goalPosition.X ? -1 : 1; } else { playerPosition.Y += playerPosition.Y > goalPosition.Y ? -1 : 1; } machine.DataStorage[PlayerPosition] = playerPosition; return(true); }; var teleportAction = new ActionNode(); teleportAction.DataStorage[TeleportCounter] = 10; moveOrTeleportSelector.ChildNodes.Add(teleportAction); teleportAction.ActionCallback = (machine, node) => { Debug.WriteLine($"teleport"); var teleportCounter = (int)node.DataStorage[TeleportCounter]; teleportCounter--; node.DataStorage[TeleportCounter] = teleportCounter; Debug.WriteLine($"teleport counter: {teleportCounter}"); if (teleportCounter > 0) { return(false); } var playerPosition = (Point)machine.DataStorage[PlayerPosition]; playerPosition.X = new Random().Next(-10, 10); playerPosition.Y = new Random().Next(-10, 10); machine.DataStorage[PlayerPosition] = playerPosition; node.DataStorage[TeleportCounter] = 10; Debug.WriteLine($"teleport to {playerPosition}"); return(true); }; }
public void SimpleSearcherTest() { const string hitpoint = "hp"; const string distanceToTower = "distance"; var machine = new BehaviourMachine(); machine.DataStorage[hitpoint] = 100; machine.DataStorage[distanceToTower] = 10; machine.OnExecuteEvent += (m) => { var hp = (int)m.DataStorage[hitpoint]; var distance = (int)m.DataStorage[distanceToTower]; Debug.WriteLine($"HP: {hp}"); Debug.WriteLine($"Distance: {distance}"); }; var selector = new SelectorNode(); machine.RegisterRootNode(selector); var decoratorHp = new DecoratorNode(); selector.ChildNodes.Add(decoratorHp); decoratorHp.ConditionCallback = (m, n) => m.DataStorage.GetValue <int>(hitpoint) > 5; var attackNearEnemy = new ActionNode(); attackNearEnemy.ActionCallback = (m, n) => { Debug.WriteLine("近くの敵を攻撃"); var distance = (int)m.DataStorage[distanceToTower]; distance += 1; m.DataStorage[distanceToTower] = distance; var hp = (int)m.DataStorage[hitpoint]; hp -= 5; m.DataStorage[hitpoint] = hp; return(true); }; decoratorHp.ChildNode = attackNearEnemy; var sequencer = new SequencerNode(); selector.ChildNodes.Add(sequencer); var moveToNearTower = new ActionNode(); sequencer.ChildNodes.Add(moveToNearTower); moveToNearTower.ActionCallback = (m, n) => { var distance = (int)m.DataStorage[distanceToTower]; if (distance <= 0) { return(true); } Debug.WriteLine("近くのタワーに移動"); distance--; m.DataStorage[distanceToTower] = distance; return(true); }; var wait = new ActionNode(); sequencer.ChildNodes.Add(wait); wait.ActionCallback = (m, n) => { Debug.WriteLine("待機"); var distance = (int)m.DataStorage[distanceToTower]; if (distance < 5) { var hp = (int)m.DataStorage[hitpoint]; hp += 20; m.DataStorage[hitpoint] = hp; } return(true); }; for (var i = 0; i < 100; i++) { machine.Execute(); } }