【问题标题】:Image won't paint to animation图像不会绘制到动画
【发布时间】:2012-03-10 19:13:31
【问题描述】:

在 Java 小程序中加载/显示图像时遇到问题。不确定我是否错误地加载了图像,或者我是否错误地访问了它。这是绘制船和背景的代码(这是一个类似小行星的游戏)。背景绘制正确,但船没有。这是我正在处理的主要类方法:

public void paintFrame(Graphics g) {
        Dimension d = size();
        g.fillRect(0, 0, d.width, d.height);
        g.drawImage(ship.getImage(), d.width/2, d.height/2, null);
}

我在类的开头创建了一个 ship 类的实例。但是,如果我尝试在方法中实例化 ship 类(例如“Ship ship = new Ship();”),它会说从未使用过变量“ship”。

这是整个船级:

public class Ship {
    private int dx;
    private int dy;
    private int x;
    private int y;
    private Image image;    

    public Ship() {
        ImageIcon ii = new ImageIcon("ship1.png");
        image = ii.getImage();
    }

    public Image getImage() {
        return image;
    }
}

如果我按原样运行它,它会运行没有错误,但它不会显示飞船。如果我尝试在除顶部以外的其他任何地方创建船的实例,它会给我一个 NullPointerException。

更新

这是我的整个主要课程:

import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;

public class RunGame extends Applet implements Runnable {
    int frame;
    int delay;
    Thread animator;
    Ship ship = new Ship();
    Level level;
    Dimension offDimension;
    Image offImage;
    Graphics offGraphics;

    /**
     * Initialize the applet and compute the delay between frames.
     */
    public void init() {
        String str = getParameter("fps");
        int fps = (str != null) ? Integer.parseInt(str) : 10;
        delay = (fps > 0) ? (1000 / fps) : 100;

    }

    /**
     * Method is called when the applet becomes visible on
     * the screen.
     */
    public void start() {
    animator = new Thread(this);
    animator.start();

    }

    /**
     * This method is called by the thread that was created in
     * the start method. It does the main animation.
     */
    public void run() {
    // Remember the starting time
    long tm = System.currentTimeMillis();
    while (Thread.currentThread() == animator) {
        // Display the next frame of animation.
        repaint();

        // Delay depending on how far we are behind.
        try {
        tm += delay;
        Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));
        } catch (InterruptedException e) {
        break;
        }

        // Advance the frame
        frame++;
    }
    }

    /**
     * This method is called when the applet is no longer
     * visible. Set the animator variable to null so that the
     * thread will exit before displaying the next frame.
     */
    public void stop() {
    animator = null;
    offImage = null;
    offGraphics = null;
    }

    /**
     * Update a frame of animation.
     */
    public void update(Graphics g) {
        Dimension d = size();

        // Create the offscreen graphics context
        if ((offGraphics == null) || (d.width != offDimension.width) || (d.height != offDimension.height)) {
            offDimension = d;
            offImage = createImage(d.width, d.height);
            offGraphics = offImage.getGraphics();
        }

        // Erase the previous image
        offGraphics.setColor(getBackground());
        offGraphics.fillRect(0, 0, d.width, d.height);
        offGraphics.setColor(Color.black);

        // Paint the frame into the image
        paintFrame(offGraphics);

        // Paint the image onto the screen
        g.drawImage(offImage, 0, 0, null);
    }

    /**
     * Paint the previous frame (if any).
     */
    public void paint(Graphics g) {
        if (offImage != null) {
            g.drawImage(offImage, 0, 0, null);
        }
    }

    /**
     * Paint a frame of animation.
     */
    public void paintFrame(Graphics g) {
        Dimension d = size();
        g.fillRect(0, 0, d.width, d.height);
        //g.drawImage(level.getImage(), 0, 0, null);
        g.drawImage(ship.getImage(), 400, 300, null);
    }
}

【问题讨论】:

  • paintFrame() 是从paintComponent 方法中调用的吗?请看这里:Performing Custom Painting with Swing.
  • 你不应该从绘图方法中读取图像开始 - 在 once 中读取它,例如在类的构造函数中,并使用 ImageIO.read(...) 来执行此操作.你的 NPE 被扔到哪里去了?您是否正在测试图像是否真的被读入?您的图像是否位于 user.dir 中?或者说,图像文件相对于所有内容的确切位置
  • @HovercraftFullOfEels :请原谅,但 JApplets 没有 paintComponent(...) 方法,似乎 OP 正在使用 JApplet,因为他的问题是“在 Java 小程序中加载/显示图像时遇到问题"。
  • @GagandeepBali:请原谅,但您应该永远直接在 JApplet 中绘图。您应该在 JApplet 持有的 JPanel 或 JComponent 中绘制 paintComponent(...) 方法。你应该知道这一点。
  • @HovercraftFullOfEels :是的,毫无疑问,借鉴JPanel 是要走的路。我只是指着你的第一条评论。你最近的评论太真实了。怀疑引发了许多不必要的问题:-)

标签: java animation awt drawimage


【解决方案1】:
ImageIcon ii = new ImageIcon("ship1.png");  

接受StringImageIcon constructor 假定字符串表示..

..文件名或文件路径。

'小程序和文件不能混合。'只有受信任的小程序才能加载File 对象,即便如此,也只能从最终用户的文件系统中加载。 File 对象不能指向服务器。

Applet 更典型地适用于由 URL 形成的路径。 Applet 类提供了许多方法来帮助形成该 URL,并且 ImageIcon 构造函数被重载以接受 URL。

..不确定是我加载图像不正确还是访问不正确。

调试101是在加载后立即显示图像。将图像图标拖放到标签中并使用JOptionPane 显示标签。

【讨论】:

    【解决方案2】:

    如果没有看到您的完整代码,我们无法真正判断异常发生了什么,但在您对 drawImage() 的调用中,将“this”指定为最后一个参数,而不是 null。图像是异步加载的,因此他们需要一些实现 ImageObserver 的东西(例如您的框架)来告诉他们何时设法加载更多(或全部) - 以便他们可以重新绘制。

    【讨论】:

    • 绘制图像时使用ImageObserver 的好建议。 +1
    猜你喜欢
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-09
    相关资源
    最近更新 更多