【问题标题】:JPanel not rendering when added to other JPanelJPanel 添加到其他 JPanel 时不呈现
【发布时间】:2015-05-26 03:46:36
【问题描述】:

这是我的游戏课:

package Game;

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

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

public class Game extends JPanel implements Runnable {
    Thread thread;
    private boolean running = true;
    private double FPS = 1.0/60.0;
    private Level level;

    public Game(){
        level = new LevelOne();
        level.setBackground(Color.BLACK);
        add(level);
    }

    public synchronized void start() {
        thread = new Thread(this, "Game");
        thread.start();
    }

    public synchronized void stop() {
        running = false;
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        double firstTime = 0;
        double lastTime = System.nanoTime() / 1000000000.0;
        double passedTime = 0;
        double updateTime = 0;
        double timer = System.nanoTime() / 1000000000.0;
        int rendered = 0;
        int updates = 0;


        while (running) { 
            firstTime = System.nanoTime() / 1000000000.0;
            passedTime = firstTime - lastTime;
            lastTime = firstTime;

            updateTime += passedTime;

            while(updateTime > FPS){
                updates++;
                update();
                updateTime -= FPS;
            }

            render();
            rendered++;
            if((System.nanoTime() / 1000000000) - timer > 1){
                timer += 1;
                System.out.println("FPS:"+rendered+" Updates:"+updates);
                updates = 0;
                rendered = 0;
            }
        }
    }

    private void update() {

    }

    private void render() {
        this.repaint();
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        level.repaint();
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setLocationRelativeTo(null);
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setTitle("Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Game game = new Game();
        frame.add(game);
        game.start();
    }

}

我的 LevelOne 课程: 打包游戏;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class LevelOne extends Level {
    private BufferedImage spriteSheet;
    private BufferedImage[] player = new BufferedImage[4]; //0 = down, 1 = right, 2 = up, 3 = left
    private int dir = 0;
    private String UP = "W";
    private String DOWN = "S";
    private String LEFT = "A";
    private String RIGHT = "D";
    private int speedX = 0;
    private int speedY = 0;

    public LevelOne(){
        try {
            spriteSheet = ImageIO.read(new File("images/sprites.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        for (int i = 0; i < 4; i++) {
            player[i] = spriteSheet.getSubimage((i * 18), 0, 18, 28);
        }

        this.addKeyListener(new KeyListener() {
            @Override
            public void keyPressed(KeyEvent e) {
                String key = e.getKeyText(e.getKeyCode());
                if (key.equals(UP)) {
                    dir = 2;
                    speedY = -5;
                } else if (key.equals(LEFT)) {
                    dir = 3;
                    speedX = -5;
                } else if (key.equals(RIGHT)) {
                    dir = 1;
                    speedX = 5;
                } else if (key.equals(DOWN)) {
                    dir = 0;
                    speedY = 5;
                }
            }
            @Override
            public void keyReleased(KeyEvent e) {
                String key = e.getKeyText(e.getKeyCode());
                if (key.equals(UP)) {
                    speedY = 0;
                } else if (key.equals(LEFT)) {
                    speedX = 0;
                } else if (key.equals(RIGHT)) {
                    speedX = 0;
                } else if (key.equals(DOWN)) {
                    speedY = 0;
                }
            }
            @Override
            public void keyTyped(KeyEvent e) {

            }
        });
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(player[dir], 0, 0, 18, 28, null);
    }
}

LevelOne 扩展了当前为空的 Level(并扩展了 JPanel),我不确定是否需要向 Level 添加任何内容。我只是不明白我需要做什么才能让播放器图像显示出来......

抱歉,如果我的代码草率,我正在尝试进入更高级别的 Java,但我不确定我是否只是错误地接近它。

谢谢。

【问题讨论】:

  • 不要从paintComponent内部调用level.repaint
  • 那么我应该在render 中调用它吗?
  • Level 可能看起来像...?
  • 目前Level是空的,不知道要添加什么方法,虽然它确实扩展了JPanel

标签: java swing jframe jpanel paintcomponent


【解决方案1】:

六件事……

  1. 不要在GamepaintComponent 方法中调用level.repaint,这可能会导致重绘请求的无限循环,这将影响您的帧速率。考虑在你的渲染方法中调用它
  2. paintComponent 永远不应该 public,任何人都没有理由直接调用它。
  3. KeyListener 上使用键绑定,它们将解决焦点相关的问题。 How to Use Key Bindings
  4. frame.add(game); 之后移动frame.setVisible,事实上,它真的应该是你做的最后一件事
  5. 确保您的图片加载正确
  6. Game 的布局管理器设置为BorderLayout

【讨论】:

  • 我把frame.setVisible移到最后,这解决了问题,谢谢:)
  • @em202020 小心其他人,他们会回来咬你的
猜你喜欢
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 2021-05-19
  • 2018-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多