Lietuvių

Išsamus baigtinių būsenų mašinų (FSM) vadovas žaidimų būsenų valdymui. Sužinokite apie diegimą, optimizavimą ir pažangias technikas patikimam žaidimų kūrimui.

Žaidimo būsenos valdymas: baigtinių būsenų mašinų (FSM) įvaldymas

Žaidimų kūrimo pasaulyje efektyvus žaidimo būsenos valdymas yra labai svarbus norint sukurti įtraukiančią ir nuspėjamą patirtį. Viena iš plačiausiai naudojamų ir pagrindinių technikų tam pasiekti yra baigtinių būsenų mašina (FSM). Šiame išsamiame vadove gilinsimės į FSM koncepciją, nagrinėsime jos privalumus, diegimo detales ir pažangias taikymo sritis žaidimų kūrime.

Kas yra baigtinių būsenų mašina?

Baigtinių būsenų mašina yra matematinis skaičiavimo modelis, apibūdinantis sistemą, kuri gali būti vienoje iš baigtinio skaičiaus būsenų. Sistema pereina iš vienos būsenos į kitą, reaguodama į išorinius signalus ar vidinius įvykius. Paprasčiau tariant, FSM yra dizaino šablonas, leidžiantis apibrėžti galimų būsenų rinkinį objektui (pvz., veikėjui, daiktui, pačiam žaidimui) ir taisykles, pagal kurias objektas pereina iš vienos būsenos į kitą.

Pagalvokite apie paprastą šviesos jungiklį. Jis turi dvi būsenas: ĮJUNGTA ir IŠJUNGTA. Paspaudus jungiklį (įvestis), įvyksta perėjimas iš vienos būsenos į kitą. Tai yra pagrindinis FSM pavyzdys.

Kodėl verta naudoti baigtinių būsenų mašinas žaidimų kūrime?

FSM žaidimų kūrime siūlo keletą reikšmingų privalumų, todėl yra populiarus pasirinkimas valdant įvairius žaidimo elgsenos aspektus:

Pagrindiniai baigtinių būsenų mašinos komponentai

Kiekvieną FSM sudaro šie pagrindiniai komponentai:

Baigtinių būsenų mašinos diegimas

Yra keletas būdų, kaip įdiegti FSM kode. Dažniausi metodai apima:

1. Naudojant „Enum“ ir „Switch“ sakinius

Tai paprastas ir tiesmukas metodas, ypač tinkamas pagrindinėms FSM. Jūs apibrėžiate „enum“ tipo kintamąjį, kuris atstovauja skirtingas būsenas, ir naudojate „switch“ sakinį kiekvienos būsenos logikai valdyti.

Pavyzdys (C#):


public enum CharacterState {
    Idle,
    Walking,
    Running,
    Jumping,
    Attacking
}

public class CharacterController : MonoBehaviour {
    public CharacterState currentState = CharacterState.Idle;

    void Update() {
        switch (currentState) {
            case CharacterState.Idle:
                HandleIdleState();
                break;
            case CharacterState.Walking:
                HandleWalkingState();
                break;
            case CharacterState.Running:
                HandleRunningState();
                break;
            case CharacterState.Jumping:
                HandleJumpingState();
                break;
            case CharacterState.Attacking:
                HandleAttackingState();
                break;
            default:
                Debug.LogError("Invalid state!");
                break;
        }
    }

    void HandleIdleState() {
        // Logika neveikimo būsenai
        if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.D)) {
            currentState = CharacterState.Walking;
        }
    }

    void HandleWalkingState() {
        // Logika ėjimo būsenai
        // Perėjimas į bėgimo būseną, jei paspaustas „shift“ klavišas
        if (Input.GetKey(KeyCode.LeftShift)) {
            currentState = CharacterState.Running;
        }
        // Perėjimas į neveikimo būseną, jei nepaspaustas joks judėjimo klavišas
        if (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.D)) {
            currentState = CharacterState.Idle;
        }
    }

    void HandleRunningState() {
        // Logika bėgimo būsenai
        // Perėjimas atgal į ėjimo būseną, jei atleistas „shift“ klavišas
        if (!Input.GetKey(KeyCode.LeftShift)) {
            currentState = CharacterState.Walking;
        }
    }

    void HandleJumpingState() {
        // Logika šuolio būsenai
        // Perėjimas atgal į neveikimo būseną po nusileidimo
    }

    void HandleAttackingState() {
        // Logika puolimo būsenai
        // Perėjimas atgal į neveikimo būseną po puolimo animacijos
    }
}

