为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

qq_遁去的一_1 2022-12-15 16:44:00
我目前正在尝试将图像打印到屏幕上以准备创建游戏。我可以自己显示图像,但前提是图像在paintComponents()类中实例化。我,当然,不想每一帧都重新实例化整个板,但似乎无法让它工作。我将如何做到这一点?我试图在类范围内声明一个图像并在类的构造函数中实例化它。但是,一旦我尝试打电话drawImage(),图像就拒绝显示。一旦我将它实例化,这个问题就消失了printComponents()。我曾尝试(轻微地)使用 JLabel 和 JIcon,但运气不佳。特别是因为我不能将 drawImage 与 JLabel 一起使用。这是行不通的: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 回答

?
绝地无双

TA贡献1946条经验 获得超4个赞

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


除此之外,您的 paintMethod 似乎有错误(实际上应该是绘制并覆盖 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 ;)


查看完整回答
反对 回复 2022-12-15
  • 1 回答
  • 0 关注
  • 76 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信