动画标题(如泰拉瑞亚的游戏名称)



我想做的是像Terraria这样的标题,而不是图形的来回摇摆,我知道它只是一个.png来回摇摆,但任何人都可以帮助我和其他阅读此书的人,该怎么做?

所以我想学习如何像Terraria中显示的标题一样来回摇摆?

对于不知道Terraria是什么的人,类似的东西。

http://www.youtube.com/watch?v=3k8pmg42l3m

看来徽标在非平等时间间隔内旋转并更改其大小。

首先,您需要熟悉此方法:

spriteBatch.draw方法(texture2d,vector2,nullable,color,single,single,vector2,single,spriteEffs,单个)

参数为:

Texture2D texture,                   // texture of your logo
Vector2 position,                    // where to draw
Nullable<Rectangle> sourceRectangle, // null
Color color,                         // Color.White
float rotation,                      // you will be changing this
Vector2 origin,                      // and this
float scale,                         // also this
SpriteEffects effects,               // SpriteEffects.None
float layerDepth                     // 0

使用这些变量:

float rotation = 0,
    rotationSpeed = 0.002f, // this is how much rotation will change each frame
    maximumAngle = 0.1f,
    minimumAngle = -0.1f,
    rotationDirection = 1,
    scale = 1f, // 1 means 100%, 0.95f = 95%
    scaleChange = 0.005f, // this may seem not much, but it's enough
    maxScale = 1.1f,
    minScale = 0.9f,
    scaleDirection = 1;

只是将DrawLogo();放入您的主要Draw()方法中。

void DrawLogo()
{
    // these two very similar pieces of code will control scale and rotation
    if (rotationDirection > 0)
    {
        if (rotation < maximumAngle)
            rotation += rotationSpeed;
        else
            rotationDirection = -rotationDirection;
    }
    else
        if (rotation > minimumAngle)
            rotation -= rotationSpeed;
        else
            rotationDirection = -rotationDirection;
    if (scaleDirection > 0)
    {
        if (scale < maxScale)
            scale += scaleChange;
        else
            scaleDirection = -scaleDirection;
    }
    else
        if (scale > minScale)
            scale -= scaleChange;
        else
            scaleDirection = -scaleDirection;

    Texture2d t2d = logoTexture;
    spriteBatch.Draw(t2d,
        centerScreen,            // change this to `new Vector2(123, 456)`
        null,                    // null means draw entire texture
        Color.White,             // no tinting
        rotation,                // the rotation we calculate above
        new Vector2(t2d.Width / 2, t2d.Height / 2),
          // this sets rotation point to the center of the texture
        scale,                   // the scale we calculate above
        SpriteEffects.None,      // you can mirror your texture with this
        0);                      // I usually leave it zero :p
}

这是测试的,正常工作:)

