新增角色状态机框架,包含空闲、移动、跳跃、攻击等状态 添加输入路由组件,统一处理键盘和手柄输入 引入动作库管理角色动作定义,支持PVF脚本配置 重构角色对象,整合运动器、状态机和输入处理 修复Actor子节点排序时的迭代安全问题
225 lines
6.5 KiB
C++
225 lines
6.5 KiB
C++
#pragma once
|
|
|
|
#include <frostbite2D/base/RefObject.h>
|
|
#include <frostbite2D/types/type_alias.h>
|
|
#include <frostbite2D/types/type_math.h>
|
|
#include <frostbite2D/types/uuid.h>
|
|
#include <frostbite2D/utils/intrusive_list.hpp>
|
|
#include <frostbite2D/event/event.h>
|
|
#include <frostbite2D/event/key_event.h>
|
|
#include <frostbite2D/event/mouse_event.h>
|
|
#include <frostbite2D/event/touch_event.h>
|
|
#include <frostbite2D/event/joystick_event.h>
|
|
#include <frostbite2D/event/window_event.h>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <functional>
|
|
#include <unordered_map>
|
|
|
|
namespace frostbite2D {
|
|
|
|
class Actor;
|
|
class Scene;
|
|
|
|
using ActorList = IntrusiveList<RefPtr<Actor>>;
|
|
|
|
class Actor : public RefObject, protected IntrusiveListValue<RefPtr<Actor>> {
|
|
public:
|
|
using IntrusiveListValue<RefPtr<Actor>>::GetNext;
|
|
using IntrusiveListValue<RefPtr<Actor>>::GetPrev;
|
|
|
|
Actor();
|
|
virtual ~Actor();
|
|
|
|
virtual void Update(float deltaTime);
|
|
virtual void Render();
|
|
virtual void OnUpdate(float deltaTime) {}
|
|
virtual void OnAdded(Actor* parent) {}
|
|
|
|
void AddChild(RefPtr<Actor> child);
|
|
void RemoveChild(RefPtr<Actor> child);
|
|
void RemoveAllChildren();
|
|
|
|
Actor* GetParent() const { return parent_; }
|
|
Scene* GetScene() const { return scene_; }
|
|
|
|
const std::string& GetName() const { return name_; }
|
|
void SetName(const std::string& name) { name_ = name; }
|
|
|
|
const UUID& GetUUID() const { return uuid_; }
|
|
std::string GetUUIDString() const { return uuid_.toString(); }
|
|
|
|
/**
|
|
* @brief 获取锚点在父坐标系中的位置
|
|
*/
|
|
const Vec2& GetPosition() const { return position_; }
|
|
/**
|
|
* @brief 设置锚点在父坐标系中的位置
|
|
*/
|
|
void SetPosition(const Vec2& pos);
|
|
void SetPosition(float x, float y);
|
|
|
|
float GetRotation() const { return rotation_; }
|
|
void SetRotation(float rotation);
|
|
|
|
const Vec2& GetScale() const { return scale_; }
|
|
void SetScale(const Vec2& scale);
|
|
void SetScale(float scale);
|
|
|
|
const Transform2D& GetLocalTransform() const;
|
|
const Transform2D& GetWorldTransform() const;
|
|
|
|
const Vec2& GetSize() const { return size_; }
|
|
void SetSize(const Vec2& size);
|
|
void SetSize(float width, float height);
|
|
|
|
/**
|
|
* @brief 获取归一化锚点,(0, 0) 为左上角,(0.5, 0.5) 为中心
|
|
*/
|
|
const Vec2& GetAnchor() const { return anchor_; }
|
|
/**
|
|
* @brief 设置归一化锚点,不会自动补偿 position
|
|
*/
|
|
void SetAnchor(const Vec2& anchor);
|
|
void SetAnchor(float x, float y);
|
|
|
|
/**
|
|
* @brief 获取未旋转矩形左上角在父坐标系中的位置
|
|
*/
|
|
Vec2 GetTopLeftPosition() const;
|
|
/**
|
|
* @brief 设置未旋转矩形左上角在父坐标系中的位置
|
|
*/
|
|
void SetTopLeftPosition(const Vec2& pos);
|
|
void SetTopLeftPosition(float x, float y);
|
|
|
|
bool IsVisible() const { return visible_; }
|
|
void SetVisible(bool visible) { visible_ = visible; }
|
|
|
|
int GetZOrder() const { return zOrder_; }
|
|
void SetZOrder(int zOrder);
|
|
|
|
float GetOpacity() const { return opacity_; }
|
|
void SetOpacity(float opacity);
|
|
float GetWorldOpacity() const;
|
|
|
|
ActorList& GetChildren() { return children_; }
|
|
const ActorList& GetChildren() const { return children_; }
|
|
|
|
bool IsEventReceiveEnabled() const { return eventReceiveEnabled_; }
|
|
void EnableEventReceive() { eventReceiveEnabled_ = true; }
|
|
void DisableEventReceive() { eventReceiveEnabled_ = false; }
|
|
|
|
int32 GetEventPriority() const { return eventPriority_; }
|
|
void SetEventPriority(int32 priority) { eventPriority_ = priority; }
|
|
|
|
bool IsEventInterceptEnabled() const { return eventInterceptEnabled_; }
|
|
void EnableEventIntercept() { eventInterceptEnabled_ = true; }
|
|
void DisableEventIntercept() { eventInterceptEnabled_ = false; }
|
|
|
|
enum class UpdatePhase {
|
|
BeforeChildren,
|
|
AfterChildren
|
|
};
|
|
|
|
using UpdateCallback = Function<void(Actor&, float)>;
|
|
using EventCallback = std::function<bool(const Event&)>;
|
|
|
|
uint32 AddUpdateListener(UpdateCallback callback,
|
|
UpdatePhase phase = UpdatePhase::BeforeChildren);
|
|
bool RemoveUpdateListener(uint32 listenerId);
|
|
void ClearUpdateListeners();
|
|
|
|
uint32 AddEventListener(EventType type, EventCallback callback);
|
|
bool RemoveEventListener(uint32 listenerId);
|
|
void ClearEventListeners();
|
|
|
|
virtual bool OnEvent(const Event& event);
|
|
|
|
virtual bool OnKeyDown(const KeyEvent& event);
|
|
virtual bool OnKeyUp(const KeyEvent& event);
|
|
virtual bool OnMouseDown(const MouseEvent& event);
|
|
virtual bool OnMouseUp(const MouseEvent& event);
|
|
virtual bool OnMouseMove(const MouseEvent& event);
|
|
virtual bool OnMouseWheel(const MouseEvent& event);
|
|
virtual bool OnTouchDown(const TouchEvent& event);
|
|
virtual bool OnTouchUp(const TouchEvent& event);
|
|
virtual bool OnTouchMove(const TouchEvent& event);
|
|
virtual bool OnJoystickAxis(const JoystickEvent& event);
|
|
virtual bool OnJoystickButtonDown(const JoystickEvent& event);
|
|
virtual bool OnJoystickButtonUp(const JoystickEvent& event);
|
|
virtual bool OnWindowResize(const WindowEvent& event);
|
|
|
|
bool DispatchEvent(const Event& event);
|
|
bool BubbleEvent(const Event& event);
|
|
|
|
protected:
|
|
void SetParent(Actor* parent) { parent_ = parent; }
|
|
void SetScene(Scene* scene) { scene_ = scene; }
|
|
|
|
void insertChildByZOrder(RefPtr<Actor> child);
|
|
void UpdateChildren(float deltaTime);
|
|
void RenderChildren();
|
|
|
|
virtual void OnTransformChanged() {};
|
|
|
|
private:
|
|
void markChildrenOrderDirty();
|
|
void reorderChildrenByZOrder();
|
|
|
|
Actor* parent_;
|
|
Scene* scene_;
|
|
ActorList children_;
|
|
|
|
UUID uuid_;
|
|
std::string name_;
|
|
Vec2 position_;
|
|
float rotation_;
|
|
Vec2 scale_ = Vec2(1.0f, 1.0f);
|
|
Vec2 size_;
|
|
Vec2 anchor_;
|
|
bool visible_;
|
|
int zOrder_;
|
|
float opacity_;
|
|
|
|
mutable Transform2D localTransform_;
|
|
mutable Transform2D worldTransform_;
|
|
mutable bool transformDirty_ = true;
|
|
|
|
bool eventReceiveEnabled_ = false;
|
|
int32 eventPriority_ = 0;
|
|
bool eventInterceptEnabled_ = false;
|
|
|
|
struct UpdateListener {
|
|
uint32 id;
|
|
UpdatePhase phase;
|
|
UpdateCallback callback;
|
|
bool active = true;
|
|
};
|
|
std::vector<UpdateListener> updateListeners_;
|
|
uint32 nextUpdateListenerId_ = 1;
|
|
bool iteratingUpdateListeners_ = false;
|
|
bool updateListenersDirty_ = false;
|
|
bool iteratingChildren_ = false;
|
|
bool childrenOrderDirty_ = false;
|
|
|
|
struct EventListener {
|
|
uint32 id;
|
|
EventType type;
|
|
EventCallback callback;
|
|
};
|
|
std::vector<EventListener> eventListeners_;
|
|
uint32 nextListenerId_ = 1;
|
|
|
|
void markTransformDirty();
|
|
void updateLocalTransform() const;
|
|
void updateWorldTransform() const;
|
|
void executeUpdateListeners(UpdatePhase phase, float deltaTime);
|
|
void compactUpdateListeners();
|
|
|
|
friend class Scene;
|
|
};
|
|
|
|
}
|
|
|