refactor(renderer): 重构渲染器模块结构
将渲染器相关代码从graphics目录移动到renderer目录,包括Camera、Renderer等核心类 删除过渡动画相关代码,简化场景切换逻辑 移除Tween动画系统,减少代码复杂度 重命名ShapeNode为Shape,保持命名一致性 更新所有引用路径以反映新的目录结构
This commit is contained in:
parent
f41600306e
commit
e52c117830
|
|
@ -1,73 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <core/math_types.h>
|
||||
#include <core/types.h>
|
||||
#include <graphics/texture.h>
|
||||
#include <string>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
// ============================================================================
|
||||
// SpriteFrame - 精灵帧(纹理 + 区域 + 偏移的中间抽象)
|
||||
// 借鉴 Cocos2d-x SpriteFrame:解耦纹理物理存储与逻辑帧
|
||||
// 一个纹理图集可包含多个 SpriteFrame,减少纹理切换提升渲染性能
|
||||
// ============================================================================
|
||||
class SpriteFrame {
|
||||
public:
|
||||
SpriteFrame() = default;
|
||||
|
||||
SpriteFrame(Ptr<Texture> texture, const Rect &rect)
|
||||
: texture_(std::move(texture)), rect_(rect), originalSize_(rect.size) {}
|
||||
|
||||
SpriteFrame(Ptr<Texture> texture, const Rect &rect, const Vec2 &offset,
|
||||
const Size &originalSize)
|
||||
: texture_(std::move(texture)), rect_(rect), offset_(offset),
|
||||
originalSize_(originalSize) {}
|
||||
|
||||
// ------ 静态创建 ------
|
||||
static Ptr<SpriteFrame> create(Ptr<Texture> texture, const Rect &rect) {
|
||||
return makePtr<SpriteFrame>(std::move(texture), rect);
|
||||
}
|
||||
|
||||
static Ptr<SpriteFrame> create(Ptr<Texture> texture, const Rect &rect,
|
||||
const Vec2 &offset, const Size &originalSize) {
|
||||
return makePtr<SpriteFrame>(std::move(texture), rect, offset, originalSize);
|
||||
}
|
||||
|
||||
// ------ 纹理信息 ------
|
||||
void setTexture(Ptr<Texture> texture) { texture_ = std::move(texture); }
|
||||
Ptr<Texture> getTexture() const { return texture_; }
|
||||
|
||||
// ------ 矩形区域(在纹理图集中的位置)------
|
||||
void setRect(const Rect &rect) { rect_ = rect; }
|
||||
const Rect &getRect() const { return rect_; }
|
||||
|
||||
// ------ 偏移(图集打包时的裁剪偏移)------
|
||||
void setOffset(const Vec2 &offset) { offset_ = offset; }
|
||||
const Vec2 &getOffset() const { return offset_; }
|
||||
|
||||
// ------ 原始尺寸(裁剪前的完整尺寸)------
|
||||
void setOriginalSize(const Size &size) { originalSize_ = size; }
|
||||
const Size &getOriginalSize() const { return originalSize_; }
|
||||
|
||||
// ------ 旋转标志(图集工具可能旋转90度)------
|
||||
void setRotated(bool rotated) { rotated_ = rotated; }
|
||||
bool isRotated() const { return rotated_; }
|
||||
|
||||
// ------ 名称(用于缓存索引)------
|
||||
void setName(const std::string &name) { name_ = name; }
|
||||
const std::string &name() const { return name_; }
|
||||
|
||||
// ------ 有效性检查 ------
|
||||
bool isValid() const { return texture_ != nullptr; }
|
||||
|
||||
private:
|
||||
Ptr<Texture> texture_;
|
||||
Rect rect_;
|
||||
Vec2 offset_;
|
||||
Size originalSize_;
|
||||
bool rotated_ = false;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <animation/sprite_frame.h>
|
||||
#include <graphics/texture.h>
|
||||
#include <mutex>
|
||||
#include <resource/resource_manager.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utils/logger.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
// ============================================================================
|
||||
// SpriteFrameCache - 精灵帧全局缓存(借鉴 Cocos SpriteFrameCache)
|
||||
// 全局单例管理所有精灵帧,避免重复创建,支持图集自动切割
|
||||
// ============================================================================
|
||||
class SpriteFrameCache {
|
||||
public:
|
||||
static SpriteFrameCache &getInstance() {
|
||||
static SpriteFrameCache instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
// ------ 添加帧 ------
|
||||
|
||||
/// 添加单个精灵帧
|
||||
void addSpriteFrame(Ptr<SpriteFrame> frame, const std::string &name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
frames_[name] = std::move(frame);
|
||||
}
|
||||
|
||||
/// 从纹理和矩形区域创建并添加帧
|
||||
void addSpriteFrameFromTexture(Ptr<Texture> texture, const Rect &rect,
|
||||
const std::string &name) {
|
||||
auto frame = SpriteFrame::create(std::move(texture), rect);
|
||||
frame->setName(name);
|
||||
addSpriteFrame(std::move(frame), name);
|
||||
}
|
||||
|
||||
/// 从纹理图集批量切割添加(等宽等高网格)
|
||||
void addSpriteFramesFromGrid(const std::string &texturePath, int frameWidth,
|
||||
int frameHeight, int frameCount = -1,
|
||||
int spacing = 0, int margin = 0) {
|
||||
auto texture = loadTextureFromFile(texturePath);
|
||||
if (!texture)
|
||||
return;
|
||||
addSpriteFramesFromGrid(texture, texturePath, frameWidth, frameHeight,
|
||||
frameCount, spacing, margin);
|
||||
}
|
||||
|
||||
/// 从纹理对象批量切割添加(等宽等高网格,无需走 TexturePool)
|
||||
void addSpriteFramesFromGrid(Ptr<Texture> texture,
|
||||
const std::string &keyPrefix, int frameWidth,
|
||||
int frameHeight, int frameCount = -1,
|
||||
int spacing = 0, int margin = 0) {
|
||||
if (!texture)
|
||||
return;
|
||||
|
||||
int texW = texture->width();
|
||||
int texH = texture->height();
|
||||
int usableW = texW - 2 * margin;
|
||||
int usableH = texH - 2 * margin;
|
||||
int cols = (usableW + spacing) / (frameWidth + spacing);
|
||||
int rows = (usableH + spacing) / (frameHeight + spacing);
|
||||
int total = (frameCount > 0) ? frameCount : cols * rows;
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
for (int i = 0; i < total; ++i) {
|
||||
int col = i % cols;
|
||||
int row = i / cols;
|
||||
if (row >= rows)
|
||||
break;
|
||||
|
||||
Rect rect(static_cast<float>(margin + col * (frameWidth + spacing)),
|
||||
static_cast<float>(margin + row * (frameHeight + spacing)),
|
||||
static_cast<float>(frameWidth),
|
||||
static_cast<float>(frameHeight));
|
||||
|
||||
std::string name = keyPrefix + "#" + std::to_string(i);
|
||||
auto frame = SpriteFrame::create(texture, rect);
|
||||
frame->setName(name);
|
||||
frames_[name] = std::move(frame);
|
||||
}
|
||||
}
|
||||
|
||||
// ------ 获取帧 ------
|
||||
|
||||
/// 按名称获取
|
||||
Ptr<SpriteFrame> getSpriteFrame(const std::string &name) const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = frames_.find(name);
|
||||
if (it != frames_.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// 通过路径+索引获取或创建(ANI 格式的定位方式)
|
||||
Ptr<SpriteFrame> getOrCreateFromFile(const std::string &texturePath,
|
||||
int index = 0) {
|
||||
std::string key = texturePath + "#" + std::to_string(index);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = frames_.find(key);
|
||||
if (it != frames_.end())
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// 缓存未命中,加载纹理并创建 SpriteFrame
|
||||
auto texture = loadTextureFromFile(texturePath);
|
||||
if (!texture)
|
||||
return nullptr;
|
||||
|
||||
// 默认整张纹理作为一帧(index=0),或用整张纹理
|
||||
Rect rect(0.0f, 0.0f, static_cast<float>(texture->width()),
|
||||
static_cast<float>(texture->height()));
|
||||
|
||||
auto frame = SpriteFrame::create(texture, rect);
|
||||
frame->setName(key);
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
frames_[key] = frame;
|
||||
return frame;
|
||||
}
|
||||
|
||||
// ------ 缓存管理 ------
|
||||
|
||||
bool has(const std::string &name) const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return frames_.find(name) != frames_.end();
|
||||
}
|
||||
|
||||
void removeSpriteFrame(const std::string &name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
frames_.erase(name);
|
||||
}
|
||||
|
||||
/// 移除未被外部引用的精灵帧(use_count == 1 表示仅缓存自身持有)
|
||||
void removeUnusedSpriteFrames() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
for (auto it = frames_.begin(); it != frames_.end();) {
|
||||
if (it->second.use_count() == 1) {
|
||||
it = frames_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
frames_.clear();
|
||||
}
|
||||
|
||||
size_t count() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return frames_.size();
|
||||
}
|
||||
|
||||
private:
|
||||
SpriteFrameCache() = default;
|
||||
~SpriteFrameCache() = default;
|
||||
SpriteFrameCache(const SpriteFrameCache &) = delete;
|
||||
SpriteFrameCache &operator=(const SpriteFrameCache &) = delete;
|
||||
|
||||
/**
|
||||
* @brief 从文件加载纹理(使用 ResourceManager 的 LRU 缓存)
|
||||
* @param filepath 纹理文件路径
|
||||
* @return 纹理对象,失败返回nullptr
|
||||
*/
|
||||
Ptr<Texture> loadTextureFromFile(const std::string &filepath) {
|
||||
// 使用 ResourceManager 的纹理缓存机制
|
||||
// 这样可以享受 LRU 缓存、自动清理和缓存统计等功能
|
||||
auto &resources = ResourceManager::getInstance();
|
||||
|
||||
// 先检查缓存中是否已有该纹理
|
||||
auto texture = resources.getTexture(filepath);
|
||||
if (texture) {
|
||||
E2D_TRACE("SpriteFrameCache: 使用缓存纹理: {}", filepath);
|
||||
return texture;
|
||||
}
|
||||
|
||||
// 缓存未命中,通过 ResourceManager 加载
|
||||
texture = resources.loadTexture(filepath);
|
||||
if (!texture) {
|
||||
E2D_ERROR("SpriteFrameCache: 加载纹理失败: {}", filepath);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
E2D_TRACE("SpriteFrameCache: 加载新纹理: {}", filepath);
|
||||
return texture;
|
||||
}
|
||||
|
||||
mutable std::mutex mutex_;
|
||||
std::unordered_map<std::string, Ptr<SpriteFrame>> frames_;
|
||||
};
|
||||
|
||||
// 便捷宏
|
||||
#define E2D_SPRITE_FRAME_CACHE() ::extra2d::SpriteFrameCache::getInstance()
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <animation/tween_easing.h>
|
||||
#include <core/color.h>
|
||||
#include <core/math_types.h>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
class Node;
|
||||
|
||||
struct TweenOptions {
|
||||
TweenEasing easing = TweenEasing::Linear;
|
||||
std::function<void()> onStart = nullptr;
|
||||
std::function<void(float progress)> onUpdate = nullptr;
|
||||
std::function<void()> onComplete = nullptr;
|
||||
};
|
||||
|
||||
struct TweenProperty {
|
||||
std::optional<Vec2> position;
|
||||
std::optional<Vec2> scale;
|
||||
std::optional<float> rotation;
|
||||
std::optional<float> opacity;
|
||||
std::optional<Color> color;
|
||||
};
|
||||
|
||||
class TweenAction {
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
Interval,
|
||||
Delay,
|
||||
Call,
|
||||
Parallel,
|
||||
};
|
||||
|
||||
virtual ~TweenAction() = default;
|
||||
virtual void update(float dt) = 0;
|
||||
virtual bool isFinished() const = 0;
|
||||
virtual float getDuration() const = 0;
|
||||
virtual float getElapsed() const = 0;
|
||||
virtual void reset() = 0;
|
||||
|
||||
Type getType() const { return type_; }
|
||||
|
||||
protected:
|
||||
TweenAction(Type type) : type_(type) {}
|
||||
Type type_;
|
||||
};
|
||||
|
||||
class Tween {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<Tween>;
|
||||
using Callback = std::function<void()>;
|
||||
|
||||
explicit Tween(Node *target);
|
||||
Tween(Node *target, const std::string &name);
|
||||
~Tween();
|
||||
|
||||
Tween(const Tween &) = delete;
|
||||
Tween &operator=(const Tween &) = delete;
|
||||
Tween(Tween &&) = default;
|
||||
Tween &operator=(Tween &&) = default;
|
||||
|
||||
static Tween create(Node *target);
|
||||
static Tween create(Node *target, const std::string &name);
|
||||
|
||||
Tween &to(float duration, const TweenProperty &props,
|
||||
const TweenOptions &options = {});
|
||||
Tween &by(float duration, const TweenProperty &props,
|
||||
const TweenOptions &options = {});
|
||||
|
||||
Tween &set(const TweenProperty &props);
|
||||
Tween &delay(float seconds);
|
||||
Tween &call(Callback callback);
|
||||
|
||||
Tween ¶llel();
|
||||
Tween &endParallel();
|
||||
|
||||
Tween &union_();
|
||||
Tween &repeat(int times);
|
||||
Tween &repeatForever();
|
||||
Tween &yoyo(bool enabled = true);
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void pause();
|
||||
void resume();
|
||||
|
||||
void update(float dt);
|
||||
|
||||
bool isFinished() const;
|
||||
bool isPlaying() const;
|
||||
bool isPaused() const;
|
||||
float getTotalDuration() const;
|
||||
|
||||
void setName(const std::string &name) { name_ = name; }
|
||||
const std::string &name() const { return name_; }
|
||||
|
||||
private:
|
||||
Node *target_ = nullptr;
|
||||
std::string name_;
|
||||
std::vector<std::unique_ptr<TweenAction>> actions_;
|
||||
size_t currentActionIndex_ = 0;
|
||||
|
||||
bool playing_ = false;
|
||||
bool paused_ = false;
|
||||
bool finished_ = false;
|
||||
|
||||
int repeatCount_ = 1;
|
||||
int currentRepeat_ = 0;
|
||||
bool yoyo_ = false;
|
||||
bool reverse_ = false;
|
||||
bool repeatForever_ = false;
|
||||
|
||||
bool inParallel_ = false;
|
||||
std::vector<std::unique_ptr<TweenAction>> parallelActions_;
|
||||
|
||||
void addAction(std::unique_ptr<TweenAction> action);
|
||||
void advanceToNextAction();
|
||||
void resetAllActions();
|
||||
};
|
||||
|
||||
namespace tween {
|
||||
|
||||
inline TweenProperty pos(const Vec2 &p) {
|
||||
TweenProperty props;
|
||||
props.position = p;
|
||||
return props;
|
||||
}
|
||||
|
||||
inline TweenProperty pos(float x, float y) { return pos(Vec2(x, y)); }
|
||||
|
||||
inline TweenProperty scl(const Vec2 &s) {
|
||||
TweenProperty props;
|
||||
props.scale = s;
|
||||
return props;
|
||||
}
|
||||
|
||||
inline TweenProperty scl(float s) { return scl(Vec2(s, s)); }
|
||||
|
||||
inline TweenProperty rot(float degrees) {
|
||||
TweenProperty props;
|
||||
props.rotation = degrees;
|
||||
return props;
|
||||
}
|
||||
|
||||
inline TweenProperty opa(float opacity) {
|
||||
TweenProperty props;
|
||||
props.opacity = opacity;
|
||||
return props;
|
||||
}
|
||||
|
||||
inline TweenProperty col(const Color &c) {
|
||||
TweenProperty props;
|
||||
props.color = c;
|
||||
return props;
|
||||
}
|
||||
|
||||
TweenProperty combine(std::initializer_list<TweenProperty> props);
|
||||
|
||||
} // namespace tween
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
enum class TweenEasing : uint8_t {
|
||||
Linear,
|
||||
QuadIn,
|
||||
QuadOut,
|
||||
QuadInOut,
|
||||
CubicIn,
|
||||
CubicOut,
|
||||
CubicInOut,
|
||||
QuartIn,
|
||||
QuartOut,
|
||||
QuartInOut,
|
||||
QuintIn,
|
||||
QuintOut,
|
||||
QuintInOut,
|
||||
SineIn,
|
||||
SineOut,
|
||||
SineInOut,
|
||||
ExpoIn,
|
||||
ExpoOut,
|
||||
ExpoInOut,
|
||||
CircIn,
|
||||
CircOut,
|
||||
CircInOut,
|
||||
ElasticIn,
|
||||
ElasticOut,
|
||||
ElasticInOut,
|
||||
BackIn,
|
||||
BackOut,
|
||||
BackInOut,
|
||||
BounceIn,
|
||||
BounceOut,
|
||||
BounceInOut,
|
||||
Smooth,
|
||||
Fade,
|
||||
};
|
||||
|
||||
class EasingFunctions {
|
||||
public:
|
||||
using EasingFunc = float (*)(float);
|
||||
|
||||
static float apply(float t, TweenEasing easing);
|
||||
static EasingFunc get(TweenEasing easing);
|
||||
|
||||
static float linear(float t);
|
||||
static float quadIn(float t);
|
||||
static float quadOut(float t);
|
||||
static float quadInOut(float t);
|
||||
static float cubicIn(float t);
|
||||
static float cubicOut(float t);
|
||||
static float cubicInOut(float t);
|
||||
static float quartIn(float t);
|
||||
static float quartOut(float t);
|
||||
static float quartInOut(float t);
|
||||
static float quintIn(float t);
|
||||
static float quintOut(float t);
|
||||
static float quintInOut(float t);
|
||||
static float sineIn(float t);
|
||||
static float sineOut(float t);
|
||||
static float sineInOut(float t);
|
||||
static float expoIn(float t);
|
||||
static float expoOut(float t);
|
||||
static float expoInOut(float t);
|
||||
static float circIn(float t);
|
||||
static float circOut(float t);
|
||||
static float circInOut(float t);
|
||||
static float elasticIn(float t);
|
||||
static float elasticOut(float t);
|
||||
static float elasticInOut(float t);
|
||||
static float backIn(float t);
|
||||
static float backOut(float t);
|
||||
static float backInOut(float t);
|
||||
static float bounceIn(float t);
|
||||
static float bounceOut(float t);
|
||||
static float bounceInOut(float t);
|
||||
static float smooth(float t);
|
||||
static float fade(float t);
|
||||
|
||||
private:
|
||||
static constexpr float PI = 3.14159265358979323846f;
|
||||
static constexpr float HALF_PI = 1.57079632679489661923f;
|
||||
static constexpr float BACK_CONST = 1.70158f;
|
||||
static constexpr float ELASTIC_CONST = 2.0f * PI / 3.0f;
|
||||
};
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <core/string.h>
|
||||
#include <core/types.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <memory>
|
||||
#include <platform/window.h>
|
||||
|
||||
|
|
@ -86,8 +86,6 @@ public:
|
|||
// 便捷方法
|
||||
// ------------------------------------------------------------------------
|
||||
void enterScene(Ptr<class Scene> scene);
|
||||
void enterScene(Ptr<class Scene> scene,
|
||||
Ptr<class TransitionScene> transitionScene);
|
||||
|
||||
float deltaTime() const { return deltaTime_; }
|
||||
float totalTime() const { return totalTime_; }
|
||||
|
|
|
|||
|
|
@ -14,33 +14,23 @@
|
|||
#include <platform/window.h>
|
||||
|
||||
// Graphics
|
||||
#include <graphics/camera.h>
|
||||
#include <graphics/font.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <graphics/shader_system.h>
|
||||
#include <graphics/texture.h>
|
||||
|
||||
#include <graphics/render_target.h>
|
||||
#include <graphics/vram_manager.h>
|
||||
|
||||
// Renderer
|
||||
#include <renderer/camera.h>
|
||||
#include <renderer/render_target.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <renderer/shader_system.h>
|
||||
|
||||
|
||||
// Scene
|
||||
#include <scene/node.h>
|
||||
#include <scene/scene.h>
|
||||
#include <scene/scene_manager.h>
|
||||
#include <scene/shape_node.h>
|
||||
#include <scene/shape.h>
|
||||
#include <scene/sprite.h>
|
||||
#include <scene/transition_box_scene.h>
|
||||
#include <scene/transition_fade_scene.h>
|
||||
#include <scene/transition_flip_scene.h>
|
||||
#include <scene/transition_scale_scene.h>
|
||||
#include <scene/transition_scene.h>
|
||||
#include <scene/transition_slide_scene.h>
|
||||
|
||||
// Animation
|
||||
#include <animation/sprite_frame.h>
|
||||
#include <animation/sprite_frame_cache.h>
|
||||
#include <animation/tween.h>
|
||||
#include <animation/tween_easing.h>
|
||||
|
||||
// UI
|
||||
#include <ui/button.h>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <graphics/opengl/gl_shader.h>
|
||||
#include <graphics/opengl/gl_sprite_batch.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
|
||||
#include <array>
|
||||
#include <glad/glad.h>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include <core/types.h>
|
||||
#include <event/event_dispatcher.h>
|
||||
#include <functional>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
@ -17,8 +17,6 @@ namespace extra2d {
|
|||
class Scene;
|
||||
class Renderer;
|
||||
struct RenderCommand;
|
||||
class Tween;
|
||||
enum class TweenEasing : uint8_t;
|
||||
|
||||
// ============================================================================
|
||||
// 节点基类 - 场景图的基础
|
||||
|
|
@ -155,85 +153,6 @@ public:
|
|||
// ------------------------------------------------------------------------
|
||||
EventDispatcher &getEventDispatcher() { return eventDispatcher_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Tween 动画系统
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief 创建 Tween 动画
|
||||
* @return Tween 对象引用,支持链式调用
|
||||
*/
|
||||
Tween &tween();
|
||||
|
||||
/**
|
||||
* @brief 创建具名 Tween 动画
|
||||
*/
|
||||
Tween &tween(const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief 移动到目标位置
|
||||
*/
|
||||
Tween &moveTo(const Vec2 &pos, float duration,
|
||||
TweenEasing easing = static_cast<TweenEasing>(0));
|
||||
|
||||
/**
|
||||
* @brief 移动指定距离
|
||||
*/
|
||||
Tween &moveBy(const Vec2 &delta, float duration,
|
||||
TweenEasing easing = static_cast<TweenEasing>(0));
|
||||
|
||||
/**
|
||||
* @brief 缩放到目标值
|
||||
*/
|
||||
Tween &scaleTo(float scale, float duration,
|
||||
TweenEasing easing = static_cast<TweenEasing>(0));
|
||||
|
||||
/**
|
||||
* @brief 缩放指定增量
|
||||
*/
|
||||
Tween &scaleBy(float delta, float duration,
|
||||
TweenEasing easing = static_cast<TweenEasing>(0));
|
||||
|
||||
/**
|
||||
* @brief 旋转到目标角度
|
||||
*/
|
||||
Tween &rotateTo(float degrees, float duration,
|
||||
TweenEasing easing = static_cast<TweenEasing>(0));
|
||||
|
||||
/**
|
||||
* @brief 旋转指定角度
|
||||
*/
|
||||
Tween &rotateBy(float degrees, float duration,
|
||||
TweenEasing easing = static_cast<TweenEasing>(0));
|
||||
|
||||
/**
|
||||
* @brief 淡入(透明度从当前到1)
|
||||
*/
|
||||
Tween &fadeIn(float duration,
|
||||
TweenEasing easing = static_cast<TweenEasing>(0));
|
||||
|
||||
/**
|
||||
* @brief 淡出(透明度从当前到0)
|
||||
*/
|
||||
Tween &fadeOut(float duration,
|
||||
TweenEasing easing = static_cast<TweenEasing>(0));
|
||||
|
||||
/**
|
||||
* @brief 透明度变化到目标值
|
||||
*/
|
||||
Tween &fadeTo(float opacity, float duration,
|
||||
TweenEasing easing = static_cast<TweenEasing>(0));
|
||||
|
||||
/**
|
||||
* @brief 停止所有 Tween 动画
|
||||
*/
|
||||
void stopAllTweens();
|
||||
|
||||
/**
|
||||
* @brief 更新所有 Tween 动画
|
||||
*/
|
||||
void updateTweens(float dt);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 内部方法
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -318,8 +237,7 @@ private:
|
|||
bool visible_ = true; // 1 byte
|
||||
bool running_ = false; // 1 byte
|
||||
|
||||
// 10. Tween 动画列表
|
||||
std::vector<std::shared_ptr<Tween>> tweens_;
|
||||
|
||||
};
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <core/color.h>
|
||||
#include <graphics/camera.h>
|
||||
#include <renderer/camera.h>
|
||||
#include <scene/node.h>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -69,12 +69,7 @@ protected:
|
|||
void onEnter() override;
|
||||
void onExit() override;
|
||||
|
||||
// 过渡场景生命周期回调(供 TransitionScene 使用)
|
||||
virtual void onExitTransitionDidStart() {}
|
||||
virtual void onEnterTransitionDidFinish() {}
|
||||
|
||||
friend class SceneManager;
|
||||
friend class TransitionScene;
|
||||
|
||||
private:
|
||||
Color backgroundColor_ = Colors::Black;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#include <core/types.h>
|
||||
#include <functional>
|
||||
#include <scene/scene.h>
|
||||
#include <scene/transition_scene.h>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
|
@ -14,15 +13,12 @@ namespace extra2d {
|
|||
|
||||
// 前向声明
|
||||
struct RenderCommand;
|
||||
class TransitionScene;
|
||||
|
||||
// ============================================================================
|
||||
// 场景管理器 - 管理场景的生命周期和切换
|
||||
// ============================================================================
|
||||
class SceneManager {
|
||||
public:
|
||||
using TransitionCallback = std::function<void()>;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 单例访问
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -37,26 +33,18 @@ public:
|
|||
|
||||
// 替换当前场景
|
||||
void replaceScene(Ptr<Scene> scene);
|
||||
void replaceScene(Ptr<Scene> scene, TransitionType transition,
|
||||
float duration = 0.5f);
|
||||
|
||||
// 压入新场景(当前场景暂停)
|
||||
void pushScene(Ptr<Scene> scene);
|
||||
void pushScene(Ptr<Scene> scene, TransitionType transition,
|
||||
float duration = 0.5f);
|
||||
|
||||
// 弹出当前场景(恢复上一个场景)
|
||||
void popScene();
|
||||
void popScene(TransitionType transition, float duration = 0.5f);
|
||||
|
||||
// 弹出到根场景
|
||||
void popToRootScene();
|
||||
void popToRootScene(TransitionType transition, float duration = 0.5f);
|
||||
|
||||
// 弹出到指定场景
|
||||
void popToScene(const std::string &name);
|
||||
void popToScene(const std::string &name, TransitionType transition,
|
||||
float duration = 0.5f);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 获取场景
|
||||
|
|
@ -82,14 +70,6 @@ public:
|
|||
void render(Renderer &renderer);
|
||||
void collectRenderCommands(std::vector<RenderCommand> &commands);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 过渡控制
|
||||
// ------------------------------------------------------------------------
|
||||
bool isTransitioning() const { return isTransitioning_; }
|
||||
void setTransitionCallback(TransitionCallback callback) {
|
||||
transitionCallback_ = callback;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 清理
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -104,30 +84,14 @@ public:
|
|||
|
||||
// 场景切换(供 Application 使用)
|
||||
void enterScene(Ptr<Scene> scene);
|
||||
void enterScene(Ptr<Scene> scene, Ptr<TransitionScene> transitionScene);
|
||||
|
||||
private:
|
||||
void doSceneSwitch();
|
||||
void startTransition(Ptr<Scene> from, Ptr<Scene> to, TransitionType type,
|
||||
float duration, Function<void()> stackAction);
|
||||
void finishTransition();
|
||||
void dispatchPointerEvents(Scene &scene);
|
||||
|
||||
// 创建过渡场景
|
||||
Ptr<TransitionScene> createTransitionScene(TransitionType type,
|
||||
float duration,
|
||||
Ptr<Scene> inScene);
|
||||
|
||||
std::stack<Ptr<Scene>> sceneStack_;
|
||||
std::unordered_map<std::string, Ptr<Scene>> namedScenes_;
|
||||
|
||||
// Transition state
|
||||
bool isTransitioning_ = false;
|
||||
TransitionType currentTransition_ = TransitionType::None;
|
||||
Ptr<TransitionScene> activeTransitionScene_;
|
||||
Function<void()> transitionStackAction_;
|
||||
TransitionCallback transitionCallback_;
|
||||
|
||||
// Next scene to switch to (queued during transition)
|
||||
Ptr<Scene> nextScene_;
|
||||
bool sendCleanupToScene_ = false;
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <scene/transition_scene.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
// ============================================================================
|
||||
// 方块/马赛克过渡场景
|
||||
// 实现原理:
|
||||
// 1. 将屏幕分成多个方块
|
||||
// 2. 方块逐个消失,显示新场景
|
||||
// ============================================================================
|
||||
class TransitionBoxScene : public TransitionScene {
|
||||
public:
|
||||
/**
|
||||
* @brief 创建方块过渡场景
|
||||
* @param duration 过渡持续时间(秒)
|
||||
* @param inScene 要进入的目标场景
|
||||
* @param divisions 方块分割数(默认为 8,表示 8x8 网格)
|
||||
*/
|
||||
TransitionBoxScene(float duration, Ptr<Scene> inScene, int divisions = 8);
|
||||
|
||||
static Ptr<TransitionBoxScene> create(float duration, Ptr<Scene> inScene,
|
||||
int divisions = 8);
|
||||
|
||||
protected:
|
||||
void onTransitionStart() override;
|
||||
void renderContent(Renderer &renderer) override;
|
||||
|
||||
private:
|
||||
int divisions_;
|
||||
};
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <core/color.h>
|
||||
#include <scene/sprite.h>
|
||||
#include <scene/transition_scene.h>
|
||||
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
// ============================================================================
|
||||
// 淡入淡出过渡场景
|
||||
// 实现原理:
|
||||
// 1. 创建一个纯色精灵作为遮罩层
|
||||
// 2. 第一阶段:遮罩从透明淡入到不透明(黑屏),同时显示旧场景
|
||||
// 3. 切换显示新场景
|
||||
// 4. 第二阶段:遮罩从不透明淡出到透明,显示新场景
|
||||
// ============================================================================
|
||||
class TransitionFadeScene : public TransitionScene {
|
||||
public:
|
||||
/**
|
||||
* @brief 创建淡入淡出过渡场景
|
||||
* @param duration 过渡持续时间(秒)
|
||||
* @param inScene 要进入的目标场景
|
||||
* @param color 遮罩颜色(默认为黑色)
|
||||
*/
|
||||
TransitionFadeScene(float duration, Ptr<Scene> inScene,
|
||||
const Color &color = Colors::Black);
|
||||
|
||||
static Ptr<TransitionFadeScene> create(float duration, Ptr<Scene> inScene,
|
||||
const Color &color = Colors::Black);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief 启动过渡动画
|
||||
* 创建遮罩层并运行动作序列
|
||||
*/
|
||||
void onTransitionStart() override;
|
||||
|
||||
/**
|
||||
* @brief 渲染内容
|
||||
* 根据进度控制新旧场景的显示
|
||||
*/
|
||||
void renderContent(Renderer &renderer) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief 隐藏退出场景,显示进入场景
|
||||
*/
|
||||
void hideOutShowIn();
|
||||
|
||||
Color maskColor_; // 遮罩颜色
|
||||
bool hasSwitched_ = false; // 是否已经切换场景
|
||||
};
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <scene/transition_scene.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
// ============================================================================
|
||||
// 翻页过渡场景
|
||||
// 实现原理:
|
||||
// 1. 前半段:旧场景翻转消失
|
||||
// 2. 后半段:新场景翻转出现
|
||||
// ============================================================================
|
||||
class TransitionFlipScene : public TransitionScene {
|
||||
public:
|
||||
enum class Axis { Horizontal, Vertical };
|
||||
|
||||
/**
|
||||
* @brief 创建翻页过渡场景
|
||||
* @param duration 过渡持续时间(秒)
|
||||
* @param inScene 要进入的目标场景
|
||||
* @param axis 翻转轴(水平或垂直)
|
||||
*/
|
||||
TransitionFlipScene(float duration, Ptr<Scene> inScene,
|
||||
Axis axis = Axis::Horizontal);
|
||||
|
||||
static Ptr<TransitionFlipScene> create(float duration, Ptr<Scene> inScene,
|
||||
Axis axis = Axis::Horizontal);
|
||||
|
||||
protected:
|
||||
void onTransitionStart() override;
|
||||
void renderContent(Renderer &renderer) override;
|
||||
|
||||
private:
|
||||
Axis axis_;
|
||||
};
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <scene/transition_scene.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
// ============================================================================
|
||||
// 缩放过渡场景
|
||||
// 实现原理:
|
||||
// 1. 旧场景缩小消失
|
||||
// 2. 新场景放大出现
|
||||
// ============================================================================
|
||||
class TransitionScaleScene : public TransitionScene {
|
||||
public:
|
||||
/**
|
||||
* @brief 创建缩放过渡场景
|
||||
* @param duration 过渡持续时间(秒)
|
||||
* @param inScene 要进入的目标场景
|
||||
*/
|
||||
TransitionScaleScene(float duration, Ptr<Scene> inScene);
|
||||
|
||||
static Ptr<TransitionScaleScene> create(float duration, Ptr<Scene> inScene);
|
||||
|
||||
protected:
|
||||
void onTransitionStart() override;
|
||||
void renderContent(Renderer &renderer) override;
|
||||
};
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <scene/scene.h>
|
||||
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
// ============================================================================
|
||||
// 过渡方向
|
||||
// ============================================================================
|
||||
enum class TransitionDirection { Left, Right, Up, Down };
|
||||
|
||||
// ============================================================================
|
||||
// 过渡效果类型
|
||||
// ============================================================================
|
||||
enum class TransitionType {
|
||||
None,
|
||||
Fade,
|
||||
SlideLeft,
|
||||
SlideRight,
|
||||
SlideUp,
|
||||
SlideDown,
|
||||
Scale,
|
||||
Flip,
|
||||
Box
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// 过渡场景基类 - 继承自 Scene,作为中介场景管理过渡效果
|
||||
// 设计参考 Cocos2d-x 的 TransitionScene
|
||||
// ============================================================================
|
||||
class TransitionScene : public Scene {
|
||||
public:
|
||||
using FinishCallback = std::function<void()>;
|
||||
|
||||
/**
|
||||
* @brief 创建过渡场景
|
||||
* @param duration 过渡持续时间(秒)
|
||||
* @param inScene 要进入的目标场景
|
||||
*/
|
||||
TransitionScene(float duration, Ptr<Scene> inScene);
|
||||
~TransitionScene() override = default;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 场景管理
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief 获取要进入的场景
|
||||
*/
|
||||
Ptr<Scene> getInScene() const { return inScene_; }
|
||||
|
||||
/**
|
||||
* @brief 获取要退出的场景
|
||||
*/
|
||||
Ptr<Scene> getOutScene() const { return outScene_; }
|
||||
|
||||
/**
|
||||
* @brief 设置要退出的场景(由 SceneManager 调用)
|
||||
*/
|
||||
void setOutScene(Ptr<Scene> outScene) { outScene_ = outScene; }
|
||||
|
||||
/**
|
||||
* @brief 设置过渡完成回调
|
||||
*/
|
||||
void setFinishCallback(FinishCallback callback) {
|
||||
finishCallback_ = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取过渡持续时间
|
||||
*/
|
||||
float getDuration() const { return duration_; }
|
||||
|
||||
/**
|
||||
* @brief 获取当前进度 [0, 1]
|
||||
*/
|
||||
float getProgress() const { return progress_; }
|
||||
|
||||
/**
|
||||
* @brief 是否已完成
|
||||
*/
|
||||
bool isFinished() const { return isFinished_; }
|
||||
|
||||
/**
|
||||
* @brief 完成过渡,通知 SceneManager 切换到目标场景
|
||||
*/
|
||||
void finish();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 渲染 - 在 TransitionScene 上渲染新旧两个子场景
|
||||
// ------------------------------------------------------------------------
|
||||
void renderContent(Renderer &renderer) override;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 生命周期
|
||||
// ------------------------------------------------------------------------
|
||||
void onEnter() override;
|
||||
void onExit() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief 子类实现具体的过渡逻辑
|
||||
* 在 onEnter 中设置动画,动画完成后调用 finish()
|
||||
*/
|
||||
virtual void onTransitionStart() = 0;
|
||||
|
||||
/**
|
||||
* @brief 绘制源场景(旧场景)
|
||||
*/
|
||||
virtual void drawOutScene(Renderer &renderer);
|
||||
|
||||
/**
|
||||
* @brief 绘制目标场景(新场景)
|
||||
*/
|
||||
virtual void drawInScene(Renderer &renderer);
|
||||
|
||||
float duration_;
|
||||
float elapsed_ = 0.0f;
|
||||
float progress_ = 0.0f;
|
||||
bool isFinished_ = false;
|
||||
|
||||
Ptr<Scene> inScene_; // 要进入的场景
|
||||
Ptr<Scene> outScene_; // 要退出的场景
|
||||
|
||||
FinishCallback finishCallback_;
|
||||
};
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <scene/transition_scene.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
// ============================================================================
|
||||
// 滑动过渡场景
|
||||
// 实现原理:
|
||||
// 1. 旧场景向指定方向滑出
|
||||
// 2. 新场景从相反方向滑入
|
||||
// ============================================================================
|
||||
class TransitionSlideScene : public TransitionScene {
|
||||
public:
|
||||
/**
|
||||
* @brief 创建滑动过渡场景
|
||||
* @param duration 过渡持续时间(秒)
|
||||
* @param inScene 要进入的目标场景
|
||||
* @param direction 滑动方向
|
||||
*/
|
||||
TransitionSlideScene(float duration, Ptr<Scene> inScene,
|
||||
TransitionDirection direction);
|
||||
|
||||
static Ptr<TransitionSlideScene> create(float duration, Ptr<Scene> inScene,
|
||||
TransitionDirection direction);
|
||||
|
||||
protected:
|
||||
void onTransitionStart() override;
|
||||
void renderContent(Renderer &renderer) override;
|
||||
|
||||
private:
|
||||
TransitionDirection direction_;
|
||||
};
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#include <animation/sprite_frame.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
// SpriteFrame 的实现全部在头文件中以内联方式完成
|
||||
// 此文件保留用于未来可能需要的非内联实现
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#include <animation/sprite_frame_cache.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
// SpriteFrameCache 的实现全部在头文件中以内联方式完成
|
||||
// 此文件保留用于未来可能需要的非内联实现
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,451 +0,0 @@
|
|||
#include <animation/tween.h>
|
||||
#include <scene/node.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
class IntervalAction : public TweenAction {
|
||||
public:
|
||||
IntervalAction(Node *target, float duration, const TweenProperty &props,
|
||||
const TweenOptions &options, bool isRelative)
|
||||
: TweenAction(Type::Interval), target_(target), duration_(duration),
|
||||
props_(props), options_(options), isRelative_(isRelative) {}
|
||||
|
||||
void update(float dt) override {
|
||||
if (finished_)
|
||||
return;
|
||||
|
||||
elapsed_ += dt;
|
||||
float t = std::min(elapsed_ / duration_, 1.0f);
|
||||
float easedT = EasingFunctions::apply(t, options_.easing);
|
||||
|
||||
applyProperties(easedT);
|
||||
|
||||
if (options_.onUpdate) {
|
||||
options_.onUpdate(t);
|
||||
}
|
||||
|
||||
if (t >= 1.0f) {
|
||||
finished_ = true;
|
||||
if (options_.onComplete) {
|
||||
options_.onComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isFinished() const override { return finished_; }
|
||||
float getDuration() const override { return duration_; }
|
||||
float getElapsed() const override { return elapsed_; }
|
||||
|
||||
void reset() override {
|
||||
elapsed_ = 0.0f;
|
||||
finished_ = false;
|
||||
started_ = false;
|
||||
}
|
||||
|
||||
void captureStartValues() {
|
||||
if (started_)
|
||||
return;
|
||||
started_ = true;
|
||||
|
||||
if (target_) {
|
||||
startPos_ = target_->pos();
|
||||
startScale_ = target_->scale();
|
||||
startRotation_ = target_->rot();
|
||||
startOpacity_ = target_->opacity();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Node *target_;
|
||||
float duration_;
|
||||
TweenProperty props_;
|
||||
TweenOptions options_;
|
||||
bool isRelative_;
|
||||
bool started_ = false;
|
||||
|
||||
float elapsed_ = 0.0f;
|
||||
bool finished_ = false;
|
||||
|
||||
Vec2 startPos_;
|
||||
Vec2 startScale_;
|
||||
float startRotation_ = 0.0f;
|
||||
float startOpacity_ = 1.0f;
|
||||
|
||||
void applyProperties(float t) {
|
||||
if (!target_)
|
||||
return;
|
||||
|
||||
if (props_.position.has_value()) {
|
||||
Vec2 targetPos = isRelative_ ? startPos_ + props_.position.value()
|
||||
: props_.position.value();
|
||||
Vec2 newPos = Vec2::lerp(startPos_, targetPos, t);
|
||||
target_->setPosition(newPos);
|
||||
}
|
||||
|
||||
if (props_.scale.has_value()) {
|
||||
Vec2 targetScale =
|
||||
isRelative_ ? startScale_ + props_.scale.value()
|
||||
: props_.scale.value();
|
||||
Vec2 newScale = Vec2::lerp(startScale_, targetScale, t);
|
||||
target_->setScale(newScale);
|
||||
}
|
||||
|
||||
if (props_.rotation.has_value()) {
|
||||
float targetRot = isRelative_ ? startRotation_ + props_.rotation.value()
|
||||
: props_.rotation.value();
|
||||
float newRot = startRotation_ + (targetRot - startRotation_) * t;
|
||||
target_->setRotation(newRot);
|
||||
}
|
||||
|
||||
if (props_.opacity.has_value()) {
|
||||
float targetOpa = isRelative_ ? startOpacity_ + props_.opacity.value()
|
||||
: props_.opacity.value();
|
||||
float newOpa = startOpacity_ + (targetOpa - startOpacity_) * t;
|
||||
target_->setOpacity(newOpa);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class DelayAction : public TweenAction {
|
||||
public:
|
||||
DelayAction(float duration)
|
||||
: TweenAction(Type::Delay), duration_(duration) {}
|
||||
|
||||
void update(float dt) override {
|
||||
elapsed_ += dt;
|
||||
finished_ = elapsed_ >= duration_;
|
||||
}
|
||||
|
||||
bool isFinished() const override { return finished_; }
|
||||
float getDuration() const override { return duration_; }
|
||||
float getElapsed() const override { return elapsed_; }
|
||||
void reset() override {
|
||||
elapsed_ = 0.0f;
|
||||
finished_ = false;
|
||||
}
|
||||
|
||||
private:
|
||||
float duration_;
|
||||
float elapsed_ = 0.0f;
|
||||
bool finished_ = false;
|
||||
};
|
||||
|
||||
class CallAction : public TweenAction {
|
||||
public:
|
||||
CallAction(std::function<void()> callback)
|
||||
: TweenAction(Type::Call), callback_(std::move(callback)) {}
|
||||
|
||||
void update(float) override {
|
||||
if (!called_) {
|
||||
if (callback_) {
|
||||
callback_();
|
||||
}
|
||||
called_ = true;
|
||||
}
|
||||
finished_ = true;
|
||||
}
|
||||
|
||||
bool isFinished() const override { return finished_; }
|
||||
float getDuration() const override { return 0.0f; }
|
||||
float getElapsed() const override { return 0.0f; }
|
||||
void reset() override {
|
||||
called_ = false;
|
||||
finished_ = false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void()> callback_;
|
||||
bool called_ = false;
|
||||
bool finished_ = false;
|
||||
};
|
||||
|
||||
class SetAction : public TweenAction {
|
||||
public:
|
||||
SetAction(Node *target, const TweenProperty &props)
|
||||
: TweenAction(Type::Call), target_(target), props_(props) {}
|
||||
|
||||
void update(float) override {
|
||||
if (!applied_ && target_) {
|
||||
if (props_.position.has_value())
|
||||
target_->setPosition(props_.position.value());
|
||||
if (props_.scale.has_value())
|
||||
target_->setScale(props_.scale.value());
|
||||
if (props_.rotation.has_value())
|
||||
target_->setRotation(props_.rotation.value());
|
||||
if (props_.opacity.has_value())
|
||||
target_->setOpacity(props_.opacity.value());
|
||||
applied_ = true;
|
||||
}
|
||||
finished_ = true;
|
||||
}
|
||||
|
||||
bool isFinished() const override { return finished_; }
|
||||
float getDuration() const override { return 0.0f; }
|
||||
float getElapsed() const override { return 0.0f; }
|
||||
void reset() override {
|
||||
applied_ = false;
|
||||
finished_ = false;
|
||||
}
|
||||
|
||||
private:
|
||||
Node *target_;
|
||||
TweenProperty props_;
|
||||
bool applied_ = false;
|
||||
bool finished_ = false;
|
||||
};
|
||||
|
||||
class ParallelAction : public TweenAction {
|
||||
public:
|
||||
ParallelAction() : TweenAction(Type::Parallel) {}
|
||||
|
||||
void addAction(std::unique_ptr<TweenAction> action) {
|
||||
actions_.push_back(std::move(action));
|
||||
}
|
||||
|
||||
void update(float dt) override {
|
||||
if (finished_)
|
||||
return;
|
||||
|
||||
bool allFinished = true;
|
||||
for (auto &action : actions_) {
|
||||
if (!action->isFinished()) {
|
||||
action->update(dt);
|
||||
allFinished = false;
|
||||
}
|
||||
}
|
||||
|
||||
finished_ = allFinished;
|
||||
}
|
||||
|
||||
bool isFinished() const override { return finished_; }
|
||||
float getDuration() const override {
|
||||
float maxDur = 0.0f;
|
||||
for (const auto &action : actions_) {
|
||||
maxDur = std::max(maxDur, action->getDuration());
|
||||
}
|
||||
return maxDur;
|
||||
}
|
||||
float getElapsed() const override {
|
||||
float maxElapsed = 0.0f;
|
||||
for (const auto &action : actions_) {
|
||||
maxElapsed = std::max(maxElapsed, action->getElapsed());
|
||||
}
|
||||
return maxElapsed;
|
||||
}
|
||||
void reset() override {
|
||||
for (auto &action : actions_) {
|
||||
action->reset();
|
||||
}
|
||||
finished_ = false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<TweenAction>> actions_;
|
||||
bool finished_ = false;
|
||||
};
|
||||
|
||||
Tween::Tween(Node *target) : target_(target) {}
|
||||
|
||||
Tween::Tween(Node *target, const std::string &name)
|
||||
: target_(target), name_(name) {}
|
||||
|
||||
Tween::~Tween() = default;
|
||||
|
||||
Tween Tween::create(Node *target) { return Tween(target); }
|
||||
|
||||
Tween Tween::create(Node *target, const std::string &name) {
|
||||
return Tween(target, name);
|
||||
}
|
||||
|
||||
Tween &Tween::to(float duration, const TweenProperty &props,
|
||||
const TweenOptions &options) {
|
||||
auto action =
|
||||
std::make_unique<IntervalAction>(target_, duration, props, options, false);
|
||||
addAction(std::move(action));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Tween &Tween::by(float duration, const TweenProperty &props,
|
||||
const TweenOptions &options) {
|
||||
auto action =
|
||||
std::make_unique<IntervalAction>(target_, duration, props, options, true);
|
||||
addAction(std::move(action));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Tween &Tween::set(const TweenProperty &props) {
|
||||
auto action = std::make_unique<SetAction>(target_, props);
|
||||
addAction(std::move(action));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Tween &Tween::delay(float seconds) {
|
||||
auto action = std::make_unique<DelayAction>(seconds);
|
||||
addAction(std::move(action));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Tween &Tween::call(Callback callback) {
|
||||
auto action = std::make_unique<CallAction>(std::move(callback));
|
||||
addAction(std::move(action));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Tween &Tween::parallel() {
|
||||
inParallel_ = true;
|
||||
parallelActions_.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Tween &Tween::endParallel() {
|
||||
if (inParallel_ && !parallelActions_.empty()) {
|
||||
auto parallel = std::make_unique<ParallelAction>();
|
||||
for (auto &action : parallelActions_) {
|
||||
parallel->addAction(std::move(action));
|
||||
}
|
||||
actions_.push_back(std::move(parallel));
|
||||
parallelActions_.clear();
|
||||
}
|
||||
inParallel_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Tween &Tween::union_() { return *this; }
|
||||
|
||||
Tween &Tween::repeat(int times) {
|
||||
repeatCount_ = times;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Tween &Tween::repeatForever() {
|
||||
repeatForever_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Tween &Tween::yoyo(bool enabled) {
|
||||
yoyo_ = enabled;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Tween::start() {
|
||||
if (actions_.empty())
|
||||
return;
|
||||
|
||||
playing_ = true;
|
||||
paused_ = false;
|
||||
finished_ = false;
|
||||
currentActionIndex_ = 0;
|
||||
currentRepeat_ = 0;
|
||||
|
||||
for (auto &action : actions_) {
|
||||
action->reset();
|
||||
}
|
||||
|
||||
if (auto *interval =
|
||||
dynamic_cast<IntervalAction *>(actions_[0].get())) {
|
||||
interval->captureStartValues();
|
||||
}
|
||||
}
|
||||
|
||||
void Tween::stop() {
|
||||
playing_ = false;
|
||||
finished_ = true;
|
||||
}
|
||||
|
||||
void Tween::pause() { paused_ = true; }
|
||||
|
||||
void Tween::resume() { paused_ = false; }
|
||||
|
||||
void Tween::update(float dt) {
|
||||
if (!playing_ || paused_ || finished_)
|
||||
return;
|
||||
|
||||
if (currentActionIndex_ >= actions_.size()) {
|
||||
if (repeatForever_ || currentRepeat_ < repeatCount_ - 1) {
|
||||
currentRepeat_++;
|
||||
resetAllActions();
|
||||
currentActionIndex_ = 0;
|
||||
if (yoyo_) {
|
||||
reverse_ = !reverse_;
|
||||
}
|
||||
} else {
|
||||
finished_ = true;
|
||||
playing_ = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto &action = actions_[currentActionIndex_];
|
||||
action->update(dt);
|
||||
|
||||
if (action->isFinished()) {
|
||||
currentActionIndex_++;
|
||||
if (currentActionIndex_ < actions_.size()) {
|
||||
actions_[currentActionIndex_]->reset();
|
||||
if (auto *interval = dynamic_cast<IntervalAction *>(
|
||||
actions_[currentActionIndex_].get())) {
|
||||
interval->captureStartValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Tween::isFinished() const { return finished_; }
|
||||
|
||||
bool Tween::isPlaying() const { return playing_; }
|
||||
|
||||
bool Tween::isPaused() const { return paused_; }
|
||||
|
||||
float Tween::getTotalDuration() const {
|
||||
float total = 0.0f;
|
||||
for (const auto &action : actions_) {
|
||||
total += action->getDuration();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void Tween::addAction(std::unique_ptr<TweenAction> action) {
|
||||
if (inParallel_) {
|
||||
parallelActions_.push_back(std::move(action));
|
||||
} else {
|
||||
actions_.push_back(std::move(action));
|
||||
}
|
||||
}
|
||||
|
||||
void Tween::advanceToNextAction() {
|
||||
currentActionIndex_++;
|
||||
if (currentActionIndex_ < actions_.size()) {
|
||||
actions_[currentActionIndex_]->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void Tween::resetAllActions() {
|
||||
for (auto &action : actions_) {
|
||||
action->reset();
|
||||
}
|
||||
}
|
||||
|
||||
namespace tween {
|
||||
|
||||
TweenProperty combine(std::initializer_list<TweenProperty> props) {
|
||||
TweenProperty result;
|
||||
for (const auto &p : props) {
|
||||
if (p.position.has_value())
|
||||
result.position = p.position;
|
||||
if (p.scale.has_value())
|
||||
result.scale = p.scale;
|
||||
if (p.rotation.has_value())
|
||||
result.rotation = p.rotation;
|
||||
if (p.opacity.has_value())
|
||||
result.opacity = p.opacity;
|
||||
if (p.color.has_value())
|
||||
result.color = p.color;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace tween
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,236 +0,0 @@
|
|||
#include <animation/tween_easing.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
float EasingFunctions::apply(float t, TweenEasing easing) {
|
||||
return get(easing)(t);
|
||||
}
|
||||
|
||||
EasingFunctions::EasingFunc EasingFunctions::get(TweenEasing easing) {
|
||||
switch (easing) {
|
||||
case TweenEasing::Linear: return linear;
|
||||
case TweenEasing::QuadIn: return quadIn;
|
||||
case TweenEasing::QuadOut: return quadOut;
|
||||
case TweenEasing::QuadInOut: return quadInOut;
|
||||
case TweenEasing::CubicIn: return cubicIn;
|
||||
case TweenEasing::CubicOut: return cubicOut;
|
||||
case TweenEasing::CubicInOut: return cubicInOut;
|
||||
case TweenEasing::QuartIn: return quartIn;
|
||||
case TweenEasing::QuartOut: return quartOut;
|
||||
case TweenEasing::QuartInOut: return quartInOut;
|
||||
case TweenEasing::QuintIn: return quintIn;
|
||||
case TweenEasing::QuintOut: return quintOut;
|
||||
case TweenEasing::QuintInOut: return quintInOut;
|
||||
case TweenEasing::SineIn: return sineIn;
|
||||
case TweenEasing::SineOut: return sineOut;
|
||||
case TweenEasing::SineInOut: return sineInOut;
|
||||
case TweenEasing::ExpoIn: return expoIn;
|
||||
case TweenEasing::ExpoOut: return expoOut;
|
||||
case TweenEasing::ExpoInOut: return expoInOut;
|
||||
case TweenEasing::CircIn: return circIn;
|
||||
case TweenEasing::CircOut: return circOut;
|
||||
case TweenEasing::CircInOut: return circInOut;
|
||||
case TweenEasing::ElasticIn: return elasticIn;
|
||||
case TweenEasing::ElasticOut: return elasticOut;
|
||||
case TweenEasing::ElasticInOut: return elasticInOut;
|
||||
case TweenEasing::BackIn: return backIn;
|
||||
case TweenEasing::BackOut: return backOut;
|
||||
case TweenEasing::BackInOut: return backInOut;
|
||||
case TweenEasing::BounceIn: return bounceIn;
|
||||
case TweenEasing::BounceOut: return bounceOut;
|
||||
case TweenEasing::BounceInOut: return bounceInOut;
|
||||
case TweenEasing::Smooth: return smooth;
|
||||
case TweenEasing::Fade: return fade;
|
||||
default: return linear;
|
||||
}
|
||||
}
|
||||
|
||||
float EasingFunctions::linear(float t) {
|
||||
return t;
|
||||
}
|
||||
|
||||
float EasingFunctions::quadIn(float t) {
|
||||
return t * t;
|
||||
}
|
||||
|
||||
float EasingFunctions::quadOut(float t) {
|
||||
return t * (2.0f - t);
|
||||
}
|
||||
|
||||
float EasingFunctions::quadInOut(float t) {
|
||||
if (t < 0.5f) {
|
||||
return 2.0f * t * t;
|
||||
}
|
||||
return -1.0f + (4.0f - 2.0f * t) * t;
|
||||
}
|
||||
|
||||
float EasingFunctions::cubicIn(float t) {
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
float EasingFunctions::cubicOut(float t) {
|
||||
float t1 = t - 1.0f;
|
||||
return t1 * t1 * t1 + 1.0f;
|
||||
}
|
||||
|
||||
float EasingFunctions::cubicInOut(float t) {
|
||||
if (t < 0.5f) {
|
||||
return 4.0f * t * t * t;
|
||||
}
|
||||
float t1 = 2.0f * t - 2.0f;
|
||||
return 0.5f * t1 * t1 * t1 + 1.0f;
|
||||
}
|
||||
|
||||
float EasingFunctions::quartIn(float t) {
|
||||
return t * t * t * t;
|
||||
}
|
||||
|
||||
float EasingFunctions::quartOut(float t) {
|
||||
float t1 = t - 1.0f;
|
||||
return 1.0f - t1 * t1 * t1 * t1;
|
||||
}
|
||||
|
||||
float EasingFunctions::quartInOut(float t) {
|
||||
if (t < 0.5f) {
|
||||
return 8.0f * t * t * t * t;
|
||||
}
|
||||
float t1 = t - 1.0f;
|
||||
return 1.0f - 8.0f * t1 * t1 * t1 * t1;
|
||||
}
|
||||
|
||||
float EasingFunctions::quintIn(float t) {
|
||||
return t * t * t * t * t;
|
||||
}
|
||||
|
||||
float EasingFunctions::quintOut(float t) {
|
||||
float t1 = t - 1.0f;
|
||||
return t1 * t1 * t1 * t1 * t1 + 1.0f;
|
||||
}
|
||||
|
||||
float EasingFunctions::quintInOut(float t) {
|
||||
if (t < 0.5f) {
|
||||
return 16.0f * t * t * t * t * t;
|
||||
}
|
||||
float t1 = 2.0f * t - 2.0f;
|
||||
return 0.5f * t1 * t1 * t1 * t1 * t1 + 1.0f;
|
||||
}
|
||||
|
||||
float EasingFunctions::sineIn(float t) {
|
||||
return 1.0f - std::cos(t * HALF_PI);
|
||||
}
|
||||
|
||||
float EasingFunctions::sineOut(float t) {
|
||||
return std::sin(t * HALF_PI);
|
||||
}
|
||||
|
||||
float EasingFunctions::sineInOut(float t) {
|
||||
return -0.5f * (std::cos(PI * t) - 1.0f);
|
||||
}
|
||||
|
||||
float EasingFunctions::expoIn(float t) {
|
||||
return t == 0.0f ? 0.0f : std::pow(2.0f, 10.0f * (t - 1.0f));
|
||||
}
|
||||
|
||||
float EasingFunctions::expoOut(float t) {
|
||||
return t == 1.0f ? 1.0f : 1.0f - std::pow(2.0f, -10.0f * t);
|
||||
}
|
||||
|
||||
float EasingFunctions::expoInOut(float t) {
|
||||
if (t == 0.0f) return 0.0f;
|
||||
if (t == 1.0f) return 1.0f;
|
||||
if (t < 0.5f) {
|
||||
return 0.5f * std::pow(2.0f, 20.0f * t - 10.0f);
|
||||
}
|
||||
return 1.0f - 0.5f * std::pow(2.0f, -20.0f * t + 10.0f);
|
||||
}
|
||||
|
||||
float EasingFunctions::circIn(float t) {
|
||||
return 1.0f - std::sqrt(1.0f - t * t);
|
||||
}
|
||||
|
||||
float EasingFunctions::circOut(float t) {
|
||||
return std::sqrt(2.0f * t - t * t);
|
||||
}
|
||||
|
||||
float EasingFunctions::circInOut(float t) {
|
||||
if (t < 0.5f) {
|
||||
return 0.5f * (1.0f - std::sqrt(1.0f - 4.0f * t * t));
|
||||
}
|
||||
return 0.5f * (std::sqrt(4.0f * t - 4.0f * t * t - 3.0f) + 1.0f);
|
||||
}
|
||||
|
||||
float EasingFunctions::elasticIn(float t) {
|
||||
if (t == 0.0f) return 0.0f;
|
||||
if (t == 1.0f) return 1.0f;
|
||||
return -std::pow(2.0f, 10.0f * (t - 1.0f)) * std::sin((t - 1.1f) * ELASTIC_CONST);
|
||||
}
|
||||
|
||||
float EasingFunctions::elasticOut(float t) {
|
||||
if (t == 0.0f) return 0.0f;
|
||||
if (t == 1.0f) return 1.0f;
|
||||
return std::pow(2.0f, -10.0f * t) * std::sin((t - 0.1f) * ELASTIC_CONST) + 1.0f;
|
||||
}
|
||||
|
||||
float EasingFunctions::elasticInOut(float t) {
|
||||
if (t == 0.0f) return 0.0f;
|
||||
if (t == 1.0f) return 1.0f;
|
||||
if (t < 0.5f) {
|
||||
return -0.5f * std::pow(2.0f, 20.0f * t - 10.0f) * std::sin((20.0f * t - 11.125f) * PI / 4.5f);
|
||||
}
|
||||
return std::pow(2.0f, -20.0f * t + 10.0f) * std::sin((20.0f * t - 11.125f) * PI / 4.5f) * 0.5f + 1.0f;
|
||||
}
|
||||
|
||||
float EasingFunctions::backIn(float t) {
|
||||
return t * t * ((BACK_CONST + 1.0f) * t - BACK_CONST);
|
||||
}
|
||||
|
||||
float EasingFunctions::backOut(float t) {
|
||||
float t1 = t - 1.0f;
|
||||
return t1 * t1 * ((BACK_CONST + 1.0f) * t1 + BACK_CONST) + 1.0f;
|
||||
}
|
||||
|
||||
float EasingFunctions::backInOut(float t) {
|
||||
float s = BACK_CONST * 1.525f;
|
||||
if (t < 0.5f) {
|
||||
return 0.5f * (t * 2.0f) * (t * 2.0f) * ((s + 1.0f) * 2.0f * t - s);
|
||||
}
|
||||
float t1 = 2.0f * t - 2.0f;
|
||||
return 0.5f * (t1 * t1 * ((s + 1.0f) * t1 + s) + 2.0f);
|
||||
}
|
||||
|
||||
float EasingFunctions::bounceIn(float t) {
|
||||
return 1.0f - bounceOut(1.0f - t);
|
||||
}
|
||||
|
||||
float EasingFunctions::bounceOut(float t) {
|
||||
if (t < 1.0f / 2.75f) {
|
||||
return 7.5625f * t * t;
|
||||
} else if (t < 2.0f / 2.75f) {
|
||||
float t1 = t - 1.5f / 2.75f;
|
||||
return 7.5625f * t1 * t1 + 0.75f;
|
||||
} else if (t < 2.5f / 2.75f) {
|
||||
float t1 = t - 2.25f / 2.75f;
|
||||
return 7.5625f * t1 * t1 + 0.9375f;
|
||||
} else {
|
||||
float t1 = t - 2.625f / 2.75f;
|
||||
return 7.5625f * t1 * t1 + 0.984375f;
|
||||
}
|
||||
}
|
||||
|
||||
float EasingFunctions::bounceInOut(float t) {
|
||||
if (t < 0.5f) {
|
||||
return 0.5f * bounceIn(t * 2.0f);
|
||||
}
|
||||
return 0.5f * bounceOut(t * 2.0f - 1.0f) + 0.5f;
|
||||
}
|
||||
|
||||
float EasingFunctions::smooth(float t) {
|
||||
return t * t * (3.0f - 2.0f * t);
|
||||
}
|
||||
|
||||
float EasingFunctions::fade(float t) {
|
||||
return t * t * t * (t * (6.0f * t - 15.0f) + 10.0f);
|
||||
}
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
#include <audio/audio_engine.h>
|
||||
#include <event/event_dispatcher.h>
|
||||
#include <event/event_queue.h>
|
||||
#include <graphics/camera.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/camera.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <graphics/vram_manager.h>
|
||||
#include <platform/input.h>
|
||||
#include <platform/window.h>
|
||||
|
|
@ -382,14 +382,11 @@ EventDispatcher &Application::eventDispatcher() { return *eventDispatcher_; }
|
|||
|
||||
Camera &Application::camera() { return *camera_; }
|
||||
|
||||
void Application::enterScene(Ptr<Scene> scene) { enterScene(scene, nullptr); }
|
||||
|
||||
void Application::enterScene(Ptr<Scene> scene,
|
||||
Ptr<class TransitionScene> transitionScene) {
|
||||
void Application::enterScene(Ptr<Scene> scene) {
|
||||
if (sceneManager_ && scene) {
|
||||
scene->setViewportSize(static_cast<float>(window_->width()),
|
||||
static_cast<float>(window_->height()));
|
||||
sceneManager_->enterScene(scene, transitionScene);
|
||||
sceneManager_->enterScene(scene);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include <algorithm>
|
||||
#include <graphics/camera.h>
|
||||
#include <renderer/camera.h>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
namespace extra2d {
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#include <graphics/opengl/gl_renderer.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include <graphics/render_command.h>
|
||||
#include <renderer/render_command.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace extra2d {
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include <glad/glad.h>
|
||||
#include <graphics/opengl/gl_texture.h>
|
||||
#include <graphics/render_target.h>
|
||||
#include <renderer/render_target.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include <graphics/shader_preset.h>
|
||||
#include <renderer/shader_preset.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#include <core/color.h>
|
||||
#include <graphics/shader_system.h>
|
||||
#include <renderer/shader_system.h>
|
||||
#include <utils/logger.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
#include <algorithm>
|
||||
#include <animation/tween.h>
|
||||
#include <cmath>
|
||||
#include <graphics/render_command.h>
|
||||
#include <renderer/render_command.h>
|
||||
#include <scene/node.h>
|
||||
#include <scene/scene.h>
|
||||
#include <utils/logger.h>
|
||||
|
|
@ -330,7 +329,6 @@ void Node::onExit() {
|
|||
}
|
||||
|
||||
void Node::onUpdate(float dt) {
|
||||
updateTweens(dt);
|
||||
onUpdateNode(dt);
|
||||
|
||||
// Update children
|
||||
|
|
@ -431,142 +429,4 @@ void Node::collectRenderCommands(std::vector<RenderCommand> &commands,
|
|||
}
|
||||
}
|
||||
|
||||
Tween &Node::tween() {
|
||||
auto tw = std::make_shared<Tween>(this);
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
Tween &Node::tween(const std::string &name) {
|
||||
auto tw = std::make_shared<Tween>(this, name);
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
Tween &Node::moveTo(const Vec2 &pos, float duration, TweenEasing easing) {
|
||||
TweenProperty props;
|
||||
props.position = pos;
|
||||
TweenOptions options;
|
||||
options.easing = easing;
|
||||
auto tw = std::make_shared<Tween>(this);
|
||||
tw->to(duration, props, options);
|
||||
tw->start();
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
Tween &Node::moveBy(const Vec2 &delta, float duration, TweenEasing easing) {
|
||||
TweenProperty props;
|
||||
props.position = delta;
|
||||
TweenOptions options;
|
||||
options.easing = easing;
|
||||
auto tw = std::make_shared<Tween>(this);
|
||||
tw->by(duration, props, options);
|
||||
tw->start();
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
Tween &Node::scaleTo(float scale, float duration, TweenEasing easing) {
|
||||
TweenProperty props;
|
||||
props.scale = Vec2(scale, scale);
|
||||
TweenOptions options;
|
||||
options.easing = easing;
|
||||
auto tw = std::make_shared<Tween>(this);
|
||||
tw->to(duration, props, options);
|
||||
tw->start();
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
Tween &Node::scaleBy(float delta, float duration, TweenEasing easing) {
|
||||
TweenProperty props;
|
||||
props.scale = Vec2(delta, delta);
|
||||
TweenOptions options;
|
||||
options.easing = easing;
|
||||
auto tw = std::make_shared<Tween>(this);
|
||||
tw->by(duration, props, options);
|
||||
tw->start();
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
Tween &Node::rotateTo(float degrees, float duration, TweenEasing easing) {
|
||||
TweenProperty props;
|
||||
props.rotation = degrees;
|
||||
TweenOptions options;
|
||||
options.easing = easing;
|
||||
auto tw = std::make_shared<Tween>(this);
|
||||
tw->to(duration, props, options);
|
||||
tw->start();
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
Tween &Node::rotateBy(float degrees, float duration, TweenEasing easing) {
|
||||
TweenProperty props;
|
||||
props.rotation = degrees;
|
||||
TweenOptions options;
|
||||
options.easing = easing;
|
||||
auto tw = std::make_shared<Tween>(this);
|
||||
tw->by(duration, props, options);
|
||||
tw->start();
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
Tween &Node::fadeIn(float duration, TweenEasing easing) {
|
||||
TweenProperty props;
|
||||
props.opacity = 1.0f;
|
||||
TweenOptions options;
|
||||
options.easing = easing;
|
||||
auto tw = std::make_shared<Tween>(this);
|
||||
tw->to(duration, props, options);
|
||||
tw->start();
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
Tween &Node::fadeOut(float duration, TweenEasing easing) {
|
||||
TweenProperty props;
|
||||
props.opacity = 0.0f;
|
||||
TweenOptions options;
|
||||
options.easing = easing;
|
||||
auto tw = std::make_shared<Tween>(this);
|
||||
tw->to(duration, props, options);
|
||||
tw->start();
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
Tween &Node::fadeTo(float opacity, float duration, TweenEasing easing) {
|
||||
TweenProperty props;
|
||||
props.opacity = opacity;
|
||||
TweenOptions options;
|
||||
options.easing = easing;
|
||||
auto tw = std::make_shared<Tween>(this);
|
||||
tw->to(duration, props, options);
|
||||
tw->start();
|
||||
tweens_.push_back(tw);
|
||||
return *tweens_.back();
|
||||
}
|
||||
|
||||
void Node::stopAllTweens() {
|
||||
for (auto &tw : tweens_) {
|
||||
tw->stop();
|
||||
}
|
||||
tweens_.clear();
|
||||
}
|
||||
|
||||
void Node::updateTweens(float dt) {
|
||||
for (auto it = tweens_.begin(); it != tweens_.end();) {
|
||||
(*it)->update(dt);
|
||||
if ((*it)->isFinished()) {
|
||||
it = tweens_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include <graphics/render_command.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/render_command.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <scene/scene.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,9 @@
|
|||
#include <algorithm>
|
||||
#include <app/application.h>
|
||||
#include <graphics/render_command.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/render_command.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <platform/input.h>
|
||||
#include <scene/scene_manager.h>
|
||||
#include <scene/transition_box_scene.h>
|
||||
#include <scene/transition_fade_scene.h>
|
||||
#include <scene/transition_flip_scene.h>
|
||||
#include <scene/transition_scale_scene.h>
|
||||
#include <scene/transition_scene.h>
|
||||
#include <scene/transition_slide_scene.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
|
||||
|
|
@ -76,7 +70,7 @@ void SceneManager::runWithScene(Ptr<Scene> scene) {
|
|||
}
|
||||
|
||||
void SceneManager::replaceScene(Ptr<Scene> scene) {
|
||||
if (!scene || isTransitioning_) {
|
||||
if (!scene) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +92,7 @@ void SceneManager::replaceScene(Ptr<Scene> scene) {
|
|||
}
|
||||
|
||||
void SceneManager::enterScene(Ptr<Scene> scene) {
|
||||
if (!scene || isTransitioning_) {
|
||||
if (!scene) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -109,112 +103,8 @@ void SceneManager::enterScene(Ptr<Scene> scene) {
|
|||
}
|
||||
}
|
||||
|
||||
void SceneManager::enterScene(Ptr<Scene> scene,
|
||||
Ptr<TransitionScene> transitionScene) {
|
||||
if (!scene || isTransitioning_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果没有过渡场景,使用无过渡切换
|
||||
if (!transitionScene) {
|
||||
enterScene(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
auto current = getCurrentScene();
|
||||
if (!current) {
|
||||
enterScene(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
// 在过渡开始前,发送 UIHoverExit 给当前悬停的节点,重置按钮状态
|
||||
if (hoverTarget_) {
|
||||
Event evt;
|
||||
evt.type = EventType::UIHoverExit;
|
||||
evt.data = CustomEvent{0, hoverTarget_};
|
||||
dispatchToNode(hoverTarget_, evt);
|
||||
hoverTarget_ = nullptr;
|
||||
}
|
||||
captureTarget_ = nullptr;
|
||||
hasLastPointerWorld_ = false;
|
||||
|
||||
// 设置过渡场景
|
||||
transitionScene->setOutScene(current);
|
||||
transitionScene->setFinishCallback([this]() { finishTransition(); });
|
||||
|
||||
// 暂停当前场景
|
||||
current->pause();
|
||||
|
||||
// 推入过渡场景(作为中介场景)
|
||||
transitionScene->onEnter();
|
||||
transitionScene->onAttachToScene(transitionScene.get());
|
||||
sceneStack_.push(transitionScene);
|
||||
|
||||
isTransitioning_ = true;
|
||||
activeTransitionScene_ = transitionScene;
|
||||
transitionStackAction_ = [this, transitionScene]() {
|
||||
// 退出旧场景
|
||||
auto outScene = transitionScene->getOutScene();
|
||||
if (!sceneStack_.empty() && outScene) {
|
||||
// 过渡场景已经在栈顶,弹出它
|
||||
if (sceneStack_.top().get() == transitionScene.get()) {
|
||||
sceneStack_.pop();
|
||||
}
|
||||
outScene->onExit();
|
||||
outScene->onDetachFromScene();
|
||||
}
|
||||
|
||||
// 推入新场景
|
||||
auto inScene = transitionScene->getInScene();
|
||||
if (inScene) {
|
||||
inScene->onAttachToScene(inScene.get());
|
||||
sceneStack_.push(inScene);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void SceneManager::replaceScene(Ptr<Scene> scene, TransitionType transition,
|
||||
float duration) {
|
||||
if (!scene || isTransitioning_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sceneStack_.empty()) {
|
||||
runWithScene(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
auto oldScene = sceneStack_.top();
|
||||
|
||||
startTransition(oldScene, scene, transition, duration, [this]() {
|
||||
// 过渡完成后,退出旧场景并从堆栈中移除
|
||||
if (!sceneStack_.empty() && activeTransitionScene_) {
|
||||
// 弹出过渡场景
|
||||
if (sceneStack_.top().get() == activeTransitionScene_.get()) {
|
||||
sceneStack_.pop();
|
||||
}
|
||||
|
||||
// 退出旧场景
|
||||
auto outScene = activeTransitionScene_->getOutScene();
|
||||
if (outScene) {
|
||||
outScene->onExit();
|
||||
outScene->onDetachFromScene();
|
||||
}
|
||||
}
|
||||
|
||||
// 将新场景推入堆栈
|
||||
if (activeTransitionScene_) {
|
||||
auto inScene = activeTransitionScene_->getInScene();
|
||||
if (inScene) {
|
||||
inScene->onAttachToScene(inScene.get());
|
||||
sceneStack_.push(inScene);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SceneManager::pushScene(Ptr<Scene> scene) {
|
||||
if (!scene || isTransitioning_) {
|
||||
if (!scene) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -229,43 +119,8 @@ void SceneManager::pushScene(Ptr<Scene> scene) {
|
|||
sceneStack_.push(scene);
|
||||
}
|
||||
|
||||
void SceneManager::pushScene(Ptr<Scene> scene, TransitionType transition,
|
||||
float duration) {
|
||||
if (!scene || isTransitioning_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sceneStack_.empty()) {
|
||||
runWithScene(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
// 暂停当前场景
|
||||
sceneStack_.top()->pause();
|
||||
|
||||
auto currentScene = sceneStack_.top();
|
||||
|
||||
startTransition(currentScene, scene, transition, duration, [this]() {
|
||||
// 过渡完成后,将新场景推入堆栈
|
||||
if (!sceneStack_.empty() && activeTransitionScene_) {
|
||||
// 弹出过渡场景
|
||||
if (sceneStack_.top().get() == activeTransitionScene_.get()) {
|
||||
sceneStack_.pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (activeTransitionScene_) {
|
||||
auto inScene = activeTransitionScene_->getInScene();
|
||||
if (inScene) {
|
||||
inScene->onAttachToScene(inScene.get());
|
||||
sceneStack_.push(inScene);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SceneManager::popScene() {
|
||||
if (sceneStack_.size() <= 1 || isTransitioning_) {
|
||||
if (sceneStack_.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -280,42 +135,8 @@ void SceneManager::popScene() {
|
|||
}
|
||||
}
|
||||
|
||||
void SceneManager::popScene(TransitionType transition, float duration) {
|
||||
if (sceneStack_.size() <= 1 || isTransitioning_) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto current = sceneStack_.top();
|
||||
auto previous = getPreviousScene();
|
||||
|
||||
startTransition(current, previous, transition, duration, [this]() {
|
||||
// 过渡完成后,退出当前场景并从堆栈中移除
|
||||
if (!sceneStack_.empty() && activeTransitionScene_) {
|
||||
// 弹出过渡场景
|
||||
if (sceneStack_.top().get() == activeTransitionScene_.get()) {
|
||||
sceneStack_.pop();
|
||||
}
|
||||
|
||||
// 退出当前场景
|
||||
auto outScene = activeTransitionScene_->getOutScene();
|
||||
if (outScene) {
|
||||
outScene->onExit();
|
||||
outScene->onDetachFromScene();
|
||||
}
|
||||
}
|
||||
|
||||
// 恢复前一个场景
|
||||
if (activeTransitionScene_) {
|
||||
auto inScene = activeTransitionScene_->getInScene();
|
||||
if (inScene && !sceneStack_.empty() && sceneStack_.top() == inScene) {
|
||||
inScene->resume();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SceneManager::popToRootScene() {
|
||||
if (sceneStack_.size() <= 1 || isTransitioning_) {
|
||||
if (sceneStack_.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -331,35 +152,7 @@ void SceneManager::popToRootScene() {
|
|||
sceneStack_.top()->resume();
|
||||
}
|
||||
|
||||
void SceneManager::popToRootScene(TransitionType transition, float duration) {
|
||||
if (sceneStack_.size() <= 1 || isTransitioning_) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto root = getRootScene();
|
||||
auto current = sceneStack_.top();
|
||||
|
||||
startTransition(current, root, transition, duration, [this, root]() {
|
||||
// 退出所有场景直到根场景
|
||||
while (!sceneStack_.empty() && sceneStack_.top().get() != root.get()) {
|
||||
auto scene = sceneStack_.top();
|
||||
scene->onExit();
|
||||
scene->onDetachFromScene();
|
||||
sceneStack_.pop();
|
||||
}
|
||||
|
||||
// 恢复根场景
|
||||
if (!sceneStack_.empty() && sceneStack_.top().get() == root.get()) {
|
||||
root->resume();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SceneManager::popToScene(const std::string &name) {
|
||||
if (isTransitioning_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find target scene in stack
|
||||
std::stack<Ptr<Scene>> tempStack;
|
||||
Ptr<Scene> target = nullptr;
|
||||
|
|
@ -380,33 +173,6 @@ void SceneManager::popToScene(const std::string &name) {
|
|||
}
|
||||
}
|
||||
|
||||
void SceneManager::popToScene(const std::string &name,
|
||||
TransitionType transition, float duration) {
|
||||
if (isTransitioning_) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto target = getSceneByName(name);
|
||||
if (target && target != sceneStack_.top()) {
|
||||
auto current = sceneStack_.top();
|
||||
|
||||
startTransition(current, target, transition, duration, [this, target]() {
|
||||
// 退出所有场景直到目标场景
|
||||
while (!sceneStack_.empty() && sceneStack_.top() != target) {
|
||||
auto scene = sceneStack_.top();
|
||||
scene->onExit();
|
||||
scene->onDetachFromScene();
|
||||
sceneStack_.pop();
|
||||
}
|
||||
|
||||
// 恢复目标场景
|
||||
if (!sceneStack_.empty() && sceneStack_.top() == target) {
|
||||
target->resume();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<Scene> SceneManager::getCurrentScene() const {
|
||||
if (sceneStack_.empty()) {
|
||||
return nullptr;
|
||||
|
|
@ -464,19 +230,10 @@ bool SceneManager::hasScene(const std::string &name) const {
|
|||
}
|
||||
|
||||
void SceneManager::update(float dt) {
|
||||
if (isTransitioning_) {
|
||||
// 过渡场景在栈顶,正常更新即可
|
||||
hoverTarget_ = nullptr;
|
||||
captureTarget_ = nullptr;
|
||||
hasLastPointerWorld_ = false;
|
||||
}
|
||||
|
||||
if (!sceneStack_.empty()) {
|
||||
auto &scene = *sceneStack_.top();
|
||||
scene.updateScene(dt);
|
||||
if (!isTransitioning_) {
|
||||
dispatchPointerEvents(scene);
|
||||
}
|
||||
dispatchPointerEvents(scene);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -519,114 +276,6 @@ void SceneManager::end() {
|
|||
|
||||
void SceneManager::purgeCachedScenes() { namedScenes_.clear(); }
|
||||
|
||||
void SceneManager::startTransition(Ptr<Scene> from, Ptr<Scene> to,
|
||||
TransitionType type, float duration,
|
||||
Function<void()> stackAction) {
|
||||
if (!from || !to) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建过渡场景
|
||||
auto transitionScene = createTransitionScene(type, duration, to);
|
||||
if (!transitionScene) {
|
||||
// 回退到无过渡切换
|
||||
replaceScene(to);
|
||||
return;
|
||||
}
|
||||
|
||||
// 在过渡开始前,发送 UIHoverExit 给当前悬停的节点,重置按钮状态
|
||||
if (hoverTarget_) {
|
||||
Event evt;
|
||||
evt.type = EventType::UIHoverExit;
|
||||
evt.data = CustomEvent{0, hoverTarget_};
|
||||
dispatchToNode(hoverTarget_, evt);
|
||||
hoverTarget_ = nullptr;
|
||||
}
|
||||
captureTarget_ = nullptr;
|
||||
hasLastPointerWorld_ = false;
|
||||
|
||||
// 设置过渡场景
|
||||
transitionScene->setOutScene(from);
|
||||
transitionScene->setFinishCallback([this]() { finishTransition(); });
|
||||
|
||||
// 暂停当前场景
|
||||
from->pause();
|
||||
|
||||
// 推入过渡场景(作为中介场景)
|
||||
transitionScene->onEnter();
|
||||
transitionScene->onAttachToScene(transitionScene.get());
|
||||
sceneStack_.push(transitionScene);
|
||||
|
||||
isTransitioning_ = true;
|
||||
currentTransition_ = type;
|
||||
activeTransitionScene_ = transitionScene;
|
||||
transitionStackAction_ = std::move(stackAction);
|
||||
}
|
||||
|
||||
Ptr<TransitionScene> SceneManager::createTransitionScene(TransitionType type,
|
||||
float duration,
|
||||
Ptr<Scene> inScene) {
|
||||
if (!inScene) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case TransitionType::Fade:
|
||||
return TransitionFadeScene::create(duration, inScene);
|
||||
case TransitionType::SlideLeft:
|
||||
return TransitionSlideScene::create(duration, inScene,
|
||||
TransitionDirection::Left);
|
||||
case TransitionType::SlideRight:
|
||||
return TransitionSlideScene::create(duration, inScene,
|
||||
TransitionDirection::Right);
|
||||
case TransitionType::SlideUp:
|
||||
return TransitionSlideScene::create(duration, inScene,
|
||||
TransitionDirection::Up);
|
||||
case TransitionType::SlideDown:
|
||||
return TransitionSlideScene::create(duration, inScene,
|
||||
TransitionDirection::Down);
|
||||
case TransitionType::Scale:
|
||||
return TransitionScaleScene::create(duration, inScene);
|
||||
case TransitionType::Flip:
|
||||
return TransitionFlipScene::create(duration, inScene);
|
||||
case TransitionType::Box:
|
||||
return TransitionBoxScene::create(duration, inScene);
|
||||
default:
|
||||
// 默认使用淡入淡出
|
||||
return TransitionFadeScene::create(duration, inScene);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneManager::finishTransition() {
|
||||
// 先保存当前悬停的节点,然后在 transitionStackAction_ 之后发送 UIHoverExit
|
||||
Node *lastHoverTarget = hoverTarget_;
|
||||
|
||||
isTransitioning_ = false;
|
||||
hoverTarget_ = nullptr;
|
||||
captureTarget_ = nullptr;
|
||||
hasLastPointerWorld_ = false;
|
||||
|
||||
if (transitionStackAction_) {
|
||||
transitionStackAction_();
|
||||
}
|
||||
|
||||
// 在 transitionStackAction_ 之后发送 UIHoverExit,确保旧场景仍然有效
|
||||
if (lastHoverTarget) {
|
||||
Event evt;
|
||||
evt.type = EventType::UIHoverExit;
|
||||
evt.data = CustomEvent{0, lastHoverTarget};
|
||||
dispatchToNode(lastHoverTarget, evt);
|
||||
}
|
||||
|
||||
activeTransitionScene_.reset();
|
||||
transitionStackAction_ = nullptr;
|
||||
|
||||
if (transitionCallback_) {
|
||||
transitionCallback_();
|
||||
transitionCallback_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneManager::dispatchPointerEvents(Scene &scene) {
|
||||
auto &input = Application::instance().input();
|
||||
Vec2 screenPos = input.getMousePosition();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <graphics/render_command.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <limits>
|
||||
#include <scene/shape_node.h>
|
||||
|
||||
#include <renderer/render_command.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <scene/shape.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
|
|
@ -110,17 +109,11 @@ Ptr<ShapeNode> ShapeNode::createFilledPolygon(const std::vector<Vec2> &points,
|
|||
return node;
|
||||
}
|
||||
|
||||
void ShapeNode::setPoints(const std::vector<Vec2> &points) {
|
||||
points_ = points;
|
||||
}
|
||||
void ShapeNode::setPoints(const std::vector<Vec2> &points) { points_ = points; }
|
||||
|
||||
void ShapeNode::addPoint(const Vec2 &point) {
|
||||
points_.push_back(point);
|
||||
}
|
||||
void ShapeNode::addPoint(const Vec2 &point) { points_.push_back(point); }
|
||||
|
||||
void ShapeNode::clearPoints() {
|
||||
points_.clear();
|
||||
}
|
||||
void ShapeNode::clearPoints() { points_.clear(); }
|
||||
|
||||
Rect ShapeNode::boundingBox() const {
|
||||
if (points_.empty()) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <graphics/render_command.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/render_command.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <graphics/texture.h>
|
||||
#include <scene/sprite.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
#include <algorithm>
|
||||
#include <app/application.h>
|
||||
#include <core/color.h>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <graphics/renderer.h>
|
||||
#include <scene/transition_box_scene.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
TransitionBoxScene::TransitionBoxScene(float duration, Ptr<Scene> inScene,
|
||||
int divisions)
|
||||
: TransitionScene(duration, inScene), divisions_(divisions) {}
|
||||
|
||||
Ptr<TransitionBoxScene>
|
||||
TransitionBoxScene::create(float duration, Ptr<Scene> inScene, int divisions) {
|
||||
return makePtr<TransitionBoxScene>(duration, inScene, divisions);
|
||||
}
|
||||
|
||||
void TransitionBoxScene::onTransitionStart() {
|
||||
// 方块过渡不需要特殊的初始化
|
||||
}
|
||||
|
||||
void TransitionBoxScene::renderContent(Renderer &renderer) {
|
||||
// 获取窗口大小
|
||||
auto &app = Application::instance();
|
||||
float windowWidth = static_cast<float>(app.window().width());
|
||||
float windowHeight = static_cast<float>(app.window().height());
|
||||
|
||||
// 更新进度
|
||||
elapsed_ += 1.0f / 60.0f;
|
||||
progress_ = duration_ > 0.0f ? std::min(1.0f, elapsed_ / duration_) : 1.0f;
|
||||
|
||||
// 先渲染新场景
|
||||
if (inScene_) {
|
||||
inScene_->renderContent(renderer);
|
||||
} else if (outScene_) {
|
||||
outScene_->renderContent(renderer);
|
||||
}
|
||||
|
||||
// 设置视口为整个窗口
|
||||
renderer.setViewport(0, 0, static_cast<int>(windowWidth),
|
||||
static_cast<int>(windowHeight));
|
||||
|
||||
// 计算要显示的方块数量
|
||||
int div = std::max(1, divisions_);
|
||||
int total = div * div;
|
||||
int visible = std::clamp(static_cast<int>(total * progress_), 0, total);
|
||||
|
||||
float cellW = windowWidth / static_cast<float>(div);
|
||||
float cellH = windowHeight / static_cast<float>(div);
|
||||
|
||||
// 设置正交投影
|
||||
glm::mat4 overlayVP =
|
||||
glm::ortho(0.0f, windowWidth, windowHeight, 0.0f, -1.0f, 1.0f);
|
||||
renderer.setViewProjection(overlayVP);
|
||||
|
||||
// 绘制剩余的方块(作为遮罩)
|
||||
for (int idx = visible; idx < total; ++idx) {
|
||||
int x = idx % div;
|
||||
int y = idx / div;
|
||||
renderer.fillRect(Rect(x * cellW, y * cellH, cellW + 1.0f, cellH + 1.0f),
|
||||
Colors::Black);
|
||||
}
|
||||
|
||||
// 检查是否完成
|
||||
if (progress_ >= 1.0f && !isFinished_) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
#include <app/application.h>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <graphics/render_target.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <scene/transition_fade_scene.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
TransitionFadeScene::TransitionFadeScene(float duration, Ptr<Scene> inScene,
|
||||
const Color &color)
|
||||
: TransitionScene(duration, inScene), maskColor_(color) {}
|
||||
|
||||
Ptr<TransitionFadeScene> TransitionFadeScene::create(float duration,
|
||||
Ptr<Scene> inScene,
|
||||
const Color &color) {
|
||||
return makePtr<TransitionFadeScene>(duration, inScene, color);
|
||||
}
|
||||
|
||||
void TransitionFadeScene::onTransitionStart() {
|
||||
E2D_LOG_DEBUG("TransitionFadeScene::onTransitionStart - 启动淡入淡出过渡");
|
||||
|
||||
// 使用一个定时器来更新进度
|
||||
// 由于我们没有直接的动作系统集成到 Scene,使用简单的 update 逻辑
|
||||
// 实际进度更新由 SceneManager 的 update 驱动
|
||||
}
|
||||
|
||||
void TransitionFadeScene::renderContent(Renderer &renderer) {
|
||||
// 获取窗口大小
|
||||
auto &app = Application::instance();
|
||||
float windowWidth = static_cast<float>(app.window().width());
|
||||
float windowHeight = static_cast<float>(app.window().height());
|
||||
|
||||
// 计算当前进度
|
||||
elapsed_ += 1.0f / 60.0f; // 假设 60fps,实际应该由 update 传递 dt
|
||||
progress_ = duration_ > 0.0f ? std::min(1.0f, elapsed_ / duration_) : 1.0f;
|
||||
|
||||
// 检查是否需要切换场景(进度过半时)
|
||||
if (!hasSwitched_ && progress_ >= 0.5f) {
|
||||
hideOutShowIn();
|
||||
}
|
||||
|
||||
// 根据进度渲染
|
||||
if (progress_ < 0.5f) {
|
||||
// 第一阶段:显示旧场景
|
||||
drawOutScene(renderer);
|
||||
} else {
|
||||
// 第二阶段:显示新场景
|
||||
drawInScene(renderer);
|
||||
}
|
||||
|
||||
// 绘制遮罩层
|
||||
// 计算遮罩透明度
|
||||
float maskAlpha;
|
||||
if (progress_ < 0.5f) {
|
||||
// 前半段:从透明到不透明
|
||||
maskAlpha = progress_ * 2.0f; // 0 -> 1
|
||||
} else {
|
||||
// 后半段:从不透明到透明
|
||||
maskAlpha = (1.0f - progress_) * 2.0f; // 1 -> 0
|
||||
}
|
||||
|
||||
// 设置视口为整个窗口
|
||||
renderer.setViewport(0, 0, static_cast<int>(windowWidth),
|
||||
static_cast<int>(windowHeight));
|
||||
|
||||
// 设置正交投影
|
||||
glm::mat4 overlayVP =
|
||||
glm::ortho(0.0f, windowWidth, windowHeight, 0.0f, -1.0f, 1.0f);
|
||||
renderer.setViewProjection(overlayVP);
|
||||
|
||||
// 绘制遮罩
|
||||
Color maskColor = maskColor_;
|
||||
maskColor.a = maskAlpha;
|
||||
renderer.fillRect(Rect(0.0f, 0.0f, windowWidth, windowHeight), maskColor);
|
||||
|
||||
// 检查是否完成
|
||||
if (progress_ >= 1.0f && !isFinished_) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
void TransitionFadeScene::hideOutShowIn() {
|
||||
hasSwitched_ = true;
|
||||
E2D_LOG_DEBUG("TransitionFadeScene::hideOutShowIn - 切换场景显示");
|
||||
}
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
#include <core/math_types.h>
|
||||
#include <graphics/camera.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <scene/transition_flip_scene.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
TransitionFlipScene::TransitionFlipScene(float duration, Ptr<Scene> inScene,
|
||||
Axis axis)
|
||||
: TransitionScene(duration, inScene), axis_(axis) {}
|
||||
|
||||
Ptr<TransitionFlipScene>
|
||||
TransitionFlipScene::create(float duration, Ptr<Scene> inScene, Axis axis) {
|
||||
return makePtr<TransitionFlipScene>(duration, inScene, axis);
|
||||
}
|
||||
|
||||
void TransitionFlipScene::onTransitionStart() {
|
||||
// 翻页过渡不需要特殊的初始化
|
||||
}
|
||||
|
||||
void TransitionFlipScene::renderContent(Renderer &renderer) {
|
||||
// 更新进度
|
||||
elapsed_ += 1.0f / 60.0f;
|
||||
progress_ = duration_ > 0.0f ? std::min(1.0f, elapsed_ / duration_) : 1.0f;
|
||||
|
||||
// 缓动函数
|
||||
float easeProgress = progress_ < 0.5f
|
||||
? 2.0f * progress_ * progress_
|
||||
: -1.0f + (4.0f - 2.0f * progress_) * progress_;
|
||||
|
||||
float angle = easeProgress * PI_F; // 180度翻转
|
||||
|
||||
if (progress_ < 0.5f) {
|
||||
// 前半段:翻转源场景
|
||||
if (outScene_) {
|
||||
float currentAngle = angle;
|
||||
|
||||
Camera *camera = outScene_->getActiveCamera();
|
||||
float originalRotation = camera ? camera->rot() : 0.0f;
|
||||
|
||||
if (axis_ == Axis::Horizontal) {
|
||||
// 水平轴翻转 - 模拟绕X轴旋转
|
||||
if (camera) {
|
||||
camera->setRotation(originalRotation + currentAngle * RAD_TO_DEG);
|
||||
}
|
||||
} else {
|
||||
// 垂直轴翻转 - 模拟绕Y轴旋转
|
||||
if (camera) {
|
||||
camera->setRotation(originalRotation - currentAngle * RAD_TO_DEG);
|
||||
}
|
||||
}
|
||||
|
||||
outScene_->renderContent(renderer);
|
||||
|
||||
if (camera) {
|
||||
camera->setRotation(originalRotation);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 后半段:翻转目标场景
|
||||
if (inScene_) {
|
||||
float currentAngle = angle - PI_F;
|
||||
|
||||
Camera *camera = inScene_->getActiveCamera();
|
||||
float originalRotation = camera ? camera->rot() : 0.0f;
|
||||
|
||||
if (axis_ == Axis::Horizontal) {
|
||||
if (camera) {
|
||||
camera->setRotation(originalRotation + currentAngle * RAD_TO_DEG);
|
||||
}
|
||||
} else {
|
||||
if (camera) {
|
||||
camera->setRotation(originalRotation - currentAngle * RAD_TO_DEG);
|
||||
}
|
||||
}
|
||||
|
||||
inScene_->renderContent(renderer);
|
||||
|
||||
if (camera) {
|
||||
camera->setRotation(originalRotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否完成
|
||||
if (progress_ >= 1.0f && !isFinished_) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
#include <algorithm>
|
||||
#include <graphics/camera.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <scene/transition_scale_scene.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
TransitionScaleScene::TransitionScaleScene(float duration, Ptr<Scene> inScene)
|
||||
: TransitionScene(duration, inScene) {}
|
||||
|
||||
Ptr<TransitionScaleScene> TransitionScaleScene::create(float duration,
|
||||
Ptr<Scene> inScene) {
|
||||
return makePtr<TransitionScaleScene>(duration, inScene);
|
||||
}
|
||||
|
||||
void TransitionScaleScene::onTransitionStart() {
|
||||
// 缩放过渡不需要特殊的初始化
|
||||
}
|
||||
|
||||
void TransitionScaleScene::renderContent(Renderer &renderer) {
|
||||
// 更新进度
|
||||
elapsed_ += 1.0f / 60.0f;
|
||||
progress_ = duration_ > 0.0f ? std::min(1.0f, elapsed_ / duration_) : 1.0f;
|
||||
|
||||
// 缓动函数
|
||||
float easeProgress = progress_ < 0.5f
|
||||
? 2.0f * progress_ * progress_
|
||||
: -1.0f + (4.0f - 2.0f * progress_) * progress_;
|
||||
|
||||
// 源场景:缩小消失
|
||||
if (outScene_) {
|
||||
float scale = std::max(0.01f, 1.0f - easeProgress);
|
||||
|
||||
Camera *camera = outScene_->getActiveCamera();
|
||||
float originalZoom = camera ? camera->getZoom() : 1.0f;
|
||||
|
||||
if (camera) {
|
||||
camera->setZoom(originalZoom * scale);
|
||||
}
|
||||
|
||||
outScene_->renderContent(renderer);
|
||||
|
||||
if (camera) {
|
||||
camera->setZoom(originalZoom);
|
||||
}
|
||||
}
|
||||
|
||||
// 目标场景:放大出现
|
||||
if (inScene_) {
|
||||
float scale = std::max(0.01f, easeProgress);
|
||||
|
||||
Camera *camera = inScene_->getActiveCamera();
|
||||
float originalZoom = camera ? camera->getZoom() : 1.0f;
|
||||
|
||||
if (camera) {
|
||||
camera->setZoom(originalZoom * scale);
|
||||
}
|
||||
|
||||
inScene_->renderContent(renderer);
|
||||
|
||||
if (camera) {
|
||||
camera->setZoom(originalZoom);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否完成
|
||||
if (progress_ >= 1.0f && !isFinished_) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
#include <graphics/renderer.h>
|
||||
#include <scene/transition_scene.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
TransitionScene::TransitionScene(float duration, Ptr<Scene> inScene)
|
||||
: duration_(duration), inScene_(inScene) {}
|
||||
|
||||
void TransitionScene::onEnter() {
|
||||
// 调用基类的 onEnter
|
||||
Scene::onEnter();
|
||||
|
||||
// 调用退出场景的 onExitTransitionDidStart
|
||||
if (outScene_) {
|
||||
outScene_->onExitTransitionDidStart();
|
||||
}
|
||||
|
||||
// 调用进入场景的 onEnter
|
||||
if (inScene_) {
|
||||
inScene_->onEnter();
|
||||
inScene_->onAttachToScene(inScene_.get());
|
||||
}
|
||||
|
||||
// 启动过渡
|
||||
onTransitionStart();
|
||||
}
|
||||
|
||||
void TransitionScene::onExit() {
|
||||
// 调用退出场景的 onExit
|
||||
if (outScene_) {
|
||||
outScene_->onExit();
|
||||
outScene_->onDetachFromScene();
|
||||
}
|
||||
|
||||
// 调用进入场景的 onEnterTransitionDidFinish
|
||||
if (inScene_) {
|
||||
inScene_->onEnterTransitionDidFinish();
|
||||
}
|
||||
|
||||
// 调用基类的 onExit
|
||||
Scene::onExit();
|
||||
}
|
||||
|
||||
void TransitionScene::finish() {
|
||||
if (isFinished_) {
|
||||
return;
|
||||
}
|
||||
|
||||
isFinished_ = true;
|
||||
|
||||
E2D_LOG_DEBUG("TransitionScene::finish - 过渡完成,切换到目标场景");
|
||||
|
||||
// 调用完成回调,通知 SceneManager 进行场景切换
|
||||
if (finishCallback_) {
|
||||
finishCallback_();
|
||||
}
|
||||
}
|
||||
|
||||
void TransitionScene::renderContent(Renderer &renderer) {
|
||||
// 在 TransitionScene 上渲染新旧两个子场景
|
||||
// 子类可以重写此方法来控制渲染顺序和效果
|
||||
|
||||
// 默认先渲染退出场景,再渲染进入场景(在上方)
|
||||
drawOutScene(renderer);
|
||||
drawInScene(renderer);
|
||||
}
|
||||
|
||||
void TransitionScene::drawOutScene(Renderer &renderer) {
|
||||
if (outScene_) {
|
||||
outScene_->renderContent(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
void TransitionScene::drawInScene(Renderer &renderer) {
|
||||
if (inScene_) {
|
||||
inScene_->renderContent(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
#include <graphics/camera.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <scene/transition_slide_scene.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
TransitionSlideScene::TransitionSlideScene(float duration, Ptr<Scene> inScene,
|
||||
TransitionDirection direction)
|
||||
: TransitionScene(duration, inScene), direction_(direction) {}
|
||||
|
||||
Ptr<TransitionSlideScene>
|
||||
TransitionSlideScene::create(float duration, Ptr<Scene> inScene,
|
||||
TransitionDirection direction) {
|
||||
return makePtr<TransitionSlideScene>(duration, inScene, direction);
|
||||
}
|
||||
|
||||
void TransitionSlideScene::onTransitionStart() {
|
||||
// 滑动过渡不需要特殊的初始化
|
||||
}
|
||||
|
||||
void TransitionSlideScene::renderContent(Renderer &renderer) {
|
||||
// 获取视口尺寸
|
||||
float screenWidth = 800.0f;
|
||||
float screenHeight = 600.0f;
|
||||
|
||||
if (outScene_) {
|
||||
Size viewportSize = outScene_->getViewportSize();
|
||||
if (viewportSize.width > 0 && viewportSize.height > 0) {
|
||||
screenWidth = viewportSize.width;
|
||||
screenHeight = viewportSize.height;
|
||||
}
|
||||
} else if (inScene_) {
|
||||
Size viewportSize = inScene_->getViewportSize();
|
||||
if (viewportSize.width > 0 && viewportSize.height > 0) {
|
||||
screenWidth = viewportSize.width;
|
||||
screenHeight = viewportSize.height;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新进度
|
||||
elapsed_ += 1.0f / 60.0f;
|
||||
progress_ = duration_ > 0.0f ? std::min(1.0f, elapsed_ / duration_) : 1.0f;
|
||||
|
||||
// 缓动函数
|
||||
float easeProgress = progress_ < 0.5f
|
||||
? 2.0f * progress_ * progress_
|
||||
: -1.0f + (4.0f - 2.0f * progress_) * progress_;
|
||||
|
||||
// 渲染退出场景(滑出)
|
||||
if (outScene_) {
|
||||
float offsetX = 0.0f;
|
||||
float offsetY = 0.0f;
|
||||
|
||||
switch (direction_) {
|
||||
case TransitionDirection::Left:
|
||||
offsetX = -screenWidth * easeProgress;
|
||||
break;
|
||||
case TransitionDirection::Right:
|
||||
offsetX = screenWidth * easeProgress;
|
||||
break;
|
||||
case TransitionDirection::Up:
|
||||
offsetY = -screenHeight * easeProgress;
|
||||
break;
|
||||
case TransitionDirection::Down:
|
||||
offsetY = screenHeight * easeProgress;
|
||||
break;
|
||||
}
|
||||
|
||||
Camera *camera = outScene_->getActiveCamera();
|
||||
Vec2 originalPos = camera ? camera->pos() : Vec2::Zero();
|
||||
|
||||
if (camera) {
|
||||
camera->setPosition(originalPos.x + offsetX, originalPos.y + offsetY);
|
||||
}
|
||||
|
||||
outScene_->renderContent(renderer);
|
||||
|
||||
if (camera) {
|
||||
camera->setPosition(originalPos);
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染进入场景(滑入)
|
||||
if (inScene_) {
|
||||
float offsetX = 0.0f;
|
||||
float offsetY = 0.0f;
|
||||
|
||||
switch (direction_) {
|
||||
case TransitionDirection::Left:
|
||||
offsetX = screenWidth * (1.0f - easeProgress);
|
||||
break;
|
||||
case TransitionDirection::Right:
|
||||
offsetX = -screenWidth * (1.0f - easeProgress);
|
||||
break;
|
||||
case TransitionDirection::Up:
|
||||
offsetY = screenHeight * (1.0f - easeProgress);
|
||||
break;
|
||||
case TransitionDirection::Down:
|
||||
offsetY = -screenHeight * (1.0f - easeProgress);
|
||||
break;
|
||||
}
|
||||
|
||||
Camera *camera = inScene_->getActiveCamera();
|
||||
Vec2 originalPos = camera ? camera->pos() : Vec2::Zero();
|
||||
|
||||
if (camera) {
|
||||
camera->setPosition(originalPos.x + offsetX, originalPos.y + offsetY);
|
||||
}
|
||||
|
||||
inScene_->renderContent(renderer);
|
||||
|
||||
if (camera) {
|
||||
camera->setPosition(originalPos);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否完成
|
||||
if (progress_ >= 1.0f && !isFinished_) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extra2d
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
#include <app/application.h>
|
||||
#include <cmath>
|
||||
#include <core/string.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <ui/button.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include <core/string.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <ui/check_box.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include <core/string.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <ui/label.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include <cmath>
|
||||
#include <core/string.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <ui/progress_bar.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include <core/string.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <ui/radio_button.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include <cmath>
|
||||
#include <core/string.h>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <ui/slider.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include <core/string.h>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <graphics/renderer.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <ui/text.h>
|
||||
|
||||
namespace extra2d {
|
||||
|
|
|
|||
Loading…
Reference in New Issue