Изображение не будет рисовать в анимации - PullRequest
1 голос
/ 10 марта 2012

Проблемы с загрузкой / отображением изображения в 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 = 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);
    }
}

Ответы [ 2 ]

3 голосов
/ 10 марта 2012
ImageIcon ii = new ImageIcon("ship1.png");  

Конструктор ImageIcon , который принимает String, предполагает, что строка представляет ..

.. имя файла или путь к файлу.

'Апплеты и файлы не смешиваются.'Только доверенный апплет может загрузить объект File, и даже тогда, только из файловой системы конечного пользователя.Объекты File не могут указывать на сервер.

Апплеты обычно работают с путями, сформированными из URL.Класс Applet предоставляет ряд методов, помогающих сформировать этот URL, а конструктор ImageIcon перегружен для принятия URL.

.. Не уверен, что я загружаю изображение неправильноили если я обращаюсь к нему неправильно.

Отладка 101 - это отображение изображения сразу после его загрузки.Поместите значок изображения в метку и используйте JOptionPane, чтобы отобразить метку.

1 голос
/ 10 марта 2012

Не видя вашего полного кода, мы не можем точно сказать, что происходит с исключением, но в вашем вызове drawImage () укажите 'this' в качестве последнего параметра вместо null. Изображения загружаются асинхронно, и поэтому им нужно что-то, что реализует ImageObserver (например, ваш кадр), чтобы сообщить, когда им удалось загрузить немного больше (или все это) - чтобы они могли перерисоваться.

...