如何从多个外部类中绘制 JPanel? [英] How do I draw on a JPanel from multiple outside classes?
问题描述
我目前正在制作一款带有主菜单和您实际玩的世界的游戏.
我有一个名为Game
的类,它继承自JPanel并实现了Runnable
、MouseListener
、KeyListener
和 ActionListener
接口(仅包含重要部分)
我还有两个类 InWorldHandler
和 OutWorldHandler
分别用于处理世界内外的机制.
Game
类:
公共类 Game 扩展 JPanel 实现 Runnable、KeyListener、MouseListener、ActionListener{受保护的 JFrame 框架;private Timer timer = new Timer(25, this);私人世界;私人播放器播放器 = 新播放器();私人布尔抽奖;游戏(世界世界){frame = new JFrame("我的世界 2D");this.world = 世界;player.enterWorld(world, this);}@覆盖protected voidpaintComponent(Graphics g){Graphics2D g2d = (Graphics2D)g;如果(画){g2d.setColor(新颜色(255, 255, 255));g2d.fillRect(0, 0, frame.getWidth(), frame.getHeight());画=假;//这里,应该处理游戏内的机制如果(玩家.在世界()){块块 = player.getLoadedChunk();for(int x = 0; x <16; x++){for(int y = 0; y <16; y++){块块 = chunk.getBlockAt(x, y);BufferedImage 纹理 = block.getTexture();g2d.drawImage(block.getTexture(), x*32, y*32, texture.getWidth()*2, texture.getHeight()*2, null);}}}//这里,应该处理游戏外的机制别的{}}}@覆盖public void actionPerformed(ActionEvent e){this.repaint();画=真;}@覆盖公共无效运行(){画=真;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);框架.pack();定时器开始();}}
其他两个类目前都有空的主体.我只是不知道该怎么做.
我希望 InWorldHandler
类在玩家在游戏中时在面板上绘制,而 OutWorldHandler
类在玩家在主菜单中时,两者都被调用Game
类.我该怎么做?
与其使用单个 JPanel
,不如尝试使用
I am currently making a game with a main menu and a world where you actually play.
I have a class called Game
, which inherits from JPanel and implements the Runnable
, MouseListener
, KeyListener
and ActionListener
interfaces
(only important parts included)
I also have two classes InWorldHandler
and OutWorldHandler
for handling the mechanics in the world and outside of it respectively.
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();
}
}
Both the other classes have empty bodies currently. I just have no idea how to do that.
I want the InWorldHandler
class to draw on the panel when the player is in game, and the OutWorldHandler
class when the player is in the main menu, both called in the Game
class. How do I do that?
Instead of having a single JPanel
, why don't you try with a CardLayout
and switch whether to show the InnerWorld
or the OuterWorld
according to a flag that determines where in the program you're at.
As you're implementing KeyListener
, I think that's for you to be able to move your character, please take a look at the accepted answer on this question: Keylistener not working for JPanel and use KeyBindings
instead.
Also avoid the use of setMimimum/Maximum/PreferredSize()
and override those methods instead: Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
Take this code as an example:
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);
}
}
这篇关于如何从多个外部类中绘制 JPanel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!