STDIO
Tìm kiếm gần đây
    • Nội dung
    • QR Code
    • 0
    • 0
    • Sao chép

    Trí Tuệ Nhân Tạo Trong Games - Phần 2: Thiết Kế AI Với FSM

    Hướng dẫn thiết kế AI với FSM sử dụng framework Cocos2d-x.
    23/01/2015
    28/09/2020
    4 phút đọc
    Trí Tuệ Nhân Tạo Trong Games - Phần 2: Thiết Kế AI Với FSM

    Nâng cấp AI với FSM từ bài viết trước để:

    • Dễ sửa chữa, bảo trì, thêm trạng thái.
    • Giảm thời gian xử lý.

    Thiết kế State

    Class State

    Header:

    // State.h  
    //  
    #ifndef __State_h__
    #define __State_h__
      
    class Monkey;  
      
    template <class entity_type>
    
    class State {
    public:
        virtual ~State() {}
    
        //hàm này sẽ được thực hiện khi state được nhập
        virtual void Enter(entity_type*) = 0;
    
        //đây là hàm update của state
        virtual void Execcute(entity_type*) = 0;
    
        //hàm này sẽ thực hiện khi state đã thoát để chuyển state   
        virtual void Exit(entity_type*) = 0;
    };  
      
    #endif // __State_h__

    Các trạng thái của Monkey bao gồm stop, walk, và turn sẽ kế thừa từ class State. Với việc thiết kế mỗi trạng thái của AI là 1 class State, việc bảo trì, sữa chữa, hay thêm 1 trạng thái cho AI sẽ tốt hơn rất nhiều vì:

    • Các đoạn code của trạng thái không liên quan gì tới các đoạn code của trạng thái khác.
    • Dễ dàng tìm đến nơi muốn sửa chữa hay bảo trì.
    • Nếu muốn thêm 1 trạng thái cho AI chỉ việc tạo ra 1 trạng thái mới cho AI được kết thừa từ class State.

    Vòng đời của 1 trạng thái của AI là:

    • Enter.
    • Execcute.
    • Exit.

    Monkey states

    Header

    #ifndef __Monkey_State_h__
    #define __Monkey_State_h__
    
    #include "State.h"
    
    class Monkey
    
    class Stop: public State<Monkey> {
    private:
        Stop(){}
      
        Stop(const Stop&);
        Stop& operator=(const Stop&);
    
    protected: 
    public:
        static EnterMineAndDigForNugget* Instance();
      
        virtual void Enter(Monkey* _monkey);
        virtual void Execute(Monkey* _monkey);
        virtual void Exit(Monkey* _monkey);
    };
    
    class Walk: public State<Monkey> {
    private:
        Walk(){}
    
        Walk(const Walk&);
        Walk& operator=(const Walk&);
     
    protected:
    public:
        static Walk* Instance();
    
        virtual void Enter(Monkey* _monkey);
        virtual void Execute(Monkey* _monkey);
        virtual void Exit(Monkey* _monkey);
    };
    
    class Turn: public State<Monkey> {
    private:
        Turn(){}
    
        Turn(const Turn&);
        Turn& operator=(const Turn&);
     
    protected:
    public:
        static Turn* Instance();
    
        virtual void Enter(Monkey* _monkey);
        virtual void Execute(Monkey* _monkey);
        virtual void Exit(Monkey* _monkey);
    };
    
    #endif // __Monkey_State_h__

    Source

    #include "MonkeyState.h"
    #include "State.h"
    #include "Monkey.h"
    
    //********************Stop*****************************
    
    Stop* Stop::Instance() {
    
        static Stop instance;
    
        return &instance;
    }
    
    void Stop::Enter(Monkey* _monkey) {}
    
    void Stop::Execute(Monkey* _monkey) {  
    
        if (_monkey->isStopTimeout())
            _monkey->GetFSM()->ChangeState(stWALK::Instance());
    }
    
    void Stop::Exit(Monkey* _monkey) {}
    
    //*****************************************************
    
    //*******************Walk******************************
    
    Walk* Walk::Instance() {
    
        static Walk instance;
    
        return &instance;
    }
    
    void Walk::Enter(Monkey* _monkey) {}
    
    void Walk::Execute(Monkey* _monkey) {
    
        pMiner->walk();  
        
        if (_monkey->isWalkOutBorder())
            _monkey->GetFSM()->ChangeState(Turn::Instance());      
    
        else if (_monkey->isWalkTimeout())
            _monkey->GetFSM()->ChangeState(Stop::Instance());      
    }
    
    void Walk::Exit(Monkey* _monkey) {}
    
    //*****************************************************
    
    //*********************Turn****************************
    
    Turn* Turn::Instance() {
    
        static Turn instance;
    
        return &instance;
    }
    
    void Turn::Enter(Monkey* _monkey) {}
    
    void Turn::Execute(Monkey* _monkey) { 
    
        _monkey->turn();
        _monkey->GetFSM()->ReVertToPriviousState();
    }
    
    void Turn::Exit(Monkey* _monkey) {}
    
    //*****************************************************
    

    State Machine

    Bây giờ cần 1 FSM có nhiệm vụ chạy trạng thái hiện tại và chuyển trạng thái của AI.

    Header

    #ifndef __State_Machine_h__
    #define __State_Machine_h__
    
    #include "State.h"
    
    template <class entity_type>
    
    class StateMachine {
    public:
        StateMachine(entity_type* m_Owner):m_pOwner(m_Owner),
                                       m_pCurrentState(NULL),
                                       m_pPreviousState(NULL),
        {}
    
        virtual ~StateMachine(){}
    
        void SetCurrentState(State<entity_type>* _state){m_pCurrentState = _state;}
        void SetPreviousState(State<entity_type>* _state){m_pPreviousState = _state;}
      
        void  Update() const {
            m_pCurrentState->Execute(m_pOwner);
        }
    
        void  ChangeState(State<entity_type>* _newState) {
        
            m_pPreviousState = m_pCurrentState;
    
            m_pCurrentState->Exit(m_pOwner);
            m_pCurrentState = _newState;
            m_pCurrentState->Enter(m_pOwner);
        }
    
        void RevertToPreviousState() {
            ChangeState(m_pPreviousState);
        }
    
        State<entity_type>*  CurrentState()  const{return m_pCurrentState;}
        State<entity_type>*  PreviousState() const{return m_pPreviousState;}
    protected:
    private:
        entity_type* m_pOwner;
        
        State<entity_type>* m_pCurrentState;
        State<entity_type>* m_pPreviousState; 
    };
    
    #endif // __State_Machine_h__

    Với class StateMachine ở trên chỉ cần thật sự chú ý những điều sau:

    • Trạng thái hiện tại của AI là m_pCurrentState
    • Trạng thái trước đó của AI là m_pPreviosState

    Monkey

    Header

    #ifndef __Monkey_h__
    #define __Monkey_h__
      
    #include <time.h>  
    #include "StateMachine.h"
    #include "State.h"
    #include "MonkeyState.h"
      
    #include "cocos2d.h"  
    USING_NS_CC;   
      
    #define MAX_STOP_TIME  10  
    #define MAX_WALK_TIME  20  
      
    #define MAX_WALK_DIST  100  
        
    class Monkey : public Node {  
    public:
        Monkey()  {  
            log("Monkey()");  
        }  
    
        ~Monkey() {
            delete m_monkeyFSM;
        }
      
        CREATE_FUNC(Monkey);  
        
        virtual bool init() {  
            _curPos = 0;  
            _step = 1;  
            
            m_monkeyFSM = new StateMachine<Monkey>(this);
            m_monkeyFSM->SetCurrentState(Stop::Instance());
      
            this->scheduleUpdate();  
      
            return true;  
        }  
      
        void stop() {  
            cocos2d::log("stop()");  
        }  
      
        void walk() {  
            _curPos += _step;  
            cocos2d::log("walk(): pos=%d", _curPos);  
        }  
      
        void turn() {  
            _step *= -1;  
            cocos2d::log("turn(): step=%d", _step);          
        }  
      
        void update(float dt) {  
             m_monkeyFSM->update();
        }  
      
     
    protected: 
    private:  
        StateMachine * m_monkeyFSM;  
      
        time_t _curTime;  
      
        int      _curPos;  
        int      _step;  
        
    public:  
        bool isStopTimeout() {  
            return (time(0) - _curTime > MAX_STOP_TIME);  
        }  
       
        bool isWalkTimeout() {  
            return (time(0) - _curTime > MAX_WALK_TIME);  
        }  
      
        bool isWalkOutBorder() {  
            return (_curPos > MAX_WALK_DIST || _curPos < -MAX_WALK_DIST);  
        }  
    };  
      
    #endif // __Monkey_h__

    Trong class Monkey lúc này gồm có:

    • Monkey FSM: Là FSM dùng để chuyển qua lại giữa các trạng thái stop, walk, turn và execcute trạng thái hiện tại của Monkey
    • Các sự kiện và quy luật.

    Tham khảo

    Bài chung series

    0
    Lập Trình Game

    Lập Trình Game

    Kiến thức, kỹ thuật, kinh nghiệm lập trình game.

    Khi bạn nhấn vào liên kết sản phẩm do STDIO đề xuất và mua hàng, STDIO có thể nhận được hoa hồng. Điều này hỗ trợ STDIO tạo thêm nhiều nội dung hữu ích.. Tìm hiểu thêm.

    Đề xuất

    Trí Tuệ Nhân Tạo trong Games - Phần 1: Thiết Kế AI với FSM
    Khái niệm, vai trò của trí tuệ nhân tạo trong games và hiện thực một AI ...

    Khám phá

    Hiện Thực Game Zero Với Unity - Phần 4 - Scene Và Popup
    Hướng Dẫn Hiện Thực Game Zero Với Unity. Thiết kế hệ thống scene và ...
    UI - Phần 2: Thiết Kế UI Trong Cocos2d-x 3.x.x
    Tìm hiểu về một số đối tượng dùng để thiết kế UI trong Cocos2d-x.
    Thành Phần Hoá Các Đối Tượng Trong Game Với Cocos2d-x
    Hướng dẫn thành phần hoá các đối tượng trong game với Cocos2d-x
    Hiện Thực Game Zero Với Unity - Phần 1 - Nhận Sự Kiện Button
    Hướng Dẫn Hiện Thực Game Zero Với Unity. Thiết lập môi trường phát triển ...
    Phát Triển Game Funny Halloween Pumpkins với Cocos2d-x - Phần 1
    Hướng dẫn làm game cụ thể bằng Cocos2d-x với code mẫu và game mẫu.
    Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 8: Hiện thực GameScene - Xử lý sự kiện trong game
    Hướng dẫn cách nhận các sự kiện từ người chơi và xử lý chúng theo logic ...
    CBP-8: Component Điều Khiển và AI – Component Ra Lệnh
    Component ra lệnh - các Component có khả năng gửi Entity Command cho ...
    Cách Thiết Kế Bản Cắt Móc Khóa Mica Hoàn Chỉnh
    Bài viết hướng dẫn bạn cách thức tạo ra 1 bản thiết kế chuẩn gửi cho nhà ...
    30/06/2020
    STDIO
    Trang chính
    Công ty TNHH STDIO

    30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
    +84 28.36205514 - +84 942.111912
    developer@stdio.vn

    383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
    Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012

    ©STDIO, 2013 - 2020