簡體   English   中英

Java:游戲中的優化算法

[英]Java: Optimizing algorithm in game

我正在使用scene2d創建一個游戲(Java)。

我編寫了用於碰撞檢測的函數,但我認為它是一個不好的函數。 看起來不好

我該如何優化? 更快,更漂亮。

private void deleteEnemies()
{
    for(int i = 0; i < getActors().size - 1; i++)
    {
        if(getActors().get(i) != null && getActors().get(i) instanceof Enemy)
        {
            ////////////////
            for (int j = 0; j < getActors().size - 1; j++)
            {
                if(getActors().get(j) != null && getActors().get(j) instanceof Ball)
                {
                    if (actorsIntersecting(getActors().get(i), getActors().get(j)))
                    {
                        getActors().get(i).remove();
                        getActors().get(j).remove();
                    }
                }
            }
            //////////////
        }
    }
}
  1. getActors().get(i)放在變量中,如果在外部,則不要兩次調用它
  2. 如果在內部if的getActors().get(j)相同
  3. 在最內部的條件和身體中使用這些變量
  4. 將大小保存在變量中,因為現在在每次檢查for條件時都會在每次迭代中調用.size函數
  5. 對於循環條件,您不應使用在循環過程中會動態變化的大小(因為您正在移動項目),這會使我們回到#4。 除此之外,它的編碼風格還不錯,我懷疑您是否可以使它比我告訴您的效率更高(除了使用線程)
  1. 好吧,我的第一個想法是只檢查“最近”的敵人,而不是全部。 以某種方式嘗試減小該列表的大小。

2.第二個條件-請一一檢查您的和條件-現在您將始終檢查兩個條件。 如果稍后嘗試將“重”放置在下面,例如:

從:

  if(getActors().get(i) != null && getActors().get(i) instanceof Enemy) 

至:

 if(getActors().get(i) != null) { if(getActors().get(i) instanceof Enemy) { ..... } } 

3.一次調用您的getActors()。get(i)-保存到變量。 4.我在想為什么要檢查一個actor是否為空,也許只是從列表中刪除null或將未初始化的actor保留在另一個列表中。 還要對“球與敵人”進行嘗試,請不要將每個演員都放在一個列表中。

由於您將經常這樣做,因此請考慮將敵人和球存儲在它們自己的結構中(列表或集合或任何可行的方法)。 這可以防止您遍歷不需要的參與者,並避免執行instanceof檢查。

不要使用size(),而是定義一個變量。 盡量不要使用instanceof。 也許可以通過zsort等對列表進行排序,所以有時您可以更快地開始和/或停止循環?

除了其他參與者的(非常好)建議之外:將敵人和投射物緩存在單獨的結構中,因此您根本不必檢查它們是什么。

盡可能多地利用時間與空間之間的權衡:如Tomek所暗示的,在這種情況下,標准方法是通過修剪可能不會在其中碰撞的敵人和射彈來減少檢查次數(=重復次數)當前幀(它們很遠)。

無論如何,請提一個建議:繼續游戲,盡可能多地完成游戲,使其正確運行(如果運行緩慢), 然后進行優化。

那是因為

  1. 通過這種先發制人的優化,您將永遠無法完成它
  2. 您可能不知道最終的比賽將是什么樣子:也許在完成90%的比賽后,您會發現一些輕松的優化機會。

我會稍微重寫一下模型,以便他們可以測試交叉點本身,然后像這樣進行刪除(可能仍可以改進)

private void deleteEnemies () {
    List<Actor> actors = getActors();
    List<Actor> toRemove = new ArrayList<Actor>();
    int actorsSize = actors.size();
    Actor first = null, second = null;
    for(int i = 0; i < actorsSize; ++i) {
        first = actors.get(i);
        for(int j = 0; j < actorsSize; ++j) {
            if(i == j) continue;
            second = actors.get(j);
            if(first.intersects(second)) {
                toRemove.add(first);
                toRemove.add(second);

            }
        }
    }
    actors.removeAll(toRemove);
} 

正如其他人所說的那樣,速度的真正提高將是兩個集合,一個集合是球,另一個集合是敵人。 至於使它看起來更好,則可以這樣:

for (Actor enemy : getActors()) {
    if (enemy != null && enemy instanceof Enemy) {
        for (Actor ball : getActors()) {
            if (ball != null && ball instanceof Ball && actorsIntersecting(enemy, ball)) {
                ball.remove();
                enemy.remove();
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM