我目前正在尝试将图像打印到屏幕上,以准备创建游戏。我可以自己显示图像,但前提是图像必须在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
中运行时代码也可以正常工作。我想念什么?
答案 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;)