2014-02-20 7 views
0

, 자바로 데스크탑 용 Flappy bird를 다시 만들었습니다. 화면을 생성하고 화면을 생성하는 기둥을 만들었지 만 이제는 성능 문제가 하나 있습니다.JavaGame 캐릭터가 그림을 그리는 동안 정확하게 움직이지 않습니까? 개인 연습을 위해

가끔은 게임이 빨리 움직이지 않고 때로는 0.5 초 정도 걸리는 경우가 있습니다.하지만 그건 사실이 아닙니다. 새를 움직이면 이상하게 움직이며, 움직이는 것처럼 보입니다.

http://gyazo.com/d7e94c0b772192e5a5dd1d2b61b8c529

그 원인이 될 수 무엇 : 많은 기대 & 다음 뒷면에, MP4 형식으로 GIF를 볼? 이것이 내 게임 루프일까요, 아니면 그래픽을 그리는 방식일까요? 나는 이중 버퍼링을 사용하지 않는다. 단순히 jframe에서 .repaint를 호출하여 JPanel을 다시 그려서 렌더링한다.

게임 루프 :

private void gameLoop() { 
    new Thread() { 
     private long last; 
     private long start; 
     private int wait; 
     public void run() { 
      while(game) { 
       long now = System.nanoTime(); 
       long length = now - lastLoop; 
       lastLoop = now; 
       double delta = length/((double) Constants.OPTIMAL); 
       lastFps += length; 
       fps++; 
       if (lastFps >= 1000000000) { 
        System.out.println("FPS: " + fps); 
        lastFps = 0; 
        fps = 0; 
       } 
       update(delta); 
       render(); 
       this.sleep 
      } 
     } 
     private void sleep() { 
      try { 
       Thread.sleep((this.last - System.nanoTime() + Constants.OPTIMAL)/1000000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }.start(); 
} 

내 도면 영역 :

public void paintComponent(Graphics g) { 
    Graphics2D g2d = (Graphics2D) g; 
    int translateAmount = this.game.getLevel().getTranslate(); 
    g.translate(-translateAmount, 0); 
    this.background.render(g2d);   
    this.game.getLevel().renderLevel(g2d); 
    g.translate(0, 0); 
    this.game.getBird().render(g2d); 

} 

나는 배경을 렌더링하는 방법이있다 : 나는 한 후 배경 하나를 추가하고 배경 프레임의 외부에있는 경우 , 나는 그것을 렌더링하지 않을 것이다.

public void render(Graphics2D g) { 
    Iterator<RepeatedBackground> itr = this.repeats.iterator(); 
    while (itr.hasNext()) { 
     RepeatedBackground b = itr.next(); 
     if (this.game.getLevel().getTranslate() - b.getX() >= 300) { 
      itr.remove(); 
      continue; 
     } 
     if (b.getX() - this.game.getLevel().getTranslate() < Constants.WIDTH) { 
      b.render(g); 
     } 
    } 
} 

이 내가 (내가 델타를 사용 해달라고이에 대한 몇 가지 튜토리얼을 사용) 내 새를 이동하는 방법입니다 : 새 또는 배경에 지연의 원인이 될 수 무엇

private void update(double delta) { 
    if (System.currentTimeMillis() - this.level.getTime() >= Constants.TRANSLATE_SPEED) { 

     // move background 
     this.level.updateTranslate(); 
     this.level.setTime(); 

     // move bird 
     this.getBird().move(); 
    } 
} 

public void move() { 
    this.x += 2/1.10; 
} 

? 렌더링 방식이나 게임 루프에 문제가 있습니까?

FPS: 1724172 
FPS: 1551857 
FPS: 1494378 
FPS: 1471987 
FPS: 1434095 
FPS: 1629905 
+0

'Constants.OPTIMAL'은 (으)로 설정되어 있습니까? 잠을 못 자? – MadProgrammer

+0

@MadProgrammer 1000000000/FPS; 그 날 시간 초과 값을주는 것은 부정 – Artemkller545

+0

Nevermind, 그 오류를 수정, fps는 지금 194-160에서 sutck이고 때로는 200 이상 점프. – Artemkller545

답변

2

게임 루프가 나를 혼란 -하지만 그건 어렵지 않다)

기본적으로, 나는이 일을 이해, 그것은 ... 같은

뭔가를 작동합니다 :

FPS 항상이 인쇄

while (gamming) { 
    now = get current time; 
    update game state 
    delta = get current time - now 
    delay = desired delay - delta 
    wait for delay 
} 

renderupdate 메서드가 실행 및 계산에 걸리는 시간을 고려하지 않은 것처럼 보입니다. 그 요구 사항을 기반으로 기다릴 시간을 주다 ...

자, 당신의 delta 값이 무엇이라고 생각하는지 모르겠습니다 ... 현재 두 번째 시간? 그래서

다음 예는도

지금, 용서, 나는 일반적으로 작업 updaterender 방법에 임의의 지연과, 나에게 일정한 초당 25을 제공합니다 ... 내 예를 밖으로 떠 났어요 밀리 초, 그것은 내 가난하고 약한 마음에서 단순 해.

import java.util.concurrent.TimeUnit; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class TestGameLoop { 

    public static void main(String[] args) { 
     new TestGameLoop(); 
    } 

    public TestGameLoop() { 
     gameLoop(); 
    } 

    public static class Constants { 

     public static final double OPTIMAL = 25; // fps... 

    } 

    private boolean game = true; 
    private long lastLoop; 
    private long lastFps; 
    private long fps; 

    private void gameLoop() { 
     new Thread() { 

      private long last; 
      private long start; 
      private int wait; 

      public void run() { 

       // Calculate the optimal/maximum delay time 
       // This is converted to nanos so it can be 
       // used to calculate the actual delay... 
       long millisPerSecond = TimeUnit.MILLISECONDS.convert(1, TimeUnit.SECONDS); 
       long optimalDelay = Math.round(millisPerSecond/Constants.OPTIMAL); 

       optimalDelay = TimeUnit.MILLISECONDS.toNanos(optimalDelay); 

       // Last start of a "second" loop      
       long loop = System.nanoTime(); 
       // While gaming... 
       while (game) { 
        // Start of this cycle... 
        long now = System.nanoTime(); 

        // Update the state and render the 
        // current frame... 
        update(); 
        render(); 

        // How long did that update take?? 
        long timeTaken = System.nanoTime(); 
        long delta = timeTaken - now; 

        // Subtract the delay from the maximum delay 
        long delay = optimalDelay - delta; 
        if (delay > 0) { 
         try { 
          // Sleep expects milliseconds... 
          delay = TimeUnit.NANOSECONDS.toMillis(delay); 
          Thread.sleep(delay); 
         } catch (InterruptedException ex) { 
          ex.printStackTrace(); 
         } 
        } 

        // Calculate if we've being running for a second yet... 
        long loopDelay = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - loop); 
        // If the loop has been cycling for a second... 
        if (loopDelay >= 1) { 
         // Reset the loop time 
         loop = System.nanoTime(); 
         System.out.println("FPS = " + fps); 
         fps = 0; 
        } else { 
         // Add another frame to the pile... 
         fps++; 
        } 
       } 
      } 
     }.start(); 
    } 

    public void update() { 
     try { 
      Thread.sleep(Math.round(Math.random() * 20)); 
     } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
     } 
    } 

    public void render() { 
     try { 
      Thread.sleep(Math.round(Math.random() * 20)); 
     } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
     } 
    } 

} 
+0

좋은 예이지만 내 fps가 항상 FPS 근처에있는 이유는 무엇입니까? 1426207 – Artemkller545

+0

나는 조류에 대한 glithcing이 20fps에서 멈추거나 그 이하가 아니라는 것을 알아 냈습니다. 일부 게임은 완벽하게 작동하려면 60fps 미만이 필요할 수 있습니다. – Artemkller545

+0

당신의 프레임 레이트가 그렇게 높은 이유는 무엇입니까 ?? 제가 말했던 것처럼 당신이보고 시간을 계산하는 방식 일 수 있습니다, 당신의 게임 루프가 나를 혼란스럽게 만들었습니다. 대부분의 화면은 약 25mhz에서 새로 고침 만하므로 버퍼를 통해 손실되거나 버려지는 것이 있습니다. 인간의 눈은 60fps 이상의 요소이기도합니다. 대부분의 사람들은 실제로 차이를 보지 않을 것입니다 ... 개인적으로는 25fps 범위 내에서 대부분의 애니메이션을 평균 처리하지만 그 다음 간단한 애니메이션 만 수행합니다. – MadProgrammer