2014-06-07 96 views
-2

我試圖落實this site基本的遊戲循環在Java中

這裏的最後一場比賽循環是從網站的代碼:

const int TICKS_PER_SECOND = 25; 
const int SKIP_TICKS = 1000/TICKS_PER_SECOND; 
const int MAX_FRAMESKIP = 5; 

DWORD next_game_tick = GetTickCount(); 
int loops; 
float interpolation; 

bool game_is_running = true; 
while(game_is_running) { 

    loops = 0; 
    while(GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) { 
     update_game(); 

     next_game_tick += SKIP_TICKS; 
     loops++; 
    } 

    interpolation = float(GetTickCount() + SKIP_TICKS - next_game_tick) 
        /float(SKIP_TICKS); 
    display_game(interpolation); 
} 

    // GetTickCount() returns the current number of milliseconds 
// that have elapsed since the system was started 

我已經代替使用System.currentTimeMillis的() GetTickCount()希望它能做到這一點。

但我一直在用我的代碼得到很奇怪的結果: 有沒有人知道如何在java中實現這個Game循環?

這裏是我的非工作例如:(我不斷收到插值大批)

private final int TICKS_PER_SECOND = 25; 
private final int SKIP_TICKS = 1000/TICKS_PER_SECOND; 
private final int MAX_FRAMESKIP = 5; 

private double nextGameTick = System.currentTimeMillis() ; 

private int loops; 
private float interpolation; 

private boolean isGameRunning = true; 

public GameLoop(){ 

while(isGameRunning) { 

    loops = 0; 
    while( System.currentTimeMillis() > nextGameTick && loops < MAX_FRAMESKIP) { 
     // update_game(); 

     nextGameTick += SKIP_TICKS; 
     loops++; 
    } 

    interpolation = (float)( System.currentTimeMillis() + SKIP_TICKS - nextGameTick)/ (float)(SKIP_TICKS); 
    //display_game(interpolation); 
    view.display(interpolation); 
} 

}

我的位置使用從網站公式扳回一球,但球只是不斷spazzing出來回

view_position =位置+(速度*插值)

我加我的代碼的其餘部分,以便其較confusin G: (雖然我有我打這個代碼前,因爲插數量是巨大的,當我運行調試器,它應該是一小部分問題) 這是我的看法類油漆球:

public class View extends JPanel 
{ 
    private static final long serialVersionUID = -2744215808270823059L; 

    Ball myBall = new Ball(); 



    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     paintBall(g); 
     g.drawString(String.valueOf(interpolation), 20, 20); 
     g.drawString(String.valueOf(myBall.getLocation()), 20, 50); 
    } 

    private void paintBall(Graphics g){ 
     g.drawOval(myBall.getLocation().x, myBall.getLocation().y, myBall.getDiameter(), myBall.getDiameter()); 

    } 
    private float interpolation; 
    public void display(float interpolation){ 
     Point location = new Point(); 
     this.interpolation = interpolation; 

     location.x = myBall.getLocation().x + (int)(myBall.getSpeedX() * interpolation); 
     location.y = myBall.getLocation().y + (int)(myBall.getSpeedY() * interpolation); 
     myBall.setLocation(location); 

     repaint(); 
    } 



} 

而且我的球類:

public class Ball { 
    private Point location = new Point(); 
    private int diameter; 


    private double speed; 
    private double speedX; 
    private double speedY; 

    private double angle; 

    Ball(){ 
     this(new Point(0, 10)); 
    } 

    Ball(Point location){ 
     this(10, 3, 60, location); 
    } 

    Ball(int diameter, double speed, double angleDeg, Point location){ 
     this.speed = speed; 
     setAngleDeg(angleDeg); 
     setDiameter(diameter); 
     setLocation(location); 
    } 
    //Getters and Setters 


    public double getAngleRad() { 
     return angle; 
    } 
    public void setAngleRad(double angle) { 
     this.angle = angle; 
     speedX = Math.cos(angle)*speed; 
     speedY = Math.sin(angle)*speed; 
    } 

    public double getAngleDeg() { 
     return angle*180/Math.PI; 
    } 
    public void setAngleDeg(double angle) { 
     this.angle = angle * Math.PI/180; 
     speedX = Math.cos(angle)*speed; 
     speedY = Math.sin(angle)*speed; 
    } 

    public double getSpeedX() { 
     return speedX; 
    } 
    public void setSpeedX(double speedX) { 
     this.speedX = speedX; 
    } 

    public double getSpeedY() { 
     return speedY; 
    } 
    public void setSpeedY(double speedY) { 
     this.speedY = speedY; 
    } 

    public Point getLocation() { 
     return location; 
    } 
    public void setLocation(Point location) { 
     this.location = location; 
    } 
    public int getDiameter() { 
     return diameter; 
    } 
    public void setDiameter(int diameter) { 
     this.diameter = diameter; 
    } 
    public double getSpeed() { 
     return speed; 
    } 

    public void setSpeed(double speed) { 
     this.speed = speed; 
     speedX = Math.cos(angle)*speed; 
     speedY = Math.sin(angle)*speed; 
    } 


} 

回答

0

在遊戲循環使用忙等待是不好的做法,我建議使用不同的策略,像在等待顯示器刷新渲染下一幀。大多數遊戲框架都包含他們自己的遊戲循環邏輯,我強烈建議尋找其中的一種。

該問題看起來像是將時間差補充到view_position中,而不是將時間差添加到獲取實際時間的時間。所以球的位置是基於你在幀時間之間得到的抖動,而不是時間本身。

請在嘗試一下游戲框架,然後再考慮用自己的方式重新發明輪子;在遊戲邏輯上工作而不是調試較低層次的東西會更有趣。當你更有經驗並且如果你需要它來表現的話,請回到這裏。

+0

這不是我的遊戲循環,它直接從網站描述如何設計一個好的遊戲循環。我只是想在Java中實現它。我懷疑自從它從原始網站中刪除後nextGameTick增量的問題。 (我在我的問題鏈接)http://www.koonsolo.com/news/dewitters-gameloop/ – Xitcod13

+0

此外,這個循環並沒有使用它內部的等待......它的設計是專門有效和最大化幀每秒輸出以固定間隔更新遊戲。 – Xitcod13

+0

對不起,誤解了代碼。用我認爲的原因編輯。不,這不是一個好的遊戲循環。你一直在使用100%的CPU,因爲它根本不限制FPS。如果你想寫一個遊戲,這不是做這件事的方法。 – cactus1