drawImage()拒绝绘制在方法外部实例化的图像

时间:2019-05-25 15:36:18

标签: java graphics

我目前正在尝试将图像打印到屏幕上,以准备创建游戏。我可以自己显示图像,但前提是图像必须在paintComponents()类中实例化。我当然不想在每一帧重新实例化整个电路板,但似乎无法使其正常工作。我该怎么办?

我试图在全班级声明一个图像,并在该类的构造函数中实例化它。但是,一旦我尝试致电drawImage(),该图片就拒绝显示。我在printComponents()中实例化了该问题后,该问题就消失了。我尝试过(少量)使用JLabel和JIcon,但是运气不高。尤其是因为我不能在JLabel中使用drawImage。

这是不起作用的工作:

public class Skeleton extends JPanel
{

    BufferedImage img = null;

    public Skeleton()
    {
        try{
            img = ImageIO.read(new File(myFile.png));
        } catch (IOException e){
            System.out.println("Loading failed.");
        }
        while(true)
        {
            repaint();
        }
    }

    public paintComponents(Graphics g)
    {
        g.drawImage(img, 50, 50, null);
    }   
}

此功能有效:

public class Skeleton extends JPanel
{


    public Skeleton()
    {
        while(true)
        {
            repaint();
        }
    }

    public paintComponents(Graphics g)
    {
        BufferedImage img = null;
        try{
            img = ImageIO.read(new File(myFile.png));
        } catch (IOException e){
            System.out.println("Loading failed.");
        }

        g.drawImage(img, 50, 50, null);
    }   
}

我想最终创建一个包含预加载图像的Tile对象的双重数组,例如myFile.png,例如g.drawImage(tiles[1][1].getTexture(), 50, 50, null);

加载文件是可行的,因为我永远不会抛出异常,并且在paintComponents中运行时代码也可以正常工作。我想念什么?

1 个答案:

答案 0 :(得分:0)

好吧,我将做两件不同的事情:首先,我测试了两个版本,但两个版本都不适合我。我想这可能是由您在构造函数中创建的无限循环引起的,因为它永远不会退出循环。

除此之外,您似乎在paintMethod中有一个错误(它实际上应该是paint,并且重写了JPanel中的super方法),您将需要对更新进行更改。我建议您看看“ Game-Loops”,尽管它也可以为每个实例使用单独的线程,尽管我建议不要这样做。我更正了您的代码,以便您可以看一下:带有单独线程的第一个版本:

package stackoverflowtests;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

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

public class Skeleton extends JPanel implements Runnable {

    private BufferedImage img = null;

    public Skeleton() {
        setSize(1000, 500);
        try {
            img = ImageIO.read(new File("index.jpg"));
        } catch (IOException e) {
            System.out.println("Loading failed.");
        }
    }

    public void paint(Graphics g) {
        g.drawImage(img, 50, 50, null);
    }

    @Override
    public void run() {
        while (true) repaint();
    }

}

主要是这样的:

package stackoverflowtests;

import javax.swing.JFrame;

public class Main extends JFrame {

    public Main() {
        setSize(1280, 720);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Skeleton skeli = new Skeleton();
        skeli.setLocation(0, 0);
        skeli.setSize(1000, 500);
        add(skeli);
        new Thread(skeli).start();
        setVisible(true);
    }

    public static void main(String[] args) {
        Main main = new Main();

    }
}

带有游戏循环的可能性2:

package stackoverflowtests;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

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

public class Skeleton extends JPanel {

    private BufferedImage img = null;

    public Skeleton() {
        setSize(1000, 500);
        try {
            img = ImageIO.read(new File("index.jpg"));
        } catch (IOException e) {
            System.out.println("Loading failed.");
        }
    }

    public void paint(Graphics g) {
        g.drawImage(img, 50, 50, null);
    }

}

主要:

package stackoverflowtests;

import javax.swing.JFrame;

public class Main extends JFrame {

    public Main() {
        setSize(1280, 720);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Skeleton skeli = new Skeleton();
        skeli.setLocation(0, 0);
        skeli.setSize(1000, 500);
        add(skeli);
        setVisible(true);
    }

    public static void main(String[] args) {
        Main main = new Main();

        // Gameloop
        long lastTime = System.nanoTime();
        double amountOfTicks = 60.0;
        double ns = 1000000000 / amountOfTicks;
        double delta = 0;
        long timer = System.currentTimeMillis();
        int frames = 0;
        while (true) {
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            while (delta >= 1) {
                // updates++;
                delta--;
            }
            System.out.println("repaint");
            main.repaint();
            frames++;
        }
    }
}

您需要问自己的第二件事是您是否可以仅对每个实体使用BufferedImage对象而不是整个JPanel;)