gpt4 book ai didi

C# 类组织/结构 - 概括执行循环线性插值的类

转载 作者:太空宇宙 更新时间:2023-11-03 20:26:59 25 4
gpt4 key购买 nike

我正在开发 C# XNA 游戏,并有以下代码根据线性插值的结果更新 Sprite 的 alpha 级别:

class AlphaProcess : GameProcess {

Sprite sprite;
public Sprite Sprite {
get { return sprite; }
set { sprite = value; }
}

float start;
public float Start {
get { return start; }
set { start = value;}
}

...<snip>...

public override void Update(float elapsed) {
if (FirstUpdate) {
Start = sprite.Alpha;
FirstUpdate = false;
}

Time += elapsed;
if (Time >= Duration)
Finished = true;

sprite.Alpha = MathHelper.Lerp(start,end,Time/Duration);
}
}

'Start' (float), 'FirstUpdate' (bool), 'Time' (float), 'Duration' (float) 都是类 AlphaProcess 的字段。 “Sprite”是一个包含比例、位置、方向、旋转等细节的类。

“更新”方法每秒调用 60 次,计算指定时间段内 Sprite 的新 alpha 值。完成后,GameProcess 将从队列中移除。

这段代码工作正常,但它非常具体。我拥有的 Sprite 类包含许多属性,可以方便地在固定时间段内进行 lerp(旋转、位置(用于缓入和缓出))。其中许多变量也是 float 。创建多个“GameProcess”扩展类来做几乎相同的事情,只是在不同的变量上,这似乎很愚蠢。但是,我想不出如何最好地重构它,以便我可以只拥有一个指向正在修改的浮点值的指针,而不是特定的 Sprite ,它是 alpha/旋转/缩放/任何值。

我已经完成了有关 SO 的 C# 引用/值/参数传递问题,并且知道在 C# 中您不能将引用存储为字段。调用 Update 的“GameProcessQueue”对正在更新的“GameProcess”的内部结构一无所知。 有没有一种更聪明的方法可以做到这一点,以便我可以概括/抽象类以更新另一个类的字段(就像这里,使用“Sprite”的“Alpha”字段)?

最佳答案

您的主要问题是您的 AlphaProcess 类的内聚性较低。它具有三个主要作用,Tweening、Lerping 和获取/设置 Sprite Alpha 值。为了改进您的设计,您需要将它们拆分为单独的解耦类。

目标:将您的 AlphaProcess 变成 TweenProcess。

不是传递给它一个 Sprite ,而是传递给它一个接口(interface),通过它它可以获取和设置它希望操作的 float 。并且不是直接调用 Lerp,而是将它传递给一个接口(interface)或委托(delegate)给一个 Tween 函数。 (我使用接口(interface)而不是委托(delegate),因为我发现委托(delegate)经常会产生垃圾,这会导致您的游戏卡顿。)

补间类是:

interface IFloatPropertySource
{
float FloatProperty { get; set; }
}

interface ITweenFunction
{
float Tween(float start, float end, float t);
}

class TweenProcess : GameProcess
{
float start;
IFloatPropertySource floatSource;
ITweenFunction tweenFunction;

public TweenProcess(IFloatPropertySource floatSource, ITweenFunction tweenFunction)
{
this.floatSource = floatSource;
this.tweenFunction = tweenFunction;
}

public override void Update(float elapsed) {
if (FirstUpdate) {
start = floatSource.FloatProperty;
FirstUpdate = false;
}

Time += elapsed;
if (Time >= Duration)
Finished = true;

floatSource.FloatProperty = tweenFunction.Tween(start, end, Time / Duration);
}
}

获取/设置 alpha 的类是:

class SpriteAlphaSource : IFloatPropertySource
{
Sprite sprite;

public SpriteAlphaSource(Sprite sprite)
{
this.sprite = sprite;
}

public float FloatProperty
{
get
{
return sprite.Alpha;
}
set
{
sprite.Alpha = value;
}
}
}

我知道你有点想避免上这门课。但是围绕它的所有方法,比如通过反射,都非常昂贵。在具有比 sprite 更多的可呈现对象的项目中,您可能希望将其与 sprite 分离并使其在 IRenderable 等基础接口(interface)上运行。

lerping 机制是:

class Lerp : ITweenFunction
{
public float Tween(float start, float end, float t)
{
return MathHelper.Lerp(start, end, t);
}
}

关于C# 类组织/结构 - 概括执行循环线性插值的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10091098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com