drawImage () отказывается рисовать изображения, созданные вне метода - PullRequest
0 голосов
/ 25 мая 2019

В настоящее время я пытаюсь распечатать изображения на экране, чтобы подготовиться к созданию игры. Я МОГУ отображать изображения самостоятельно, но только если изображение создается в классе 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 Ответ

0 голосов
/ 25 мая 2019

Хорошо, я бы сделал 2 вещи по-разному: во-первых, я протестировал обе версии, и обе у меня не работали. Я полагаю, это может быть вызвано бесконечным циклом, который вы создаете в конструкторе, поскольку он никогда не выйдет из него.

Помимо того, что у вас, похоже, есть ошибка в вашем paintMethod (на самом деле это должен быть метод рисования и переопределение супер-метода в JPanel), вам потребуется внести изменения в обновления. Я бы посоветовал вам взглянуть на «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 для каждой сущности;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...