C# 动画标题(如Terraria和游戏标题)
我想做的是制作一个像Terraria这样的标题,只是前后摇摆的一面,而不是图形的一面,我知道它只是一个.png前后摇摆的画面,但是有谁能帮助我和其他读过这篇文章的人,知道怎么做吗 所以我想学习如何制作一个前后摇摆的图像,就像Terraria中显示的标题一样 对于那些不知道Terraria是什么的人来说是这样的C# 动画标题(如Terraria和游戏标题),c#,.net,xna,title,C#,.net,Xna,Title,我想做的是制作一个像Terraria这样的标题,只是前后摇摆的一面,而不是图形的一面,我知道它只是一个.png前后摇摆的画面,但是有谁能帮助我和其他读过这篇文章的人,知道怎么做吗 所以我想学习如何制作一个前后摇摆的图像,就像Terraria中显示的标题一样 对于那些不知道Terraria是什么的人来说是这样的 你是说当你在菜单中选择东西时,我们在1:16左右(可能在其他时间也会看到)看到的效果 概念 就我所见,你可以通过简单的旋转和缩放来做到这一点。因此,如果您不想制作动画gif(您认为是这样)
你是说当你在菜单中选择东西时,我们在1:16左右(可能在其他时间也会看到)看到的效果 概念 就我所见,你可以通过简单的旋转和缩放来做到这一点。因此,如果您不想制作动画gif(您认为是这样),您可以在XNA代码中制作。以带有alpha通道的png或gif为例(这样非文本是透明的) 然后,当您使用
spriteBatch.draw()
在屏幕上绘制它时,您可以选择其中一个重载
然后您必须设置:
- 要进行的旋转(将随时间进行旋转)
- 原点(到图像的中心)
- 比例(将随时间缩放)
update()
方法,因此我们必须更新那里图像的旋转和缩放。我们需要时钟,因为我们不能只设置旋转=10°,XNA将为我们处理一切。我们必须自己计算每个时间步中的当前旋转。例如,如果一个完整的旋转持续10秒,并且已经过去了5秒,那么你知道你有一个半旋转。所以我们会告诉XNA:现在将旋转设置为180°
,在下一个时间步骤中,我们可能会告诉:现在将旋转设置为190°
基本概念是:
- 反复重复这两个步骤
- 它们也有正值和负值(因此我们可以很容易地在两个方向上旋转)
- 它们是平滑的,这意味着您的旋转和缩放在旋转/缩放结束时看起来不会太突然
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;
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;
在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);
}
徽标似乎在不相等的时间间隔内旋转并改变其大小 首先,您需要熟悉: SpriteBatch.Draw方法(Texture2D,Vector2,Nullable,Color,Single,Vector2,Single,SpriteEffects,Single) 参数包括:
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
只需放置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
}
void DrawLogo()
{
//这两段非常相似的代码将控制缩放和旋转
如果(旋转方向>0)
{
if(旋转<最大角度)
旋转+=旋转速度;
其他的
旋转方向=-旋转方向;
}
其他的
如果(旋转>最小角度)
旋转-=旋转速度;
其他的
旋转方向=-旋转方向;
如果(缩放方向>0)
{
if(比例<最大比例)
比例+=比例变化;
其他的
scaleDirection=-scaleDirection;
}
其他的
如果(比例>最小比例)
比例-=比例变化;
其他的
scaleDirection=-scaleDirection;
纹理2d t2d=纹理;
spriteBatch.Draw(t2d,
centerScreen,//将其更改为“新矢量2(123456)”`
null,//null表示绘制整个纹理
颜色。白色,//无着色
旋转,//我们上面计算的旋转
新矢量2(t2d.宽度/2,t2d.高度/2),
//这会将旋转点设置为纹理的中心
scale,//我们上面计算的比例
SpriteEffects.None,//你可以用这个镜像你的纹理
0);//我通常将其保留为0:p
}
这是经过测试的,效果很好:)谢谢,我现在就试用一下,只有一个问题:如何集成XNA