您的意思是我们可以在1:16大约看到的效果(在其他时候也可能在菜单中选择东西?

概念

据我所知,您可以通过简单的旋转和缩放来完成此操作。因此,如果您不想制作动画gif(您认为是它),则可以在XNA代码中进行操作。用alpha-enannel取PNG或GIF(以便非文本是透明的)。

然后,当您使用spriteBatch.draw()在屏幕上绘制它时,您可以选择一个支持缩放 rotation 的过载之一。。

然后您必须设置:

  • 您想要的旋转(随着时间的推移会旋转)
  • 原点(到图像的中心)
  • 比例尺(将随时间扩展)

,就我记得XNA而言,时钟被发送到update()方法,我们将不得不更新那里的图像的旋转和尺度。我们需要时钟,因为我们不能仅设置rotaton = 10°,而XNA将为我们处理所有内容。我们必须在每个时间步骤中计算当前旋转。例如。如果完全旋转将持续10秒和5秒,那么您知道您的旋转半旋转。因此,我们会告诉XNA:Set our rotation to 180° now,在下一次步骤中,我们可能会说:Set our rotation to 190° now

基本概念是:

  1. 计算我们在当前时间步骤中所做的旋转/比例的多少
  2. 告诉XNA在此时间步骤中调整此旋转/比例
    • 一次遍历这两个步骤

实施

我认为这里最好的事情是使用sin()或cos()函数进行缩放和旋转。关于他们的好事:

  • 它们也具有正值和负值(因此我们可以轻松地向两个方向旋转)
  • 它们很光滑,这意味着您的旋转和缩放在旋转/缩放结束时看起来不会太突然

我希望我的数学在这里正确。我将解释一切,以便其他人可以纠正我,如果有问题。或者,您是否可以找到问题。我们将在这里使用sin(),因为它从0开始,在我们的情况下,这意味着什么都不应发生。这就是我们想要的:我们想从什么都没发生的情况开始。

现在,sin()的周期时间为2*pi。当然,我们不希望扩展到持续2*pi,而是想缩放比例,而是1000毫秒。我们不能更改C#中Math.Sin()的定义,但是我们可以更改丢弃内部的值。因此,当我们指1000毫秒时,我们将给出Math.Sin() 2PI,而当我们指500毫秒时,我们会给它PI。

我们将定义这些成员变量:

// define some variables for rotation and scale speed, in milliseconds 
int fullRotationTime = 1000; // max rotation will be reached after 1 second
float maxRotationAngle = MathHelper.ToRadians(10); // we will rotate by 10 degree up and down
int rotationTimePassed = 0;
float currentRotationAngle = 0;
int fullScaleTime = 1000; // max scale will be reached after 1 second
float maxScaleSize = 1.2f; // we will scale to 20% larger max
int scaleTimePassed = 0;
float currentScaleFactor = 1.0;

和在Update()方法中,我们计算了我们已经完成了多少旋转。

protected virtual void Update(GameTime gameTime)
{
    int milliseconds = gameTime.ElapsedGameTime.TotalMilliseconds;
    // these are the milliseconds in the current rotation
    rotationTimePassed += milliseconds;
    scaleTimePassed += milliseconds;
    if (rotationTimePassed >= fullRotationTime)
        rotationTimePassed %= fullRotationTime;
    if (scaleTimePassed >= fullScaleTime)
        scaleTimePassed %= fullScaleTime;

    float rotationTimeAdjustedToTwoPi = ((float)rotationTimePassed)/fullRotationTime * 2* Math.PI);
    currentRotationAngle = maxRotationAngle * Math.Sin(rotationTimeAdjustedToTwoPi);
    // we do not want the scaling to be negative, thus we add 1 to the whole and
    // divide by 2. Then the maximum will be 1 and the minimum 0
    float scaleTimeAdjustedToTwoPi = ((float)scaleTimePassed)/fullScaleTime * 2* Math.PI);
    currentScaleFactor = maxScaleSize * (Math.Sin(scaleTimeAdjustedToTwoPi) + 1)/2;
}

然后,在Draw()方法中,我们可以在之前计算出的值并显示我们的旋转和缩放图像。

protected virtual void Draw()
{
    spriteBatch.Begin();
    spriteBatch.Draw(texture,
        new Vector2(50, 50),
        null,
        Color.White,
        currentRotationAngle,
        new Vector2(texture.width/2, texture.height/2),
        currentScaleFactor,
        SpriteEffects.None,
        0
    );
    spriteBatch.End();
}

它没有经过测试,因此甚至可能存在语法错误,但是我至少基本想法应该是正确的,我认为重要的是您了解如何概念上完成。<<<<<<<<<<<<<<

可变时间步骤

很容易集成可变的时间步骤 user1306322 已在上面的代码中提到。我们有这些if条件,在其中检查了当前的时间片是否结束了,例如: if (rotationTimePassed >= fullRotationTime)

现在,我们要制作时间平方的变量长度,只需根据此处的随机数调整新的时板即可。这样:

var rand = new Random();
if (rotationTimePassed >= fullRotationTime)
{
    rotationTimePassed %= fullRotationTime;
    // next rotation might take between 0.5 and 2.5 seconds
    fullRotationTime = rand.next(500, 2500);
}

最新更新