2010-11-12 66 views
1

我正在研究一個程序,它模擬在一個字段中移動的對象。該領域具有1024x1024的界限。該對象不能在x,y座標下低於0,並且它不能超過1024.我爲每個對象創建一個名爲「move()」的方法,以當前速度將對象移動到當前方向。如果物體接近邊界,它會以新的方向和相同的速度轉向。移動的物體卡在角落

我遇到的問題是,當我的一個對象接近x和y邊界(字段的角落)時,它會卡在角落裏。就好像它試圖遠離角落,但隨後又轉回來。它必須喜歡那個角落。我查看了我的代碼和我,我的邏輯似乎是正確的。我檢查以確保新的方向不是負的或超過359.我檢查以確保新的x,y與新方向的座標也在範圍內。我甚至有辦法設定一個新的方向。

我試過用不同的邏輯重新實現這個方法,但沒有運氣。如果有人可能在我的編程中發現缺陷或指出可能導致它的原因,那麼將非常感激。

我試圖調試並逐步通過我的程序,我發現當它到達角落時,它會改變方向轉向,移動大約3個空格,然後回到角落。必須是一個美妙的角落。

代碼移動方法如下:

public void move(){ 

    localX = super.getX(); 
    localY = super.getY(); 

    float newX=0, newY=0; 
    float testX, testY; 
    boolean acceptX = false, acceptY = false; 

    testX = (float) (Math.cos(direction)*10) + localX; 
    testY = (float) (Math.sin(direction)*10) + localY; 
    int testDirection; 

    while(!acceptX){ 
    if(testX >= 0 && testX <= bound){ 
    newX = testX; 
    acceptX = true; 
    }//end if statement 
    else{ 
    if(direction+180 > 359){ 
    setDirection(direction-180); 
    testX = (float) (Math.cos(Math.toRadians(direction))*speed) + localX; 
    } 
    else{ 
    setDirection(direction+180); 
    testX = (float) (Math.cos(Math.toRadians(direction))*speed) + localX; 
    } 
    }//end else 
    }//end while that checks for X value 

    while(!acceptY){ 
    if(testY >= 0 && testY <= bound){ 
    newY = testY; 
    acceptY = true; 
    }//end if statement 
    else{ 
    if(direction+180 > 359){ 
    setDirection(direction-180); 
    testY = (float) (Math.sin(Math.toRadians(direction))*speed) + localY; 
    } 
    else{ 
    setDirection(direction+180); 
    testY = (float) (Math.sin(Math.toRadians(direction))*speed) + localY; 
    } 
    }//end else 
    }//end while that checks for Y value 

    super.setX(newX); 
    super.setY(newY); 

} 

這裏是setDirection代碼

public void setDirection(int d) { 
     direction = d; 
    } 
+0

我們還需要設置'direction'的代碼。可能它出於某種原因偏向於朝着角落移動。 – Donnie 2010-11-12 00:50:54

+0

沒問題,上面加了。 – Seephor 2010-11-12 00:54:08

+1

setDirection((direction + 180)%360)。擺脫那些如果。 – 2010-11-12 00:54:54

回答

2

假設你在左上角有一個物體,正在上升。你的第一個測試將它轉換成所以它下降。然後你的第二次檢查,再次變成了一次又一次。

您的代碼也可以使用更多的可讀性。我注意到的第一件事是,您正在使用>359檢查來規範新的方向。但是,所有情況都包括移動代碼。我會這樣做:

setDirection(direction + 180);   //turn around 
if (direction >= 360) direction -= 360; //normalize 
testY = ...;       //move 

將移動代碼移出方向檢查if/else塊。 360也是一個更好的魔術數字使用; 359度毫無意義。如前所述,您最終應該使用矢量庫,因此會丟掉大部分數學運算。

+0

好的,謝謝。我決定使用上面提到的參數進行清理。傳入((方向+ 180)%360)。我實際上使用Java矢量庫來存儲在場中移動的對象,但是如何將它用於座標? – Seephor 2010-11-12 01:16:47

+0

我的意思是數學向量。這些東西:http://download.java.net/media/java3d/javadoc/1.5.2/javax/vecmath/package-summary.html – aib 2010-11-12 08:25:12

1

我真的建議你存儲方向矢量(X,Y),而不是從標量中計算該向量;我認爲這對你的代碼非常有幫助。

+0

我從來沒有用過矢量來存儲方向。我會將x和y分量存儲在向量中嗎? – Seephor 2010-11-12 01:14:40

+0

@Seephor:是的,這就是主意。關鍵是那些trig函數是昂貴的;當以直線移動時,實際矢量將保持一致(或由另一個矢量修改),並且節省這些trig函數的計算開銷是非常有用的。當你需要方向時,你可以從反三角函數(弧函數)中得到它。 – 2010-11-12 05:13:01

1

問題:當物體碰到邊緣時,將其轉動180度。如果碰到兩邊,它會旋轉到位,測試座標將始終位於錯誤的位置。

當你的一個物體碰到一個邊緣時,它需要反彈,而不是關於面部!入射角度==折射角度等。換句話說,如果您檢查x座標並彈跳,則取x軸速度,不能同時x & y。