Реализация простого конечного автомата
Всякое состояние есть функция. Причем такая, что она будет вызываться при каждом обновлении кадра игры. Как уже говорилось, в activeState будет храниться указатель на функцию активного состояния. Класс Ant также содержит свойства velocity и position. Эти переменные будут использоваться для расчета движения с помощью метода Эйлера. Функция update ()вызывается при каждом обновлении кадра игры… Читать ещё >
Реализация простого конечного автомата (реферат, курсовая, диплом, контрольная)
Конечный автомат можно реализовать при помощи одного класса. Назовем его FSM. Идея состоит в том, чтобы реализовать каждое состояние как метод или функцию. Также будем использовать свойство activeState для определения активного состояния.
public class FSM {.
private var activeState: Function; // указатель на активное состояние автомата.
public function FSM () { }.
public function setState (state :Function) :void {.
activeState = state; }.
public function update () :void {.
if (activeState ≠ null) {.
activeState (); } } }.
Всякое состояние есть функция. Причем такая, что она будет вызываться при каждом обновлении кадра игры. Как уже говорилось, в activeState будет храниться указатель на функцию активного состояния.
Метод update () класса FSM должен вызываться каждый кадр игры. А он, в свою очередь, будет вызывать функцию того состояния, которое в данный момент является активным.
Метод setState () будет задавать новое активное состояние. Более того, каждая функция, определяющую какое-то состояние автомата, не обязательно должна принадлежать классу FSM — это делает наш класс более универсальным.
Использование конечного автомата
Давайте реализуем ИИ муравья. Выше мы уже показывали набор его состояний и переходов между ними. Проиллюстрируем их еще раз, но в этот раз сосредоточимся на коде.
Описание состояний интеллекта муравья, сосредоточенное на коде Наш муравей представлен классом Ant, в котором есть поле brain. Это как раз экземпляр класса FSM.
public class Ant{.
public var position: Vector3D;
public var velocity: Vector3D;
public var brain: FSM;
public function Ant (posX :Number, posY: Number) {.
position = new Vector3D (posX, posY);
velocity = new Vector3D (-1, -1);
brain = new FSM ();
// Начинаем с поиска листка.
brain.setState (findLeaf); }.
public function findLeaf () :void { }.
public function goHome () :void {.
public function runAway () :void { }.
public function update ():void {.
// Обновление конечного автомата. Эта функция будет вызывать.
// функцию активного состояния: findLeaf (), goHome () или runAway ().
brain.update ();
// Применение скорости для движения муравья.
moveBasedOnVelocity (); } (…) }.
Класс Ant также содержит свойства velocity и position. Эти переменные будут использоваться для расчета движения с помощью метода Эйлера. Функция update ()вызывается при каждом обновлении кадра игры.
Для понимания кода мы опустим реализацию метода moveBasedOnVelocity ().
Ниже приводится реализация каждого из методов, начиная с findLeaf () — состояния, ответственного за поиск листьев.
public function findLeaf () :void {.
// Перемещает муравья к листу.
velocity = new Vector3D (Game.instance.leaf.x — position. x, Game.instance.leaf.y — position. y);
if (distance (Game.instance.leaf, this) <= 10) {.
// Муравей только что подобрал листок, время.
// возвращаться домой!
brain.setState (goHome); }.
if (distance (Game.mouse, this) <= MOUSE_THREAT_RADIUS) {.
// Курсор мыши находится рядом. Бежим!
// Меняем состояние автомата на runAway ().
brain.setState (runAway); } }.
Состояние goHome () — используется для того, чтобы муравей отправился домой.
public function goHome () :void {.
// Перемещает муравья к дому.
velocity = new Vector3D (Game.instance.home.x — position. x, Game.instance.home.y — position. y);
if (distance (Game.instance.home, this) <= 10) {.
// Муравей уже дома. Пора искать новый лист.
brain.setState (findLeaf); } }.
И, наконец, состояние runAway () — используется при уворачивании от курсора мыши.
public function runAway () :void {.
// Перемещает муравья подальше от курсора.
velocity = new Vector3D (position.x — Game.mouse.x, position. y — Game.mouse.y);
// Курсор все еще рядом?
if (distance (Game.mouse, this) > MOUSE_THREAT_RADIUS) {.
// Нет, уже далеко. Пора возвращаться к поискам листочек.
brain.setState (findLeaf); } }.