14

我正在制作一个类似银河的射手,我的敌人物体有一个目的地向量,他们使用这段代码前往该向量:

position.X -= (Motion.X / Magnitude) * Speed;
position.Y -= (Motion.Y / Magnitude) * Speed;

运动是通过:

this.Motion = InitialPosition - Destination;

这使他们沿直线向目的地行驶。

但是,我想让它们变得更有趣,并在 sin 或 cos 波中旅行,有点像 Galaxian 所做的那样。

我怎样才能做到这一点?

4

4 回答 4

9

您最好为运动函数定义贝塞尔曲线,而不是像正弦波这样的简单函数。Galaxian当然有比这更复杂的动作。

这是贝塞尔曲线数学入门的链接。这是一个相当长的文档,但很好地涵盖了所涉及的数学,并提供了大量示例。

希望对您有所启发。

于 2012-12-19T16:19:05.653 回答
5

一种方法是为水平运动创建一个加速因子,并将该因子添加到每个刻度的水平速度。因此,如果你对给定敌人的水平速度一开始是 2,而你的加速度是 -.01,那么在 200 个滴答声之后,敌人会直线下降,再过 200 个滴答声之后,它会以 -2 的水平速度移动. 这将给出一个很好的曲线。

通过随机确定每个敌人的速度和加速度(在实验确定的特定限制内),您可以创建漂亮的各种攻击配置文件,而无需太多努力。这将给出一个非常类似银河的运动。

你也可以对垂直方向做同样的事情,当然,加速度限制会非常不同......对于水平加速度,你可能想要确定一个在 0 两侧大小相等的范围(比如说 -.02 到 +.02),而对于垂直加速度,您可能总是希望船最终从屏幕底部下降,因此您可能希望该加速度始终为正(或负,具体取决于你如何做屏幕坐标。)

于 2012-12-19T16:17:57.913 回答
3

您可以根据当前的运动代码使用航点导航来做到这一点。您将通过绘制正弦波来计算航点。你可以通过使用一些东西来做到这一点Destination.Y = Math.Sin(Destination.X)——如果没有看到你的代码,很难确定。

于 2012-12-19T16:19:29.243 回答
2

创建一个振荡器并将敌人(即使没有动量)垂直于其方向移动一个等于振荡器的正弦或余弦的偏移量就足够了。

以下示例在工作时显然只是一个指南。我希望它可以帮助你。

var dest = new PointF(200, 100);
var pos = new PointF(30, 140);
var oscAngle = 0d;
var dirAngle = Math.Atan2(dest.Y - pos.Y, dest.X - pos.X);
//Constants for your simulation
const int movSpeed = 2;
const int amp = 2;
const double frequency = Math.PI / 5;
//Inappropriate loop condition, change it to proper
while (true)
{
    oscAngle += frequency;
    //Scalar offset, you can use Cos as well
    var oscDelta = Math.Sin(oscAngle);
    //Linear movement
    var stepVector = new SizeF((float)(Math.Cos(dirAngle) * movSpeed), (float)(Math.Sin(dirAngle) * movSpeed));
    //Oscillating movement, making it transversal by adding 90° to the direction angle
    var oscNormalAngle = dirAngle + Math.PI / 2;
    //Vector for the oscillation
    var oscVector = new SizeF((float)(Math.Cos(oscNormalAngle) * oscDelta) * amp, (float)(Math.Sin(oscNormalAngle) * oscDelta) * amp);
    pos += stepVector + oscVector;
    //Operate below
}
于 2012-12-19T16:52:56.240 回答