简体   繁体   English

模拟2D弹丸旋转的最佳方法?

[英]Best method to simulate rotation of a projectile in 2D?

so I'm working on a 2D castle defense style game for a class I'm taking and I'm having difficulties trying to get the arrows that the player fires to rotate properly as they fly in their parabolic arc. 因此,我正在为正在参加的课程开发2D城堡防御风格的游戏,并且在尝试获得玩家射击时抛射弧线正确旋转时遇到的困难。 I'm sure many of you have played similar games before, but here is a link, for example's sake, of exactly what I'm trying to accomplish. 我敢肯定你们中的许多人以前都玩过类似的游戏,但是例如,在这里,正是我想要实现的目标的链接。

http://www.lostvectors.com/prelude/ http://www.lostvectors.com/prelude/

I currently have an arrow class: 我目前有一个箭课程:

public class Arrow
    {
        public Texture2D arrowSprite;
        public double Xvelocity;
        public double Yvelocity;
        public int currentXpos;
        public int currentYpos;
        public int oldXpos;
        public int oldYpos;
        public float currentAngle;
        public float oldAngle;

        public Arrow() 
        {
            arrowSprite = WindowsGame1.Game1.arrow;
            Xvelocity = 10;
            Yvelocity = 10;
            currentXpos = 850;
            currentYpos = 200;
        }
    }

Note: The initial values I have set are just in place until I can get the animation to work correctly. 注意:在使动画正常工作之前,我设置的初始值就位。 I will have the values set based on user input once I have this problem solved. 解决此问题后,将根据用户输入设置值。

I have the following code in my update method to update the arrows: 我的更新方法中包含以下代码来更新箭头:

foreach (Player.Arrow arrow in onscreenArrows)
            {
                arrow.oldXpos = arrow.currentXpos;
                arrow.oldYpos = arrow.currentYpos;
                arrow.currentXpos -= Convert.ToInt32(arrow.Xvelocity);
                arrow.currentYpos -= Convert.ToInt32(arrow.Yvelocity);
                arrow.oldAngle = arrow.currentAngle;
                arrow.currentAngle = Convert.ToSingle(Math.Atan(arrow.Yvelocity/arrow.Xvelocity) * 180 / Math.PI);
                arrow.Yvelocity -= 1;
            }

and this snippet in my draw method: 这是我的draw方法中的代码段:

foreach (Player.Arrow arrow in onscreenArrows)
        {
            spriteBatch.Draw(arrow.arrowSprite, new Vector2(arrow.currentXpos, arrow.currentYpos), null, Color.White, arrow.currentAngle - arrow.oldAngle, new Vector2(0, 4), 1.0f, SpriteEffects.None, 0);
        }

To clarify, the arrows are being fired from the right side of the screen and are traveling left. 为了清楚起见,箭头从屏幕的右侧发射,向左移动。 I apologize for my extremely messy code. 非常抱歉我的代码很乱。 I'm still very new to game programming and I've just been trying to get the animation to work properly before doing anything else. 我对游戏编程还是很陌生,我一直在尝试使动画正常工作,然后再执行其他操作。 Any advice would be very helpful and greatly appreciated, thanks!! 任何建议将是非常有益的,非常感谢,谢谢!

Your code actually looks pretty good. 您的代码实际上看起来不错。 The only mistake I can see is that you are passing the spriteBatch.Draw function the rotation as: 我看到的唯一错误是,您正在将spriteBatch.Draw函数传递为:

arrow.currentAngle - arrow.oldAngle

The rotation given to SpriteBatch.Draw is the absolute rotation ( MSDN ) and so you should just pass it arrow.currentAngle 提供给SpriteBatch.Draw的旋转是绝对旋转( MSDN ),因此您只需将其传递给arrow.currentAngle

To be clear, you are currently passing it the change in angle (delta, or relative angle) from the last frame, when it has no memory of the last frame. 需要明确的是,当前没有传递最后一帧的内存时,当前传递的是与最后一帧的角度变化(δ或相对角度)。 You should just give it the angle to draw at. 您应该给它绘制角度。

Update Missed a few problems on your math. 更新错过了数学上的一些问题。

  1. Math.Atan returns a radian, and spriteBatch.Draw expects a radian, so you don't need to do the conversion between degrees and radians (in fact, that is probably why you see it jumping around wildly). Math.Atan返回一个弧度,而spriteBatch.Draw则期望一个弧度,因此您无需在度和弧度之间进行转换(实际上,这可能就是为什么您看到它疯狂地跳跃)。

  2. Your math gets the correct angle if you were travelling right. 如果您正确旅行,您的数学将获得正确的角度。 To get it travelling left, take 180 degrees and subtract the calculated angle. 要使其向左移动,请采取180度并减去计算出的角度。

With those improvements, your code becomes: 经过这些改进,您的代码将变为:

arrow.currentAngle = Math.Pi - Math.Atan(arrow.Yvelocity/arrow.Xvelocity);

Let me know how it goes! 让我知道事情的后续!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM