游戏循环和按钮的Java图形问题



我正在制作一个包含游戏面板的游戏,游戏循环在其中绘制游戏。它还包含一个面板,面板上有一个启动游戏循环的按钮。游戏面板的背景只能在游戏开始时绘制一次。这是因为游戏图形不应该在每次重新绘制时被擦除。我遇到了两个问题,一开始没有绘制背景,二是在游戏面板上绘制了开始循环的按钮。

我试图将问题简化为最简单的形式,以下是我所拥有的:

public class Graphics_Trouble extends JFrame
{
private MainPanel mainPanel = new MainPanel();
private JPanel menuPanel = new JPanel();
private JButton start = new JButton("Start");
public Graphics_Trouble()
{
start.addActionListener(new java.awt.event.ActionListener()
{
@Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
StartActionPerformed(evt);
}
});
menuPanel.add(start);
add(menuPanel, BorderLayout.PAGE_START);
add(mainPanel, BorderLayout.CENTER);
pack();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void StartActionPerformed(java.awt.event.ActionEvent evt)
{
mainPanel.start();
}
public static void main(String[] args)
{
java.awt.EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
new Graphics_Trouble().setVisible(true);
}
});
}
}
class MainPanel extends JPanel
{
private Timer timer;
private boolean first = true;
public MainPanel()
{
timer = new Timer(30, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
timedAction();
}
});
}
@Override
public Dimension getPreferredSize()
{
Dimension size = new Dimension(300, 400);
return size;
}
@Override
public void paintComponent(Graphics g)
{
if(first)
{
g.setColor(Color.black);
g.fillRect(0, 0, 300, 400);
}
first = false;
}
public void timedAction()
{
repaint();
}
public void start()
{
timer.start();
}
}

当运行时,这会产生带有"开始"按钮的框架,但没有颜色,当按下"开始"键时,按钮会被绘制到另一个面板上,这是我无意的。

谢谢

你的绘画是错误的

  • 不是第一次绘制背景,而是必须每隔绘制一次
  • 因此,创建一个BufferedImage,将背景绘制到图像中(一次(,然后在paintComponent中绘制图像
  • 始终在您自己的override方法中首先调用super.paintComopnent(g);,否则您将看到诸如按钮图像之类的伪像,正如您现在看到的那样
  • 请确保Timer的侦听器比当前"更智能"。对象的状态应该根据Timer而不是绘制方法进行更改。绘画方法应该只反映物体的状态,而不是改变它

还有:

  • 不要将同一组件添加到GUI中两次。只添加一次
  • 如果背景图像只是将背景绘制为统一的颜色——填充JPanel,那么只需在JPanel的构造函数中调用setBackground(Color.BLACK);

例如

@SuppressWarnings("serial")
public class MainPanel2 extends JPanel {
private static final int PREF_W = 300;
private static final int PREF_H = 400;
private static final Color RECT_COLOR = Color.BLACK;
private static final Color COLOR1 = Color.pink;
private static final Color COLOR2 = new Color(158, 185, 212);
private BufferedImage background;
public MainPanel2() {
background = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = background.createGraphics();
g2.setPaint(new GradientPaint(0, 0, COLOR1, 20, 20, COLOR2, true));
g2.fillRect(0, 0, PREF_W, PREF_H);
g2.dispose();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
g.drawImage(background, 0, 0, this);
}
// do your other drawing here
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
// timer code
}

最新更新