使用光标射击弹丸

时间:2017-05-29 17:29:25

标签: .net winforms

我正在制作一款游戏,你可以点击它来射击飞向你光标的射弹。但是,我不知道如何让射弹沿光标方向飞行。我试着像这样找到这条线的斜率......

 public bool PreFilterMessage(ref Message m)
        {
            if(m.Msg == 0x0201)
            {
                Point MousePos = PointToClient(Form.MousePosition);

                slope = (MousePos.Y - aCharacter.Location.Y) / (MousePos.X - aCharacter.Location.X);
                aLaser.Location = aCharacter.Location;
                if (MousePos.X < aCharacter.Location.X)
                    lasDir = -1;
                else
                    lasDir = 1;
                laserLaunched = true;   
                return true;
            }

    private void aChMvmTimer_Tick(object sender, EventArgs e)
    {

        if(laserLaunched)
        {
            aLaser.Location = new Point(aLaser.Location.X + lasDir, aLaser.Location.Y + (slope * lasDir));
            aLaser.Visible = true;

        }

        else
        {
            aLaser.Visible = false;
        }
}

然而,它并没有向光标射击,而且在射击的地方看起来几乎是随机的。我该怎么做呢?

我尝试了另一种解决方案,但我怀疑我做得对。

  int currentTime = Environment.TickCount;
        double deltaTime = (currentTime - lastTime) / 1000.0;
        lastTime = currentTime;
        if (laserLaunched)
        {

            int movementSpeed = 20;
            //aLaser.Location = new Point(aLaser.Location.X + lasDir, aLaser.Location.Y + (slope * lasDir));
            aLaser.Visible = true;
            double x = aLaser.Location.X - curMousePos.X;
            double y = aLaser.Location.Y - curMousePos.Y;
            double loc = ((int)x ^ 2) + ((int)y ^ 2);
            loc = Math.Sqrt(((int)x ^ 2) + ((int)y ^ 2));
            x = (x / (int)loc);
            y = (y / (int)loc);
            x *= (int)deltaTime * movementSpeed;
            y *= (int)deltaTime * movementSpeed;
            aLaser.Location = new Point(aLaser.Location.X + (int)x, aLaser.Location.Y + (int)y);
        }

我做得对吗?

1 个答案:

答案 0 :(得分:0)

最简单的方法是使用简单的矢量数学:

获取从A到B的矢量:

V = B - A // That means subtracting each component of B from the respective component of A.

如果您使用的是System.Windows.Point而不是WinForms版本,则可以使用Point.Subtract(Point,Point)方法立即为您提供Vector个对象。

然后将该矢量标准化,这样您就可以更好地缩放到所需的射弹移动速度。标准化向量在每个组件中仍具有相同的相对幅度,但总长度为1.为实现此目的,您将每个组件除以向量的总长度,或者如果使用{{1,则使用Vector.Normalize()之前提到的方法。

一旦你有了标准化的矢量,你就可以通过矢量来改变每个刻度上实际射弹位置的坐标,乘以你的刻度事件所需的速度和帧速率*。

再一次,你可以这样做&#34;手工&#34;或使用System.Windows

的内置函数
Vector

*我在这里使用的newLocation = Vector.Add(Vector.Multiply(movementVector, movementSpeed * deltaTime), currentLocation); 可以通过每次调用tick函数时存储系统时间(以毫秒为单位)并将当前系统时间与上一次的时间进行比较来获取。将它除以1000,你会得到一个浮点值,它告诉你以秒为单位的时差,然后你可以用&#34;每秒像素数来指定你的射弹移动速度&#34;。这使得实际移动独立于您的节拍功能所运行的帧速率,因此如果玩家的CPU是瓶颈并且如果您决定不改变它也不会变得更慢更改刻度更新的频率,以便以后获得更流畅的游戏体验。

示例:

deltaTime