2012-04-12 145 views
2

这里是我的类,做渲染:为什么不调用paintComponent()方法?

Game.java

package poke; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.GridLayout; 
import java.awt.Image; 
import java.awt.Toolkit; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

import poke.GamePanel; 

import poke.graphics.GraphicsHandler; 
import poke.player.Player; 
import poke.player.PlayerHandler; 
import poke.world.WorldHandler; 

public class Game extends JFrame implements MouseListener, MouseMotionListener, KeyListener { 

    private GamePanel gamePanel = new GamePanel(); 
    public static Toolkit toolkit = Toolkit.getDefaultToolkit(); 
    public static final int gameWidth = 1280; 
    public static final int gameHeight = 720; 

    public static String version = "Indev v0.1"; 
    private boolean running = false; 

     private int fps = 60; 
     private int frameCount = 0; 

    // GAME INITIALIZATION 

    public Game() { 
     super("PokéRealms Client " + version); 
     JFrame f = new JFrame(); 
     setVisible(true); 
     running = true; 
     setSize(new Dimension(gameWidth, gameHeight)); 
     setResizable(false); 
     setBackground(Color.BLACK); 

     Image icon = toolkit.getImage("./data/graphics/misc/icon.png"); 
     setIconImage(icon); 

     addMouseListener(this); 
     addMouseMotionListener(this); 
     addKeyListener(this); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     runGameLoop(); 
    } 

    // RUN THREAD 

    public void runGameLoop() { 
     Thread loop = new Thread() { 
      public void run() { 
       gameLoop(); 
      } 
     }; 
     loop.start(); 
    } 

    // GAME LOOP 

    private void gameLoop() { 

     final double GAME_HERTZ = 30.0; 
     final double TIME_BETWEEN_UPDATES = 1000000000/GAME_HERTZ; 
     final int MAX_UPDATES_BEFORE_RENDER = 5; 
     double lastUpdateTime = System.nanoTime(); 
     double lastRenderTime = System.nanoTime(); 
     final double TARGET_FPS = 60; 
     final double TARGET_TIME_BETWEEN_RENDERS = 1000000000/TARGET_FPS; 

     int lastSecondTime = (int) (lastUpdateTime/1000000000); 

     while (running) { 

      double now = System.nanoTime(); 
      int updateCount = 0; 

      while(now - lastUpdateTime > TIME_BETWEEN_UPDATES && updateCount < MAX_UPDATES_BEFORE_RENDER) { 
       updateGame(); 
       lastUpdateTime += TIME_BETWEEN_UPDATES; 
       updateCount++; 
      } 

      if (lastUpdateTime - now > TIME_BETWEEN_UPDATES) { 
       lastUpdateTime = now - TIME_BETWEEN_UPDATES; 
      } 

      float interpolation = Math.min(1.0f, (float) ((now - lastUpdateTime)/TIME_BETWEEN_UPDATES)); 
      drawGame(interpolation); 
      lastRenderTime = now; 

      int thisSecond = (int) (lastUpdateTime/1000000000); 
      if(thisSecond > lastSecondTime) { 
       System.out.println("NEW SECOND " + thisSecond + " " + frameCount); 
       fps = frameCount; 
       frameCount = 0; 
       lastSecondTime = thisSecond; 
      } 

      while(now - lastRenderTime < TARGET_TIME_BETWEEN_RENDERS && now - lastUpdateTime < TIME_BETWEEN_UPDATES) { 
       Thread.yield(); 
       try { 
        Thread.sleep(1); 
       } catch(Exception e) { 
        System.err.println(e); 
       } 

       now = System.nanoTime(); 
      } 
     } 
    } 

    // UPDATES AND DRAWS 

    private void updateGame() { 
     gamePanel.update(); 
    } 

    private void drawGame(float interpolation) { 
     gamePanel.setInterpolation(interpolation); 
     gamePanel.repaint(); 
    } 

    // MAIN METHOD 

    public static void main(String[] args) { 
     Game game = new Game(); 
     System.out.println("Game initialized."); 
    } 
} 

GamePanel.java

package poke; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Image; 

import javax.swing.JPanel; 

import poke.graphics.GraphicsHandler; 
import poke.player.PlayerHandler; 
import poke.util.ClockTime; 
import poke.world.WorldHandler; 

public class GamePanel extends JPanel { 

    private static final long serialVersionUID = 1L; 
    Image image; 
    Graphics graphics; 
    float interpolation; 
    private int fps = 60; 
    private int frameCount = 0; 
    public boolean time = false; 
    public int lastSecond = 0; 

    public GamePanel() { 
     PlayerHandler.addPlayer(0); 
     WorldHandler.loadTiles(); 
     WorldHandler.loadObjects(); 
    } 

    public void setInterpolation(float interp) { 
     interpolation = interp; 
    } 

    public void update() { 
     PlayerHandler.processWalking(); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if(lastSecond != ClockTime.getSecond()) { 
      lastSecond = ClockTime.getSecond(); 
      time = !time; 
     } 

     GraphicsHandler.drawWorld(g, time); 
     PlayerHandler.process(g); 

     image = createImage(getWidth(), getHeight()); 
     graphics = image.getGraphics(); 
     g.drawImage(image, 0, 0, this); 

     g.setColor(Color.yellow); 
     g.drawString("FPS: " + fps, 5, 10); 

     frameCount++; 
    } 
} 

我的比赛一直工作正常,但我需要添加报时功能因为游戏逻辑会以与图形相同的速率进行打勾,并且我最终打算添加多人游戏支持,所以我显然需要逻辑的固定时间跳动率。我试图在这里实现一个循环,但我无法弄清楚为什么我的paintComponent()方法没有被调用。任何帮助表示赞赏。

+0

尚未进入tick函数,您确认'drawGame'正在被调用吗? – 2012-04-12 01:38:38

+0

是的,我刚才查了一下,确实是打电话来的。 – taylorthurlow 2012-04-12 02:17:49

+0

你怎么知道'paintComponent()'没有被调用 - 可能像'paint()'这样的更高级方法中的某个东西会覆盖你在'paintComponent()'中所做的更改?另外,在'drawGame()'中,你可以尝试通过调用'gamePanel.paintImmediately(0,0,width,height);'来强制重绘,看它是否没有被正确重绘。 – wattostudios 2012-04-12 03:02:02

回答

相关问题