如何从多个外部类中调用 JPanel?

2024-04-02

我目前正在制作一款带有主菜单和您实际玩的世界的游戏。

我有一堂课叫Game,它继承自 JPanel 并实现Runnable, MouseListener, KeyListener and ActionListener接口 (仅包含重要部分)

我也有两节课InWorldHandler and OutWorldHandler分别用于处理世界内部和外部的机制。

The Game class:

public class Game extends JPanel implements Runnable, KeyListener, MouseListener, ActionListener
{
    protected JFrame frame;
    private Timer timer = new Timer(25, this);

    private World world;
    private Player player = new Player();

    private boolean draw;

    Game(World world)
    {
        frame = new JFrame("Minecraft 2D");
        this.world = world;
        player.enterWorld(world, this);
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        Graphics2D g2d = (Graphics2D)g;

        if(draw)
        {
            g2d.setColor(new Color(255, 255, 255));
            g2d.fillRect(0, 0, frame.getWidth(), frame.getHeight());

            draw = false;
            //Here, the in-game mechanics should be handled
            if(player.inWorld())
            {
                Chunk chunk = player.getLoadedChunk();
                for(int x = 0; x < 16; x++)
                {
                    for(int y = 0; y < 16; y++)
                    {
                        Block block = chunk.getBlockAt(x, y);
                        BufferedImage texture = block.getTexture();

                        g2d.drawImage(block.getTexture(), x*32, y*32, texture.getWidth()*2, texture.getHeight()*2, null);
                    }
                }
            }
            //Here, the out-game mechanics should be handled
            else
            {

            }
        }
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        this.repaint();
        draw = true;
    }

    @Override
    public void run()
    {
        draw = true;

        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(this);
        frame.setMinimumSize(new Dimension(518, 540));
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.addKeyListener(this);
        frame.addMouseListener(this);
        frame.setFocusable(true);
        frame.setVisible(true);
        frame.pack();
        timer.start();
    }
}

其他班级目前都空着尸体。我只是不知道该怎么做。

我想要InWorldHandler当玩家在游戏中时在面板上绘制的类,以及OutWorldHandler当玩家在主菜单中时的类,两者都在Game班级。我怎么做?


而不是拥有一个单一的JPanel,你为什么不尝试一下CardLayout https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html并切换是否显示InnerWorld or the OuterWorld根据确定您在程序中所处位置的标志。

当你正在实施时KeyListener,我认为这是为了让你能够移动你的角色,请看看这个问题上接受的答案:Keylistener 不适用于 JPanel https://stackoverflow.com/questions/16530775/keylistener-not-working-for-jpanel并使用KeyBindings反而。

还要避免使用setMimimum/Maximum/PreferredSize()并重写这些方法:我应该避免在 Java Swing 中使用 set(Preferred|Maximum|Minimum)Size 方法吗? https://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi

以这段代码为例:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Game {
    private JFrame frame;
    private JButton button;
    private boolean status;
    private JPanel[] cards;
    private CardLayout cl;
    private JPanel gamePane;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Game().createAndShowGUI());
    }

    private void createAndShowGUI() {
        frame = new JFrame(getClass().getSimpleName());
        button = new JButton("Switch Worlds");
        status = true; //True = Inner / False = Outer

        cl = new CardLayout();

        gamePane = new JPanel(cl);
        cards = new JPanel[2];

        cards[0] = new InnerWorld();
        cards[1] = new OuterWorld();

        gamePane.add(cards[0], "innerWorld");
        gamePane.add(cards[1], "outerWorld");

        button.addActionListener(e -> {
            status = !status;
            if (status) {
                cl.show(gamePane, "innerWorld");
            } else {
                cl.show(gamePane, "outerWorld");
            }
        });

        frame.add(gamePane);
        frame.add(button, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

@SuppressWarnings("serial")
class InnerWorld extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;

        g2d.drawString("Inner World", 50, 50);
    }

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

@SuppressWarnings("serial")
class OuterWorld extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;

        g2d.drawString("Outer World", 50, 50);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从多个外部类中调用 JPanel? 的相关文章

随机推荐