简体   繁体   English

为什么我的paintComponent()方法没有被调用?

[英]Why isn't my paintComponent() method getting called?

Here are my classes that do the rendering: 这是我进行渲染的类:

Game.java 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 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++;
    }
}

My game had been working fine but I needed to add a time tick function because the game logic would tick at the same rate as the graphics, and I eventually intend to add multiplayer support, so I obviously need a fixed time tick rate for the logic. 我的游戏一直运行良好,但是我需要添加一个时间刻度功能,因为游戏逻辑的滴答速度与图形相同,因此我最终打算添加多人游戏支持,因此我显然需要固定的时间滴答速度。 I've tried to implement a loop here, but I can't figure out why my paintComponent() method isn't getting called. 我试图在这里实现一个循环,但是我无法弄清楚为什么我的paintComponent()方法没有被调用。 Any help is appreciated. 任何帮助表示赞赏。

Swing paint methods need to be invoked by the event handler thread. 需要事件处理程序线程调用Swing Paint方法。 See http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html#single_thread_rule 请参阅http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html#single_thread_rule

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM