2017-05-29 53 views
-1

我正在做一個遊戲,你點擊射擊朝光標過得彈射擊彈丸。但是,我不知道如何去做使彈丸向光標方向飛行。我試圖找到像這樣的斜線...使用光標

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); 
     } 

我做對了嗎?

+0

「它不工作」 是沒有問題的描述。而「最細微」的限定詞根本沒有改善。 –

+0

感謝您指出了這一點!當我發佈時我沒有意識到。 – Beldar4000

回答

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的總長度要做到這一點,可以通過該矢量的總長度除以每個組件或如果你使用前面提到的方法System.Windows使用Vector.Normalize()

一旦你的歸一化向量,就可以通過矢量量,乘以所需的速度和你的Tick事件的幀率*改變每個替您的實際彈丸位置的座標。

同樣,你可以做到這一點「手動」或使用Vector內置功能:

newLocation = Vector.Add(Vector.Multiply(movementVector, movementSpeed * deltaTime), currentLocation); 

*我在這裏使用可以通過存儲系統時將予收購之deltaTime(以毫秒),每次調用tick函數並將當前系統時間與前一時間進行比較。將它除以1000,您將得到一個浮點值,以秒爲單位告訴您時間差異,然後您可以用「像素/秒」來指定拋射體移動速度。這使得獨立於您的蜱功能在運行幀率的實際運動,所以它不容易成爲,如果玩家的CPU是一個瓶頸慢,也不會改變,如果你決定改變你的滴答更新的頻率,帶來更順暢後來的遊戲體驗。

例子:

private int lastTime; // Initialize this to Environment.TickCount in your constructor. 

private void TickUpdate() { // Called by your tick event. 

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

    // Do stuff with deltaTime. 
} 
+0

這是有道理的,但我沒有使用WPF。我怎樣才能做到這一點呢? – Beldar4000

+0

那麼,您仍然可以在這些位置明確指向Windows.Point,並在Drawing.Point中使用最終結果的座標。或者你正如我在帖子中指出的那樣,親手做所有的事情。這意味着您只需直接對X個Y組件執行所有操作,而不是使用便捷方法。所以你拿'B.X - A.X','B.Y - A.Y',計算得到的向量的長度('Sqrt(X^2 + Y^2)')並且除以X和Y.然後,將X和Y乘以移動速度和deltaTime,最後將其添加到舊位置的相應X和Y. –

+0

這應該可行,但我對deltaTime的使用方法有點好奇。你能深入瞭解如何獲得它嗎?謝謝! – Beldar4000