将png作为SpriteJava加载

将png作为SpriteJava加载,java,image,swing,jpanel,Java,Image,Swing,Jpanel,首先,我很抱歉我的英语不好。 我知道我的问题很相似,可能和其他人的问题一样,很多人在网上提出的问题都是一样的。但是我试过很多,但都不管用。很简单,我不知道我的错 这是权变学: 我有5个类,它们是Game.java、Player.java、Menu.java、System.java和Control.java。 Control类是一个KeyListener类,因此它用于从键盘进行控制。 System类是主类,用于显示JFrame。 菜单类用于显示背景和按钮的菜单。它扩展了JPanel。 玩家类,当然

首先,我很抱歉我的英语不好。 我知道我的问题很相似,可能和其他人的问题一样,很多人在网上提出的问题都是一样的。但是我试过很多,但都不管用。很简单,我不知道我的错

这是权变学:

我有5个类,它们是Game.java、Player.java、Menu.java、System.java和Control.java。 Control类是一个KeyListener类,因此它用于从键盘进行控制。 System类是主类,用于显示JFrame。 菜单类用于显示背景和按钮的菜单。它扩展了JPanel。 玩家类,当然是玩家统计。 java是我项目的核心,因为它控制着游戏性

那么,我如何加载播放器的png。我的结构是系统调用菜单,然后菜单调用游戏(新的游戏按钮),然后游戏调用玩家类。但当我点击“新建游戏”按钮或按enter键时,什么也没发生,其他的都很好(加载背景,退出按钮)

System.java

public class System extends JFrame{
private final int lebar=954;
private final int tinggi=540;

private static boolean[] kibod = new boolean[525];

public System(){
    this.setTitle("Unknown man Unkown power");
    this.setSize(new Dimension(lebar,tinggi));
    this.setFocusable(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setResizable(false);
    this.setContentPane(new Menu());
    this.addKeyListener(new Control());
    this.setVisible(true);

}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            new Sistem();
        }
    });
}

}
Menu.java

public class Menu extends JPanel{
 private int l=954;
private int t=540;

JButton menu1=new JButton("MULAI BARU");
JButton menu2=new JButton("KELUARRR");

public Menu(){
    this.add(menu1);
    this.add(menu2);

    menu1.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            new Game();
        }
    });
    menu2.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            System.exit(0);
        }
    });

}
}
Player.java

public class Player extends JPanel{
private int posx=System.WIDTH/3;
private int posy=System.HEIGHT/3;

private BufferedImage im;
private Graphics gr;

public void loadl() {
    try {
        im=ImageIO.read(new File("res/glakon2.png"));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
public void paint(Graphics g) {
    gr=g;
    g.drawImage(im, posx, posy, System.WIDTH/3, System.HEIGHT/3, this);
}
public Player(){
    loadl();
}
}
Game.java

public class Game{

public Game() {

    new Player();
}
}
游戏类仍然是空的,至于我只是想测试它是否显示。我试着用

URL u=this.getClass().getResource("res/glakon2.png");
im=ImageIO.read(u);

我的png是一个spritesheet png,只包含2个图像。那么我如何加载它呢? 感谢您的关注和帮助


抱歉,我编辑了Game.java以匹配这个问题,真正的问题是它的Gameplay.java。

当我使用下面的设置时,它工作正常

new ImageIcon(TestIMage.class.getResource("/res/stackoverflow5.png"));


编辑

此外,我认为你面临的一个问题是没有一个优先的专家组成员。您应该@Override面板的
getPreferredSize()
。像这样的

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(DIM_W, DIM_H);
    }
您还应该重写
paintComponent
方法并调用
super.paintComponent
,而不是像这样调用
paint

   @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        gr = g;
        g.drawImage(im, 0, 0, DIM_W, DIM_W, this);
    }
运行此测试。我用了你的
播放器

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class TestIMage {

    public TestIMage() {

        JFrame frame = new JFrame();
        frame.add(new Player());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TestIMage();
            }
        });
    }

    private class Player extends JPanel {

        private  int DIM_W;
        private  int DIM_H;

        private BufferedImage im;
        private Graphics gr;

        public void loadl() {
            try {
                im = ImageIO.read(TestIMage.class.getResource("/res/stackoverflow5.png"));
                DIM_W = im.getWidth();
                DIM_H = im.getHeight();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(DIM_W, DIM_H);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            gr = g;
            g.drawImage(im, 0, 0, DIM_W, DIM_W, this);
        }

        public Player() {
            loadl();
        }
    }
}
class Game extends JDialog {
    public Game(JFrame frame, boolean modal) {
        super(frame, modal);
        setLayout(new BorderLayout());
        add(new Player());

        pack();
        setVisible(true);
    }
}

