所以基本上它是一款2D平台射击游戏。我想画出每个子弹的路径。每个子弹后都应该有一条白线,并且alpha值应该从子弹减少到它被发射的位置。
我如何创造这样的效果?
编辑:我只是要求一个基本的方法而不是详细的代码。 我想我可能需要使用粒子效果来做到这一点?编辑2:谢谢!但是我可以更改渐变纹理的源矩形而不是缩放吗?
如果我在某处弄错了,请纠正我,谢谢!
Texture2D gradline应如下所示:
(据我记得在使用Math.Atan2找到矢量的角度时,0度应该在正Y轴上)
我正在使用此方法来查找向量的度数。由于正Y在窗口坐标系中沿着窗口向下,我在这里改为-vector.Y :(这对我来说更有意义)
protected float VectorToRadians(Vector2 vector)
{
return (float)Math.Atan2(vector.X, -vector.Y);
}
我还需要找到子弹与其发射位置之间的距离,以确定源矩形的高度。所以我有一个像这样的方法
protected int GetRectangleHeight(Vector2 startingPos, Vector2 currentPos, int lineTextureLength)
{
float distance = (startingPos - currentPos).Length();
if (distance < lineTextureLength) // if distance is smaller than the texture length, only draw part of it
return distance;
else // if distance is larger or equal to the texture length, draw the entire texture
return lineTextureLength;
}
最后是画画
spriteBatch.Draw(
gradline,
bulletCurrentPos,
new Rectangle(0, 0, gradline.Width, GetRectangleHeight(bulletStartingPos, bulletCurrentPos),
Color.White,
VectorToRadians(bulletCurrentPos - bulletStartingPos),
Vector2.Zero, // actually i think setting the top-center as origin might look better
1f, // full scale
SpriteEffects.None,
0f);
当子弹击中某些东西并且消失时,路径仍然应该被绘制到屏幕上。在此期间,源矩形的y(以及高度,我认为,以确保矩形不会超出纹理)应该更改为仅绘制轨迹的末尾部分,直到y达到高度质地。
答案 0 :(得分:1)
您可以使用淡化为透明色的线条图像来执行此操作。像这样:
这是一个从屏幕中心到光标(激光瞄准具)绘制轨迹的版本:
(如果您希望从其他地方绘制它,可以用您首选的Vector2替换centerScreen
和cursor_v2
,例如子弹的当前位置以及该子弹最初拍摄的位置为此,我的答案最后的代码片段可能是最好的。)
Texture2D gradline; // set this var to your fading line texture in LoadContent
Vector2 centerScreen = new Vector2(
GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
Vector2 cursor_v2 = new Vector2(currentMouseState.X, currentMouseState.Y);
spriteBatch.Draw( // this is one of many Draw overloads
gradline, // your line texture
centerScreen, // we just set this to be at your game window center
null, // this means entire texture will be drawn
Color.White, // no tinting
GetAngle(centerScreen, cursor_v2), // this rotates texture, see my code below
Vector2.Zero, // texture will be drawn from screen center without offset
new Vector2(GetDistance(centerScreen, cursor_v2) / gradline.Width, 1),
// ↑ This is scaling vector, X scales texture to distance from screen center
// to cursor and then divides by the texture's length.
// See how Y is set to 1, which means texture height will not be changed.
SpriteEffects.None, // this can mirror the texture, we don't do this now
0f); // everybody leaves this zero :p
再一次没有评论:
spriteBatch.Draw(gradline,centerScreen,null,Color.White,GetAngle(centerScreen,cursor_v2),Vector2.Zero,new Vector2(GetDistance(centerScreen,cursor_v2)/ gradline.Width,1),SpriteEffects.None,0f );
获取角度值的代码:(只需将其放在Game类中的某个位置)
public float GetAngle(Vector2 v1, Vector2 v2)
{
Vector2 v = Vector2.Normalize(Vector2.Subtract(v2, v1));
return (float)Math.Atan2(v.Y, v.X);
}
或者,您可以创建一个长度恒定的纹理,并使用以下代码旋转它:
spriteBatch.Draw(gradline, centerScreen, null, Color.White,
GetAngle(centerScreen, cursor_v2), Vector2.Zero, 1, SpriteEffects.None, 0f);
// look here ↑
// this Draw overload takes float value instead of Vector2 for scaling textures
// so with 1 the texture size will not be scaled
另一种方法是在游戏中每个子弹的位置每隔半秒左右创建粒子,并在粒子过期后删除它。我怀疑你的子弹在线上移动,而不是抛物线,所以它可能不值得表现明智。
如果你的子弹经常改变他们的方向,你可以绘制他们的完整路径,但这需要绘制VertexPositionColor
的列表,这更复杂,但可能会给出很好的结果。