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/string.h>
|
||||||
#include <core/types.h>
|
#include <core/types.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <platform/window.h>
|
#include <platform/window.h>
|
||||||
|
|
||||||
|
|
@ -86,8 +86,6 @@ public:
|
||||||
// 便捷方法
|
// 便捷方法
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void enterScene(Ptr<class Scene> scene);
|
void enterScene(Ptr<class Scene> scene);
|
||||||
void enterScene(Ptr<class Scene> scene,
|
|
||||||
Ptr<class TransitionScene> transitionScene);
|
|
||||||
|
|
||||||
float deltaTime() const { return deltaTime_; }
|
float deltaTime() const { return deltaTime_; }
|
||||||
float totalTime() const { return totalTime_; }
|
float totalTime() const { return totalTime_; }
|
||||||
|
|
|
||||||
|
|
@ -14,33 +14,23 @@
|
||||||
#include <platform/window.h>
|
#include <platform/window.h>
|
||||||
|
|
||||||
// Graphics
|
// Graphics
|
||||||
#include <graphics/camera.h>
|
|
||||||
#include <graphics/font.h>
|
#include <graphics/font.h>
|
||||||
#include <graphics/renderer.h>
|
|
||||||
#include <graphics/shader_system.h>
|
|
||||||
#include <graphics/texture.h>
|
#include <graphics/texture.h>
|
||||||
|
|
||||||
#include <graphics/render_target.h>
|
|
||||||
#include <graphics/vram_manager.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
|
// Scene
|
||||||
#include <scene/node.h>
|
#include <scene/node.h>
|
||||||
#include <scene/scene.h>
|
#include <scene/scene.h>
|
||||||
#include <scene/scene_manager.h>
|
#include <scene/scene_manager.h>
|
||||||
#include <scene/shape_node.h>
|
#include <scene/shape.h>
|
||||||
#include <scene/sprite.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
|
// UI
|
||||||
#include <ui/button.h>
|
#include <ui/button.h>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <graphics/opengl/gl_shader.h>
|
#include <graphics/opengl/gl_shader.h>
|
||||||
#include <graphics/opengl/gl_sprite_batch.h>
|
#include <graphics/opengl/gl_sprite_batch.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include <core/types.h>
|
#include <core/types.h>
|
||||||
#include <event/event_dispatcher.h>
|
#include <event/event_dispatcher.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -17,8 +17,6 @@ namespace extra2d {
|
||||||
class Scene;
|
class Scene;
|
||||||
class Renderer;
|
class Renderer;
|
||||||
struct RenderCommand;
|
struct RenderCommand;
|
||||||
class Tween;
|
|
||||||
enum class TweenEasing : uint8_t;
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// 节点基类 - 场景图的基础
|
// 节点基类 - 场景图的基础
|
||||||
|
|
@ -155,85 +153,6 @@ public:
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
EventDispatcher &getEventDispatcher() { return eventDispatcher_; }
|
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 visible_ = true; // 1 byte
|
||||||
bool running_ = false; // 1 byte
|
bool running_ = false; // 1 byte
|
||||||
|
|
||||||
// 10. Tween 动画列表
|
|
||||||
std::vector<std::shared_ptr<Tween>> tweens_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace extra2d
|
} // namespace extra2d
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <core/color.h>
|
#include <core/color.h>
|
||||||
#include <graphics/camera.h>
|
#include <renderer/camera.h>
|
||||||
#include <scene/node.h>
|
#include <scene/node.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -69,12 +69,7 @@ protected:
|
||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void onExit() override;
|
void onExit() override;
|
||||||
|
|
||||||
// 过渡场景生命周期回调(供 TransitionScene 使用)
|
|
||||||
virtual void onExitTransitionDidStart() {}
|
|
||||||
virtual void onEnterTransitionDidFinish() {}
|
|
||||||
|
|
||||||
friend class SceneManager;
|
friend class SceneManager;
|
||||||
friend class TransitionScene;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Color backgroundColor_ = Colors::Black;
|
Color backgroundColor_ = Colors::Black;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
#include <core/types.h>
|
#include <core/types.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <scene/scene.h>
|
#include <scene/scene.h>
|
||||||
#include <scene/transition_scene.h>
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
@ -14,15 +13,12 @@ namespace extra2d {
|
||||||
|
|
||||||
// 前向声明
|
// 前向声明
|
||||||
struct RenderCommand;
|
struct RenderCommand;
|
||||||
class TransitionScene;
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// 场景管理器 - 管理场景的生命周期和切换
|
// 场景管理器 - 管理场景的生命周期和切换
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class SceneManager {
|
class SceneManager {
|
||||||
public:
|
public:
|
||||||
using TransitionCallback = std::function<void()>;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// 单例访问
|
// 单例访问
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
@ -37,26 +33,18 @@ public:
|
||||||
|
|
||||||
// 替换当前场景
|
// 替换当前场景
|
||||||
void replaceScene(Ptr<Scene> scene);
|
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);
|
||||||
void pushScene(Ptr<Scene> scene, TransitionType transition,
|
|
||||||
float duration = 0.5f);
|
|
||||||
|
|
||||||
// 弹出当前场景(恢复上一个场景)
|
// 弹出当前场景(恢复上一个场景)
|
||||||
void popScene();
|
void popScene();
|
||||||
void popScene(TransitionType transition, float duration = 0.5f);
|
|
||||||
|
|
||||||
// 弹出到根场景
|
// 弹出到根场景
|
||||||
void popToRootScene();
|
void popToRootScene();
|
||||||
void popToRootScene(TransitionType transition, float duration = 0.5f);
|
|
||||||
|
|
||||||
// 弹出到指定场景
|
// 弹出到指定场景
|
||||||
void popToScene(const std::string &name);
|
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 render(Renderer &renderer);
|
||||||
void collectRenderCommands(std::vector<RenderCommand> &commands);
|
void collectRenderCommands(std::vector<RenderCommand> &commands);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// 过渡控制
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
bool isTransitioning() const { return isTransitioning_; }
|
|
||||||
void setTransitionCallback(TransitionCallback callback) {
|
|
||||||
transitionCallback_ = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// 清理
|
// 清理
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
@ -104,30 +84,14 @@ public:
|
||||||
|
|
||||||
// 场景切换(供 Application 使用)
|
// 场景切换(供 Application 使用)
|
||||||
void enterScene(Ptr<Scene> scene);
|
void enterScene(Ptr<Scene> scene);
|
||||||
void enterScene(Ptr<Scene> scene, Ptr<TransitionScene> transitionScene);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void doSceneSwitch();
|
void doSceneSwitch();
|
||||||
void startTransition(Ptr<Scene> from, Ptr<Scene> to, TransitionType type,
|
|
||||||
float duration, Function<void()> stackAction);
|
|
||||||
void finishTransition();
|
|
||||||
void dispatchPointerEvents(Scene &scene);
|
void dispatchPointerEvents(Scene &scene);
|
||||||
|
|
||||||
// 创建过渡场景
|
|
||||||
Ptr<TransitionScene> createTransitionScene(TransitionType type,
|
|
||||||
float duration,
|
|
||||||
Ptr<Scene> inScene);
|
|
||||||
|
|
||||||
std::stack<Ptr<Scene>> sceneStack_;
|
std::stack<Ptr<Scene>> sceneStack_;
|
||||||
std::unordered_map<std::string, Ptr<Scene>> namedScenes_;
|
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)
|
// Next scene to switch to (queued during transition)
|
||||||
Ptr<Scene> nextScene_;
|
Ptr<Scene> nextScene_;
|
||||||
bool sendCleanupToScene_ = false;
|
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 <audio/audio_engine.h>
|
||||||
#include <event/event_dispatcher.h>
|
#include <event/event_dispatcher.h>
|
||||||
#include <event/event_queue.h>
|
#include <event/event_queue.h>
|
||||||
#include <graphics/camera.h>
|
#include <renderer/camera.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <graphics/vram_manager.h>
|
#include <graphics/vram_manager.h>
|
||||||
#include <platform/input.h>
|
#include <platform/input.h>
|
||||||
#include <platform/window.h>
|
#include <platform/window.h>
|
||||||
|
|
@ -382,14 +382,11 @@ EventDispatcher &Application::eventDispatcher() { return *eventDispatcher_; }
|
||||||
|
|
||||||
Camera &Application::camera() { return *camera_; }
|
Camera &Application::camera() { return *camera_; }
|
||||||
|
|
||||||
void Application::enterScene(Ptr<Scene> scene) { enterScene(scene, nullptr); }
|
void Application::enterScene(Ptr<Scene> scene) {
|
||||||
|
|
||||||
void Application::enterScene(Ptr<Scene> scene,
|
|
||||||
Ptr<class TransitionScene> transitionScene) {
|
|
||||||
if (sceneManager_ && scene) {
|
if (sceneManager_ && scene) {
|
||||||
scene->setViewportSize(static_cast<float>(window_->width()),
|
scene->setViewportSize(static_cast<float>(window_->width()),
|
||||||
static_cast<float>(window_->height()));
|
static_cast<float>(window_->height()));
|
||||||
sceneManager_->enterScene(scene, transitionScene);
|
sceneManager_->enterScene(scene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <graphics/camera.h>
|
#include <renderer/camera.h>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include <graphics/opengl/gl_renderer.h>
|
#include <graphics/opengl/gl_renderer.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include <graphics/render_command.h>
|
#include <renderer/render_command.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <graphics/opengl/gl_texture.h>
|
#include <graphics/opengl/gl_texture.h>
|
||||||
#include <graphics/render_target.h>
|
#include <renderer/render_target.h>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
|
|
||||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include <graphics/shader_preset.h>
|
#include <renderer/shader_preset.h>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include <core/color.h>
|
#include <core/color.h>
|
||||||
#include <graphics/shader_system.h>
|
#include <renderer/shader_system.h>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <animation/tween.h>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <graphics/render_command.h>
|
#include <renderer/render_command.h>
|
||||||
#include <scene/node.h>
|
#include <scene/node.h>
|
||||||
#include <scene/scene.h>
|
#include <scene/scene.h>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
|
|
@ -330,7 +329,6 @@ void Node::onExit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::onUpdate(float dt) {
|
void Node::onUpdate(float dt) {
|
||||||
updateTweens(dt);
|
|
||||||
onUpdateNode(dt);
|
onUpdateNode(dt);
|
||||||
|
|
||||||
// Update children
|
// 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
|
} // namespace extra2d
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include <graphics/render_command.h>
|
#include <renderer/render_command.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <scene/scene.h>
|
#include <scene/scene.h>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,9 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <app/application.h>
|
#include <app/application.h>
|
||||||
#include <graphics/render_command.h>
|
#include <renderer/render_command.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <platform/input.h>
|
#include <platform/input.h>
|
||||||
#include <scene/scene_manager.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>
|
#include <utils/logger.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -76,7 +70,7 @@ void SceneManager::runWithScene(Ptr<Scene> scene) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::replaceScene(Ptr<Scene> scene) {
|
void SceneManager::replaceScene(Ptr<Scene> scene) {
|
||||||
if (!scene || isTransitioning_) {
|
if (!scene) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,7 +92,7 @@ void SceneManager::replaceScene(Ptr<Scene> scene) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::enterScene(Ptr<Scene> scene) {
|
void SceneManager::enterScene(Ptr<Scene> scene) {
|
||||||
if (!scene || isTransitioning_) {
|
if (!scene) {
|
||||||
return;
|
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) {
|
void SceneManager::pushScene(Ptr<Scene> scene) {
|
||||||
if (!scene || isTransitioning_) {
|
if (!scene) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,43 +119,8 @@ void SceneManager::pushScene(Ptr<Scene> scene) {
|
||||||
sceneStack_.push(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() {
|
void SceneManager::popScene() {
|
||||||
if (sceneStack_.size() <= 1 || isTransitioning_) {
|
if (sceneStack_.size() <= 1) {
|
||||||
return;
|
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() {
|
void SceneManager::popToRootScene() {
|
||||||
if (sceneStack_.size() <= 1 || isTransitioning_) {
|
if (sceneStack_.size() <= 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -331,35 +152,7 @@ void SceneManager::popToRootScene() {
|
||||||
sceneStack_.top()->resume();
|
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) {
|
void SceneManager::popToScene(const std::string &name) {
|
||||||
if (isTransitioning_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find target scene in stack
|
// Find target scene in stack
|
||||||
std::stack<Ptr<Scene>> tempStack;
|
std::stack<Ptr<Scene>> tempStack;
|
||||||
Ptr<Scene> target = nullptr;
|
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 {
|
Ptr<Scene> SceneManager::getCurrentScene() const {
|
||||||
if (sceneStack_.empty()) {
|
if (sceneStack_.empty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -464,21 +230,12 @@ bool SceneManager::hasScene(const std::string &name) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::update(float dt) {
|
void SceneManager::update(float dt) {
|
||||||
if (isTransitioning_) {
|
|
||||||
// 过渡场景在栈顶,正常更新即可
|
|
||||||
hoverTarget_ = nullptr;
|
|
||||||
captureTarget_ = nullptr;
|
|
||||||
hasLastPointerWorld_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sceneStack_.empty()) {
|
if (!sceneStack_.empty()) {
|
||||||
auto &scene = *sceneStack_.top();
|
auto &scene = *sceneStack_.top();
|
||||||
scene.updateScene(dt);
|
scene.updateScene(dt);
|
||||||
if (!isTransitioning_) {
|
|
||||||
dispatchPointerEvents(scene);
|
dispatchPointerEvents(scene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SceneManager::render(Renderer &renderer) {
|
void SceneManager::render(Renderer &renderer) {
|
||||||
Color clearColor = Colors::Black;
|
Color clearColor = Colors::Black;
|
||||||
|
|
@ -519,114 +276,6 @@ void SceneManager::end() {
|
||||||
|
|
||||||
void SceneManager::purgeCachedScenes() { namedScenes_.clear(); }
|
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) {
|
void SceneManager::dispatchPointerEvents(Scene &scene) {
|
||||||
auto &input = Application::instance().input();
|
auto &input = Application::instance().input();
|
||||||
Vec2 screenPos = input.getMousePosition();
|
Vec2 screenPos = input.getMousePosition();
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <graphics/render_command.h>
|
|
||||||
#include <graphics/renderer.h>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <scene/shape_node.h>
|
#include <renderer/render_command.h>
|
||||||
|
#include <renderer/renderer.h>
|
||||||
|
#include <scene/shape.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
|
|
@ -110,17 +109,11 @@ Ptr<ShapeNode> ShapeNode::createFilledPolygon(const std::vector<Vec2> &points,
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShapeNode::setPoints(const std::vector<Vec2> &points) {
|
void ShapeNode::setPoints(const std::vector<Vec2> &points) { points_ = points; }
|
||||||
points_ = points;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShapeNode::addPoint(const Vec2 &point) {
|
void ShapeNode::addPoint(const Vec2 &point) { points_.push_back(point); }
|
||||||
points_.push_back(point);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShapeNode::clearPoints() {
|
void ShapeNode::clearPoints() { points_.clear(); }
|
||||||
points_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect ShapeNode::boundingBox() const {
|
Rect ShapeNode::boundingBox() const {
|
||||||
if (points_.empty()) {
|
if (points_.empty()) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <graphics/render_command.h>
|
#include <renderer/render_command.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <graphics/texture.h>
|
#include <graphics/texture.h>
|
||||||
#include <scene/sprite.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 <app/application.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <core/string.h>
|
#include <core/string.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <ui/button.h>
|
#include <ui/button.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include <core/string.h>
|
#include <core/string.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <ui/check_box.h>
|
#include <ui/check_box.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include <core/string.h>
|
#include <core/string.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <ui/label.h>
|
#include <ui/label.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <core/string.h>
|
#include <core/string.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <ui/progress_bar.h>
|
#include <ui/progress_bar.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include <core/string.h>
|
#include <core/string.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <ui/radio_button.h>
|
#include <ui/radio_button.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <core/string.h>
|
#include <core/string.h>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <ui/slider.h>
|
#include <ui/slider.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include <core/string.h>
|
#include <core/string.h>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <graphics/renderer.h>
|
#include <renderer/renderer.h>
|
||||||
#include <ui/text.h>
|
#include <ui/text.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue