2017-04-11 36 views
2

所以我一直在嘗試編寫一個物理模擬。我從模擬一個自由落體開始很小。我在Java中使用Java Jframe和一些來自awt庫的方法。然而,我一直面臨的問題是調整參數以使我的模擬更加生活。我的遊戲while循環以恆定的60 FPS運行,這意味着每個循環都需要16 ms。每次我更新,我執行這些法律:物理模擬,將像素調整爲米?

this.velX = this.velX + (accX)*delta; 
this.velY = this.velY + (accY) * delta ; 

this.velY = this.velY * 0.9; 


this.x = this.x + (int) ((this.velX) * delta); 
this.y = this.y + (int) ((this.velY)* delta); 

然而,由於我轉換爲int的值總是又回到了0,因爲它們非常小。而形狀的繪製方法只接受int(我認爲這是可以理解的,對吧?)我想知道是否會有解決方案?球會卡住,它的運動不會明顯(如果它移動的話)。

我試着將delta傳遞爲1,它很好地工作,但它太快了,但我認爲它不現實。因此,如果有人能夠給我關於這個問題的一般想法,那將是非常有用的。

+1

「16毫升秒」 - 16毫秒?我想這應該是「毫秒」=毫秒? – Fildor

+3

這聽起來像你正在從渲染他們的同一個地方讀你的座標 - 這正是你眼中問題的原因。嘗試將座標存儲在一些專用對象中,這些對象可以以您實際需要的任何形式接受它們(即以'double'或其他形式),然後在渲染它們時僅轉換爲'int'。 –

+0

是的,抱歉,我編輯了它。 – Robot0110

回答

1

的問題是,在這些線路

this.x = this.x + (int) ((this.velX) * delta); 
this.y = this.y + (int) ((this.velY)* delta); 

讓長期方程((this.velX) * delta) and ((this.velY) * delta)的後一部分deltaX and deltaY

所以公式應成爲

this.x = this.x + (int) deltaX; 
this.y = this.y + (int) deltaY; 

現在,這裏的問題是,您將deltaX and deltaY轉換爲整數,從而將他們對x and y職位的貢獻降至零。

即使長時間(多幀)的變化很小,貢獻也會變得很大。

假設變化deltaX.1它應該能夠在10幀中添加1像素移位。

如果您的draw函數只帶有整數,那麼您應該在該行之前轉換位置值,但應該是float or double以用於所有其他目的。

所以公式應該是

this.x = this.x + this.velX * delta; //this.x is float 
this.y = this.y + this.velY* delta; //this.x is float 

draw((int)x, (int)y) 

現在應該工作。

注意:另外我不知道你如何保持恆定的幀率,因爲Java不能這樣做。您將不得不考慮可變幀頻。你已經完成了使用delta。 Delta值不應該是恆定的,應該在每幀結束時計算。

+0

非常感謝你!這實際上工作!我正在使用典型的thread.sleep來處理處理輸入後16 ms剩下的內容。那是錯的嗎? – Robot0110

+0

是的,'Thread.sleep()'不能保證線程在指定的確切時間被喚醒。所以你可以使用'System.currentTimeMillis()'來計算睡眠時的實際delta值。這應該完美。 – 11thdimension

+0

@ user70319,更好的辦法是使用'java.util.concurrent.ScheduledExecutorService',它有這個方便的方法'scheduleAtFixedRate',它可以讓你每x個時間單位運行一些代碼。請注意,如果您的計劃代碼太慢而無法及時完成執行,則應該捕獲這些實例並處理它們。 –