Privalumai:

Trūkumai:

2. Naudojant būsenų klasių hierarchiją

Šis metodas naudoja paveldėjimą, siekiant apibrėžti bazinę būsenos (State) klasę ir poklasius kiekvienai konkrečiai būsenai. Kiekvienas būsenos poklasis apima tos būsenos logiką, todėl kodas tampa tvarkingesnis ir lengviau prižiūrimas.

Pavyzdys (C#):


public abstract class State {
    public abstract void Enter();
    public abstract void Execute();
    public abstract void Exit();
}

public class IdleState : State {
    private CharacterController characterController;

    public IdleState(CharacterController characterController) {
        this.characterController = characterController;
    }

    public override void Enter() {
        Debug.Log("Entering Idle State");
    }

    public override void Execute() {
        // Logika neveikimo būsenai
        if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.D)) {
            characterController.ChangeState(new WalkingState(characterController));
        }
    }

    public override void Exit() {
        Debug.Log("Exiting Idle State");
    }
}

public class WalkingState : State {
    private CharacterController characterController;

    public WalkingState(CharacterController characterController) {
        this.characterController = characterController;
    }

    public override void Enter() {
        Debug.Log("Entering Walking State");
    }

    public override void Execute() {
        // Logika ėjimo būsenai
        // Perėjimas į bėgimo būseną, jei paspaustas „shift“ klavišas
        if (Input.GetKey(KeyCode.LeftShift)) {
            characterController.ChangeState(new RunningState(characterController));
        }
        // Perėjimas į neveikimo būseną, jei nepaspaustas joks judėjimo klavišas
        if (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.D)) {
            characterController.ChangeState(new IdleState(characterController));
        }
    }

    public override void Exit() {
        Debug.Log("Exiting Walking State");
    }
}

// ... (Kitos būsenų klasės, pvz., RunningState, JumpingState, AttackingState)

public class CharacterController : MonoBehaviour {
    private State currentState;

    void Start() {
        currentState = new IdleState(this);
        currentState.Enter();
    }

    void Update() {
        currentState.Execute();
    }

    public void ChangeState(State newState) {
        currentState.Exit();
        currentState = newState;
        currentState.Enter();
    }
}

Privalumai:

Trūkumai:

3. Naudojant būsenų mašinų resursus (vaizdinis programavimas)

Tiems, kurie mokosi vizualiai arba mėgsta mazgais paremtą metodą, žaidimų varikliuose, tokiuose kaip „Unity“ ir „Unreal Engine“, yra prieinami keli būsenų mašinų resursai (angl. assets). Šie resursai suteikia vaizdinį redaktorių būsenų mašinoms kurti ir valdyti, supaprastindami būsenų ir perėjimų apibrėžimo procesą.

Pavyzdžiai:

Šie įrankiai dažnai leidžia kūrėjams kurti sudėtingas FSM nerašant nė vienos kodo eilutės, todėl jie tampa prieinami ir dizaineriams bei menininkams.

Privalumai:

Trūkumai:

Pažangios technikos ir aspektai

Hierarchinės būsenų mašinos (HSM)

Hierarchinės būsenų mašinos praplečia pagrindinę FSM koncepciją, leisdamos būsenoms turėti įdėtas antrines būsenas. Tai sukuria būsenų hierarchiją, kurioje pirminė būsena gali apimti bendrą elgseną savo antrinėms būsenoms. Tai ypač naudinga valdant sudėtingą elgseną su bendra logika.

