feat: 项目初始化 + 3D方块世界原型 + AI助搭系统
CI / Go Backend (push) Canceled after 0s

初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器

HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块

Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚

AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
This commit is contained in:
xyou
2026-08-08 14:07:56 +08:00
parent 9500c4c80a
commit f70b061d1a
1972 changed files with 159760 additions and 6 deletions
@@ -0,0 +1,13 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class BackEaseIn : Easing
{
public static BackEaseIn Shared { get; } = new();
protected override double EaseCore(double progress)
{
return progress * (progress * progress - Math.Sin(progress * Math.PI));
}
}
@@ -0,0 +1,22 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class BackEaseInOut : Easing
{
public static BackEaseInOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
if (progress < 0.5)
{
var f = 2 * progress;
return 0.5 * f * (f * f - Math.Sin(f * Math.PI));
}
else
{
var f = 1 - (2 * progress - 1);
return 0.5 * (1 - f * (f * f - Math.Sin(f * Math.PI))) + 0.5;
}
}
}
@@ -0,0 +1,14 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class BackEaseOut : Easing
{
public static BackEaseOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
var p = 1 - progress;
return 1 - p * (p * p - Math.Sin(p * Math.PI));
}
}
@@ -0,0 +1,14 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class BackEaseWithPowerIn(EasePower power = EasePower.Middle) : Easing
{
private readonly double _p = 3.0 - (double)power * 0.5;
protected override double EaseCore(double progress)
{
var t = Math.Clamp(progress, 0.0, 1.0);
return Math.Pow(t, _p) * Math.Cos(1.5 * Math.PI * (1.0 - t));
}
}
@@ -0,0 +1,25 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class BackEaseWithPowerInOut(EasePower power = EasePower.Middle) : Easing
{
private readonly double _p = 3.0 - (double)power * 0.5;
protected override double EaseCore(double progress)
{
var t = Math.Clamp(progress, 0.0, 1.0);
if (t < 0.5)
{
var f = 2.0 * t;
return 0.5 * (Math.Pow(f, _p) * Math.Cos(1.5 * Math.PI * (1.0 - f)));
}
else
{
var f = 2.0 * (t - 0.5);
var inv = 1.0 - f;
return 0.5 * (1.0 - Math.Pow(inv, _p) * Math.Cos(1.5 * Math.PI * f)) + 0.5;
}
}
}
@@ -0,0 +1,15 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class BackEaseWithPowerOut(EasePower power = EasePower.Middle) : Easing
{
private readonly double _p = 3.0 - (double)power * 0.5;
protected override double EaseCore(double progress)
{
var t = Math.Clamp(progress, 0.0, 1.0);
var inv = 1.0 - t;
return 1.0 - Math.Pow(inv, _p) * Math.Cos(1.5 * Math.PI * t);
}
}
@@ -0,0 +1,13 @@
using PCL.Core.Utils;
namespace PCL.Core.UI.Animation.Easings;
public class BounceEaseIn : Easing
{
public static BounceEaseIn Shared { get; } = new();
protected override double EaseCore(double progress)
{
return 1 - EaseUtils.Bounce(1 - progress);
}
}
@@ -0,0 +1,18 @@
using PCL.Core.Utils;
namespace PCL.Core.UI.Animation.Easings;
public class BounceEaseInOut : Easing
{
public static BounceEaseInOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
if (progress < 0.5)
{
return 0.5 * (1 - EaseUtils.Bounce(1 - progress * 2));
}
return 0.5 * EaseUtils.Bounce(progress * 2 - 1) + 0.5;
}
}
@@ -0,0 +1,13 @@
using PCL.Core.Utils;
namespace PCL.Core.UI.Animation.Easings;
public class BounceEaseOut : Easing
{
public static BounceEaseOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
return EaseUtils.Bounce(progress);
}
}
@@ -0,0 +1,13 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class CircularEaseIn : Easing
{
public static CircularEaseIn Shared { get; } = new();
protected override double EaseCore(double progress)
{
return 1 - Math.Sqrt(1d - progress * progress);
}
}
@@ -0,0 +1,19 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class CircularEaseInOut : Easing
{
public static CircularEaseInOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
if (progress < 0.5)
{
return 0.5 * (1 - Math.Sqrt(1 - 4 * progress * progress));
}
var t = 2 * progress;
return 0.5 * (Math.Sqrt((3 - t) * (t - 1)) + 1);
}
}
@@ -0,0 +1,13 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class CircularEaseOut : Easing
{
public static CircularEaseOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
return Math.Sqrt((2d - progress) * progress);
}
}
@@ -0,0 +1,21 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class CombinedEasing(IEasing ease1, IEasing ease2, double split = 0.5) : Easing
{
private readonly IEasing _ease1 = ease1 ?? throw new ArgumentNullException(nameof(ease1));
private readonly IEasing _ease2 = ease2 ?? throw new ArgumentNullException(nameof(ease2));
private readonly double _split = Math.Clamp(split, 0.00001, 0.99999);
protected override double EaseCore(double t)
{
if (t < _split)
{
return _split * _ease1.Ease(t / _split);
}
return (1.0 - _split) * _ease2.Ease((t - _split) / (1.0 - _split)) + _split;
}
}
@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PCL.Core.UI.Animation.Easings;
/// <summary>
/// 复合缓动,支持多个缓动混合,每个缓动可独立设置时长,延迟和权重。
/// </summary>
public class CompositeEasing : Easing
{
private readonly List<(IEasing easing, TimeSpan duration, TimeSpan delay, double weight)> _easings;
private readonly TimeSpan _totalDuration;
/// <summary>
/// 初始化复合缓动。
/// </summary>
/// <param name="easings">参数元组:(缓动逻辑, 持续时长)</param>
public CompositeEasing(params (IEasing easing, TimeSpan duration)[] easings)
: this(easings.Select(e => (e.easing, e.duration, TimeSpan.Zero, 1.0 / (easings.Length > 0 ? easings.Length : 1))).ToArray())
{
}
/// <summary>
/// 初始化复合缓动。
/// </summary>
/// <param name="easings">参数元组:(缓动逻辑, 持续时长, 延迟时间)</param>
public CompositeEasing(params (IEasing easing, TimeSpan duration, TimeSpan delay)[] easings)
: this(easings.Select(e => (e.easing, e.duration, e.delay, 1.0 / (easings.Length > 0 ? easings.Length : 1))).ToArray())
{
}
/// <summary>
/// 初始化复合缓动。
/// </summary>
/// <param name="easings">参数元组:(缓动逻辑, 持续时长, 权重)</param>
public CompositeEasing(params (IEasing easing, TimeSpan duration, double weight)[] easings)
: this(easings.Select(e => (e.easing, e.duration, TimeSpan.Zero, e.weight)).ToArray())
{
}
/// <summary>
/// 初始化复合缓动。
/// </summary>
/// <param name="easings">参数元组:(缓动逻辑, 持续时长, 延迟时间, 权重)</param>
public CompositeEasing(params (IEasing easing, TimeSpan duration, TimeSpan delay, double weight)[] easings)
{
if (easings is null || easings.Length == 0)
throw new ArgumentException("至少需要一个缓动", nameof(easings));
_easings = new List<(IEasing, TimeSpan, TimeSpan, double)>(easings.Length);
long maxTicks = 0;
foreach (var (easing, duration, delay, weight) in easings)
{
if (easing is null) throw new ArgumentNullException(nameof(easing));
if (duration <= TimeSpan.Zero) throw new ArgumentException("duration 必须大于 zero");
_easings.Add((easing, duration, delay, weight));
long endTicks = (delay + duration).Ticks;
if (endTicks > maxTicks)
maxTicks = endTicks;
}
_totalDuration = TimeSpan.FromTicks(maxTicks);
}
public TimeSpan TotalDuration => _totalDuration;
protected override double EaseCore(double progress)
{
// 计算当前绝对时间
var elapsed = _totalDuration * progress;
var value = 0.0;
foreach (var (easing, duration, delay, weight) in _easings)
{
if (weight == 0) continue;
// 计算相对于该缓动的时间
var localElapsed = elapsed - delay;
double easingValue;
// 还没开始
if (localElapsed <= TimeSpan.Zero)
{
easingValue = 0.0;
}
// 已经结束
else if (localElapsed >= duration)
{
// 保持最终状态
easingValue = easing.Ease(1.0);
}
// 正在运行
else
{
// 避免除法浮点数计算问题
var localProgress = localElapsed.TotalSeconds / duration.TotalSeconds;
easingValue = easing.Ease(localProgress);
}
value += easingValue * weight;
}
return value;
}
}
@@ -0,0 +1,11 @@
namespace PCL.Core.UI.Animation.Easings;
public class CubicEaseIn : Easing
{
public static CubicEaseIn Shared { get; } = new();
protected override double EaseCore(double progress)
{
return progress * progress * progress;
}
}
@@ -0,0 +1,17 @@
namespace PCL.Core.UI.Animation.Easings;
public class CubicEaseInOut : Easing
{
public static CubicEaseInOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
if (progress < 0.5)
{
return 4 * progress * progress * progress;
}
var f = 2 * (progress - 1);
return 0.5 * f * f * f + 1;
}
}
@@ -0,0 +1,12 @@
namespace PCL.Core.UI.Animation.Easings;
public class CubicEaseOut : Easing
{
public static CubicEaseOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
var f = progress - 1;
return f * f * f + 1;
}
}
@@ -0,0 +1,9 @@
namespace PCL.Core.UI.Animation.Easings;
public enum EasePower
{
Weak = 2,
Middle = 3,
Strong = 4,
ExtraStrong = 5
}
@@ -0,0 +1,24 @@
namespace PCL.Core.UI.Animation.Easings;
/// <summary>
/// 所有缓动类的基类。
/// </summary>
public abstract class Easing : IEasing
{
protected abstract double EaseCore(double progress);
public double Ease(double progress)
{
return progress switch
{
<= 0.0 => 0.0,
>= 1.0 => 1.0,
_ => EaseCore(progress)
};
}
public double Ease(int currentFrame, int totalFrames)
{
return totalFrames <= 1 ? 1.0 : Ease((double)currentFrame / (totalFrames - 1));
}
}
@@ -0,0 +1,15 @@
using System;
using PCL.Core.Utils;
namespace PCL.Core.UI.Animation.Easings;
public class ElasticEaseIn : Easing
{
public static ElasticEaseIn Shared { get; } = new();
protected override double EaseCore(double progress)
{
return Math.Sin(EaseUtils.ElasticPiTimes6Point5 * progress) *
Math.Exp(EaseUtils.ElasticLn2Times10 * (progress - 1d));
}
}
@@ -0,0 +1,25 @@
using System;
using PCL.Core.Utils;
namespace PCL.Core.UI.Animation.Easings;
public class ElasticEaseInOut : Easing
{
public static ElasticEaseInOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
if (progress < 0.5d)
{
var t = progress * 2d;
return 0.5d * Math.Sin(EaseUtils.ElasticPiTimes6Point5 * t) *
Math.Exp(EaseUtils.ElasticLn2Times10 * (t - 1d));
}
else
{
var t = progress * 2d - 1d;
return 0.5d * (Math.Sin(-EaseUtils.ElasticPiTimes6Point5 * (t + 1d)) *
Math.Exp(-EaseUtils.ElasticLn2Times10 * t) + 2d);
}
}
}
@@ -0,0 +1,15 @@
using System;
using PCL.Core.Utils;
namespace PCL.Core.UI.Animation.Easings;
public class ElasticEaseOut : Easing
{
public static ElasticEaseOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
return Math.Sin(-EaseUtils.ElasticPiTimes6Point5 * (progress + 1d)) *
Math.Exp(-EaseUtils.ElasticLn2Times10 * progress) + 1d;
}
}
@@ -0,0 +1,13 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class ExponentialEaseIn : Easing
{
public static ExponentialEaseIn Shared { get; } = new();
protected override double EaseCore(double progress)
{
return progress == 0 ? progress : Math.Pow(2, 10 * (progress - 1));
}
}
@@ -0,0 +1,18 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class ExponentialEaseInOut : Easing
{
public static ExponentialEaseInOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
if (progress < 0.5)
{
return 0.5 * Math.Pow(2, 20 * progress - 10);
}
return -0.5 * Math.Pow(2, -20 * progress + 10) + 1;
}
}
@@ -0,0 +1,13 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class ExponentialEaseOut : Easing
{
public static ExponentialEaseOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
return Math.Abs(progress - 1.0) < 1e-4 ? progress : 1 - Math.Pow(2, -10 * progress);
}
}
@@ -0,0 +1,26 @@
using System.ComponentModel;
using PCL.Core.UI.Converters;
namespace PCL.Core.UI.Animation.Easings;
/// <summary>
/// 定义了缓动类的接口。
/// </summary>
[TypeConverter(typeof(EasingConverter))]
public interface IEasing
{
/// <summary>
/// 返回指定进度的过渡值。
/// </summary>
/// <param name="progress">从 0.0 到 1.0 的进度值。</param>
/// <returns>过渡值。</returns>
double Ease(double progress);
/// <summary>
/// 返回指定动画帧的过渡值。
/// </summary>
/// <param name="currentFrame">当前动画帧。</param>
/// <param name="totalFrames">总动画帧数量。</param>
/// <returns>过渡值。</returns>
double Ease(int currentFrame, int totalFrames);
}
@@ -0,0 +1,11 @@
namespace PCL.Core.UI.Animation.Easings;
public class LinearEasing : Easing
{
public static LinearEasing Shared { get; } = new();
protected override double EaseCore(double progress)
{
return progress;
}
}
@@ -0,0 +1,11 @@
namespace PCL.Core.UI.Animation.Easings;
public class QuadEaseIn : Easing
{
public static QuadEaseIn Shared { get; } = new();
protected override double EaseCore(double progress)
{
return progress * progress;
}
}
@@ -0,0 +1,16 @@
namespace PCL.Core.UI.Animation.Easings;
public class QuadEaseInOut : Easing
{
public static QuadEaseInOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
if (progress < 0.5)
{
return 2 * progress * progress;
}
return progress * (4 - 2 * progress) - 1;
}
}
@@ -0,0 +1,11 @@
namespace PCL.Core.UI.Animation.Easings;
public class QuadEaseOut : Easing
{
public static QuadEaseOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
return 1 - (1 - progress) * (1 - progress);
}
}
@@ -0,0 +1,12 @@
namespace PCL.Core.UI.Animation.Easings;
public class QuarticEaseIn : Easing
{
public static QuarticEaseIn Shared { get; } = new();
protected override double EaseCore(double progress)
{
var p2 = progress * progress;
return p2 * p2;
}
}
@@ -0,0 +1,19 @@
namespace PCL.Core.UI.Animation.Easings;
public class QuarticEaseInOut : Easing
{
public static QuarticEaseInOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
if (progress < 0.5d)
{
var p2 = progress * progress;
return 8 * p2 * p2;
}
var f = progress - 1;
var f2 = f * f;
return -8 * f2 * f2 + 1;
}
}
@@ -0,0 +1,13 @@
namespace PCL.Core.UI.Animation.Easings;
public class QuarticEaseOut : Easing
{
public static QuarticEaseOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
var f = progress - 1;
var f2 = f * f;
return -f2 * f2 + 1;
}
}
@@ -0,0 +1,12 @@
namespace PCL.Core.UI.Animation.Easings;
public class QuinticEaseIn : Easing
{
public static QuinticEaseIn Shared { get; } = new();
protected override double EaseCore(double progress)
{
var p2 = progress * progress;
return p2 * p2 * progress;
}
}
@@ -0,0 +1,19 @@
namespace PCL.Core.UI.Animation.Easings;
public class QuinticEaseInOut : Easing
{
public static QuinticEaseInOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
if (progress < 0.5)
{
var p2 = progress * progress;
return 16 * p2 * p2 * progress;
}
var f = 2 * progress - 2;
var f2 = f * f;
return 0.5 * f2 * f2 * f + 1;
}
}
@@ -0,0 +1,13 @@
namespace PCL.Core.UI.Animation.Easings;
public class QuinticEaseOut : Easing
{
public static QuinticEaseOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
var f = progress - 1d;
var f2 = f * f;
return f2 * f2 * f + 1d;
}
}
@@ -0,0 +1,13 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class SineEaseIn : Easing
{
public static SineEaseIn Shared { get; } = new();
protected override double EaseCore(double progress)
{
return 1 - Math.Cos(progress * Math.PI / 2);
}
}
@@ -0,0 +1,13 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class SineEaseInOut : Easing
{
public static SineEaseInOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
return -(Math.Cos(Math.PI * progress) - 1) / 2;
}
}
@@ -0,0 +1,13 @@
using System;
namespace PCL.Core.UI.Animation.Easings;
public class SineEaseOut : Easing
{
public static SineEaseOut Shared { get; } = new();
protected override double EaseCore(double progress)
{
return Math.Sin(progress * Math.PI / 2);
}
}