更新 此外,您还需要确保将
Player
添加到顶级容器中,如
JDialog
。当前在
游戏
类中,您所做的只是在
玩家
类的实例中创建,但您从未将
玩家
添加到容器中。如果你想使用
JDialog
,你可以在
游戏
类中使用

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class TestIMage {

    public TestIMage() {

        JFrame frame = new JFrame();
        frame.add(new Player());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TestIMage();
            }
        });
    }

    private class Player extends JPanel {

        private  int DIM_W;
        private  int DIM_H;

        private BufferedImage im;
        private Graphics gr;

        public void loadl() {
            try {
                im = ImageIO.read(TestIMage.class.getResource("/res/stackoverflow5.png"));
                DIM_W = im.getWidth();
                DIM_H = im.getHeight();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(DIM_W, DIM_H);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            gr = g;
            g.drawImage(im, 0, 0, DIM_W, DIM_W, this);
        }

        public Player() {
            loadl();
        }
    }
}
class Game extends JDialog {
    public Game(JFrame frame, boolean modal) {
        super(frame, modal);
        setLayout(new BorderLayout());
        add(new Player());

        pack();
        setVisible(true);
    }
}
您可以在
操作中执行此操作

menu1.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent arg0) {
        new Game(System.this, true);
    }
});

更新2 :)它可以工作,我创建了测试类,并通过系统类调用它,但如果我从游戏类调用它,它将不会出现。关于JDialog,它是否创建了另一个JFrame?我认为它很简单,只有一个JFrame(它在系统类中声明)

我不确定你的程序的流程。我不知道你想用
Game
class做什么。如果希望
播放器
位于主帧中,则必须
。如果播放器位于主帧中,则必须添加
。您不能使用
Game
类来实现这一点,因为
Game
类不是组件。如果要在按下按钮时显示
播放器
屏幕,可以使用
卡片布局

这里有一个例子

import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class TestIMage {
    private Player player = new Player();
    private JPanel introPanel = new JPanel();
    private CardLayout cardLayout = new CardLayout();
    private JButton button = new JButton("View Player");
    private JPanel mainPanel = new JPanel(cardLayout);

    public TestIMage() {
        introPanel.setPreferredSize(player.getPreferredSize());
        introPanel.setLayout(new GridBagLayout());
        introPanel.add(button);

        mainPanel.add(introPanel, "introPanel");
        mainPanel.add(player, "playerPanel");

        button.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                cardLayout.show(mainPanel, "playerPanel");
            }
        });

        JFrame frame = new JFrame();
        frame.add(mainPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TestIMage();
            }
        });
    }

    private class Player extends JPanel {


        private  int DIM_W;
        private  int DIM_H;

        private BufferedImage im;
        private Graphics gr;

        public void loadl() {
            try {
                im = ImageIO.read(TestIMage.class.getResource("/res/stackoverflow5.png"));
                DIM_W = im.getWidth();
                DIM_H = im.getHeight();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(DIM_W, DIM_H);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            gr = g;
            g.drawImage(im, 0, 0, DIM_W, DIM_W, this);
        }

        public Player() {
            loadl();
        }
    }
}

图像位于何处?请尝试
.getResource(“/res/glakon2.png”)。添加了额外的
/
。您的文件
res
应该直接是'res'文件夹上的
src
的子文件,正如我在buld中设置的'res'path@peeskillet它仍然不起作用,我只是尝试了ittry.getResource(“C:/…../res/glakon2.png”);imageits的完整路径仍然不起作用,我使用了“ImageIcon”并在Player.java中添加了“JLabel”,它仍然显示错误。错误为线程“AWT-EventQueue-0”java.lang.NullPointerExceptionSee my EDIT中的异常。我认为这是首选sizeI的一个问题,我在游戏项目中使用BuffereImage作为玩家加载程序,ImageIcon可以作为可控对象吗?喜欢移动吗?如果你在画画,你应该使用
buffereImage
。不是
图像图标
。我只是用了一个简单的例子,不用画画。但是我在我的编辑中使用了你的类,它也很好用。你必须记住将
播放器面板的实例添加到容器中。您的
游戏
类在实例化
玩家