【JAVA】状态机的一个应用示例2

发布时间:2024年01月03日

在红警游戏里有菜单切换,基于状态机写了下大概的代码,不过不太确定代码对不对。。。。

?

?

?

?

import java.util.AbstractMap;
import java.util.Comparator;
import java.util.TreeMap;

//游戏页面一共有多少状态
class State
{
    public final static int MainMenu = 1; //主菜单
    public final static int SinglePlayer = 2; // 单人游戏
    public final static int Encounter = 3; // 遭遇战
    public final static int GameStarted = 4; // 游戏已启动
    public final static int Exit = 5; // 退出游戏
}

//在不同游戏页面的时候,有哪些用户可以输入的事件
class Input{
    //主菜单页面
    public final static int MainMenu_Single = 11;
    public final static int MainMenu_Exit = 12;

    //单人游戏页面
    public final static int Single_NewCampaign = 21; //新战役
    public final static int Single_Load = 22; // 加载历史存档
    public final static int Single_Enconter = 23; //遭遇战
    public final static int Single_MainMenu = 24; //返回主菜单


    //遭遇战页面
    public final static int Enconter_StartGame = 31; //开始游戏
    public final static int Enconter_MapSet = 32; //地图设置
    public final static int Enconter_LastPage = 31; //返回上一页
}

//用于记录当前游戏的状态和用户的输入
class Record{
    public int currentState;
    public int input;

    public Record(int currentState, int input) {
        this.currentState = currentState;
        this.input = input;
    }
}

//页面的基类,比如,可以从JFrame继承,这样都有画面
class Base
{
    String name;
    Base(String name)
    {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

//游戏主菜单页面,正常来说,上边会有很多按钮
class Main extends Base
{
    Main()
    {
        super("Main");
    }
}

//单人游戏菜单,正常来说,上边会有很多按钮
class Single extends Base
{
    Single()
    {
        super("Single");
    }
}

//遭遇战菜单页面,正常来说,上边会有很多按钮
class Enconter extends Base
{
    Enconter()
    {
        super("Enconter");
    }
}

//已经开始游戏页面,正常来说,上边会有玩家、坦克、军队等等
class Game extends Base
{
    Game()
    {
        super("Game started");
    }
}

//地图设置菜单页面,正常来说,上边会有很多按钮
class Map extends Base
{
    Map()
    {
        super("Map");
    }
}

//根据状态机当前状态以及用户输入,通过查找treeMap返回的新的状态,以及一个页面的类。
class Result
{
    int newState;
    Base base;

    public Result(int newState, Base base) {
        this.newState = newState;
        this.base = base;
    }
}

public class FSM
{
    public TreeMap<Record, Result> treeMap;
    int CurrentState;
    Base CurrentPage;

    FSM()
    {
        //游戏开始运行时,会在第一个主菜单页面
        CurrentState = State.MainMenu;

        //重写了下比较器,为了把当前状态和用户的输入作为Map的key参数
        treeMap = new TreeMap<>(new Comparator<Record>() {
            @Override
            public int compare(Record record1, Record record2) {
                if (record1.currentState != record2.currentState)
                {
                    return record1.currentState - record2.currentState;
                }
                else if (record1.input != record2.input)
                {
                    return record1.input - record2.input;
                }
                else
                {
                    return 0;
                }
            }
        });

        /**
         *这里是把状态机初始化,当前只添加了三行:
         * 1、第一行是从主菜单页面跳转到单人模式菜单页面;
         * 2、第二行是从单人模式菜单页面跳转到遭遇战菜单页面;
         * 3、第三行是从遭遇战菜单页面跳转到开始游戏遭遇战菜单页面;
         * 这里实际上可以根据菜单的多少可以添加和删除。
         */

        treeMap.put(new Record(State.MainMenu,     Input.MainMenu_Single),    new Result(State.SinglePlayer, new Single()));
        treeMap.put(new Record(State.SinglePlayer, Input.Single_Enconter),    new Result(State.Encounter, new Enconter()));
        treeMap.put(new Record(State.Encounter,    Input.Enconter_StartGame), new Result(State.GameStarted, new Game()));
    }

    public AbstractMap<Record,Result> getTreeMap() {
        return treeMap;
    }

    public void setTreeMap(TreeMap<Record, Result> treeMap) {
        this.treeMap = treeMap;
    }

    public Base getCurrentPage() {
        return CurrentPage;
    }

    public void setCurrentPage(Base currentPage) {
        CurrentPage = currentPage;
    }

    public int getCurrentState() {
        return CurrentState;
    }

    public void setCurrentState(int currentState) {
        CurrentState = currentState;
    }

    //状态机的运行,比如:当用户进入游戏,首先会在主菜单,当用户不断输入的时候,这里会不断的切换当前页面
    public void Run(int Input)
    {
        //基于当前状态和用户的输入,看用户输入是否合法,如果合法则进行状态切换
        Result result = treeMap.get(new Record(getCurrentState(), Input));
        if (result != null)
        {
            //如果合法则切换新的状态,并把对应页面的类返回
            setCurrentState(result.newState);
            setCurrentPage(result.base);
            System.out.println(result.base.getName());
        }
    };

    public static void main(String[] args) {
        FSM fsm = new FSM();
        fsm.Run(Input.MainMenu_Single);

        fsm.Run(Input.Single_Enconter);

        fsm.Run(Input.Enconter_StartGame);
    }
}

文章来源:https://blog.csdn.net/r77683962/article/details/135356948
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。