Pavyzdžiui, veikėjas gali turėti bendrą KOVOS būseną, kurioje yra antrinės būsenos, tokios kaip PUOLIMAS, GYNIMAS ir VENGIMAS. Perėjus į KOVOS būseną, veikėjas patenka į numatytąją antrinę būseną (pvz., PUOLIMAS). Perėjimai antrinėse būsenose gali vykti nepriklausomai, o perėjimai iš pirminės būsenos gali paveikti visas antrines būsenas.

HSM privalumai:

Būsenų dizaino šablonai

Kartu su FSM galima naudoti kelis dizaino šablonus, siekiant pagerinti kodo kokybę ir priežiūrą:

Globalios būsenos valdymas

Kai kuriais atvejais gali prireikti valdyti globalią žaidimo būseną, kuri veikia kelis objektus ar sistemas. Tai galima pasiekti sukūrus atskirą būsenų mašiną pačiam žaidimui arba naudojant globalų būsenų valdiklį, kuris koordinuoja skirtingų FSM elgseną.

Pavyzdžiui, globali žaidimo būsenų mašina gali turėti tokias būsenas kaip ĮKĖLIMAS, MENIU, ŽAIDŽIAMA ir ŽAIDIMO PABAIGA. Perėjimai tarp šių būsenų sukeltų atitinkamus veiksmus, pvz., žaidimo resursų įkėlimą, pagrindinio meniu rodymą, naujo žaidimo pradžią ar žaidimo pabaigos ekrano rodymą.

Našumo optimizavimas

Nors FSM paprastai yra efektyvios, svarbu atsižvelgti į našumo optimizavimą, ypač sudėtingoms būsenų mašinoms su dideliu būsenų ir perėjimų skaičiumi.

Įvykiais grįsta architektūra

FSM integravimas su įvykiais grįsta architektūra gali padidinti sistemos lankstumą ir reakcijos greitį. Užuot tiesiogiai tikrinus įvestis ar sąlygas, būsenos gali prenumeruoti konkrečius įvykius ir atitinkamai reaguoti.

Pavyzdžiui, veikėjo būsenų mašina gali prenumeruoti tokius įvykius kaip „GyvybesPasikeite“, „PriesasAptiktas“ arba „MygtukasPaspaustas“. Kai šie įvykiai įvyksta, būsenų mašina gali inicijuoti perėjimus į atitinkamas būsenas, tokias kaip SUŽEISTAS, PULTI arba SĄVEIKAUTI.

FSM skirtinguose žaidimų žanruose

FSM yra taikomos įvairiuose žaidimų žanruose. Štai keletas pavyzdžių:

Alternatyvos baigtinių būsenų mašinoms

Nors FSM yra galingas įrankis, jos ne visada yra geriausias sprendimas kiekvienai problemai. Alternatyvūs žaidimų būsenų valdymo metodai apima:

Pasirinkimas, kurią techniką naudoti, priklauso nuo konkrečių žaidimo reikalavimų ir valdomos elgsenos sudėtingumo.

Pavyzdžiai populiariuose žaidimuose

Nors neįmanoma žinoti tikslių kiekvieno žaidimo diegimo detalių, FSM ar jų dariniai greičiausiai plačiai naudojami daugelyje populiarių žaidimų. Štai keletas galimų pavyzdžių:

Geriausios baigtinių būsenų mašinų naudojimo praktikos

Išvada

Baigtinių būsenų mašinos yra pagrindinis ir galingas įrankis žaidimo būsenų valdymui. Suprasdami pagrindines koncepcijas ir diegimo technikas, galite sukurti tvirtesnes, nuspėjamas ir lengviau prižiūrimas žaidimų sistemas. Nesvarbu, ar esate patyręs žaidimų kūrėjas, ar tik pradedate, FSM įvaldymas ženkliai pagerins jūsų gebėjimą kurti ir įdiegti sudėtingą žaidimų elgseną.

Nepamirškite pasirinkti tinkamą diegimo metodą pagal savo konkrečius poreikius ir nebijokite tyrinėti pažangių technikų, tokių kaip hierarchinės būsenų mašinos ir įvykiais grįstos architektūros. Praktikuodamiesi ir eksperimentuodami galėsite išnaudoti FSM galią, kad sukurtumėte įtraukiančią ir įsimintiną žaidimų patirtį.