BreezyGUI闪烁的绘制方法[Java]

时间:2015-04-12 22:19:12

标签: java graphics paint keylistener repaint

在有人说这个问题得到解答之前,我无法在任何地方找到这个,因为我没有使用缓冲图像,我使用g.drawRect(...)等等...我的目标,这就是我被告知要做的事情,因为我现在正在学习如何编码。但由于某种原因,屏幕一直闪烁,我想要一些帮助。

所以,我在编码方面很陌生,我正在尝试编写一个非常简单的炸弹人游戏。而且我没有使用BufferedImages,我只是使用Graphics paint来绘制角色。而且,当我添加KeyBinding时,我使用repaint()来更新"按下键时的游戏。但这是非常错误的,当我按下其中一个按钮时,它会出现故障并显示一个空白屏幕。我认为这是由于我重新粉刷它,但我不确定如何解决这个问题。以下是我正在使用的一些代码。

    public static void left(Graphics g) {
    bomberManLowerLeft(g, -90 + dx, -20 + dy);
    bomberManBodyLeft(g, -90 + dx, -20 + dy);
    bomberManFaceLeft(g, -90 + dx, -20 + dy);
}

public static void right(Graphics g) {
    bomberManLowerRight(g, -90 + dx, -20 + dy);
    bomberManBodyRight(g, -90 + dx, -20 + dy);
    bomberManFaceRight(g, -90 + dx, -20 + dy);
}

public void paint(Graphics g) {
    if (down) {
        front(g);
    } else if (up) {
        back(g);
    } else if (left) {
        left(g);
    } else if (right) {
        right(g);
    }
}

public static void main(String[] args) {
    Frame frm = new BomberMan();
    frm.setSize(750, 750);
    frm.setVisible(true);
    frm.add(panel);
    frm.setBackground(Color.black);
}

@Override
public void keyPressed(KeyEvent e) {
    int kCode = e.getKeyCode();
    if (kCode == KeyEvent.VK_D) {
        System.out.println("Right");
        dx += 3;
        down = false;
        right = true;
        left = false;
        up = false;
        repaint();
    } else if (kCode == KeyEvent.VK_A) {
        System.out.println("Left");
        dx -= 3;
        down = false;
        right = false;
        left = true;
        up = false;
        repaint();
    } else if (kCode == KeyEvent.VK_W) {
        System.out.println("Up");
        dy -= 3;
        down = false;
        right = false;
        left = false;
        up = true;
        repaint();
    } else if (kCode == KeyEvent.VK_S) {
        System.out.println("Down");
        dy += 3;
        down = true;
        right = false;
        left = false;
        up = false;
        repaint();
    } else if(kCode == KeyEvent.VK_SPACE){
        placeBomb = true;
        bombdx = dx;
        bombdy = dy;
        repaint();
    }

}

我真的可以使用这方面的帮助,谢谢。如果你确实需要完整的代码,那就是:PASTEBIN-CODE

1 个答案:

答案 0 :(得分:0)

  1. 避免直接从JFrame等顶级容器扩展(我不知道GBFrame是什么,但我猜它来自JFrame或其他一些窗口)
  2. 避免覆盖paint顶级容器,它们不会被双重缓冲,如果你打破了油漆链(你有),它就不会导致问题的结束。
  3. 避免KeyListener,它在焦点方面存在很多问题,很容易变得无法应对。相反,请考虑使用密钥绑定API。有关详细信息,请参阅How to Use Key Bindings
  4. 避免过度使用staticstatic不是一个跨对象的通信机制,当程序变得更复杂时,不会导致问题的结束。
  5. 相反,创建一个自JPanel之类的自定义组件,并覆盖它的paintComponent方法并在那里执行自定义绘画......

    public class BomberManPanel extends JPanel {
        //...
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Your painting goes here...
        }
    }
    

    有关详细信息,请参阅Painting in AWT and SwingPerforming Custom Painting

    我还将所有核心逻辑移至此组件,只需将其实例添加到BomberMan框架中。

    虽然您当前的方法通常会起作用,但通常情况下,您会遇到某种类型的游戏循环"它负责更新游戏的当前状态并安排游戏状态的渲染。

    这意味着您只需设置一个标志,指示当前按下哪些键并允许"游戏循环"而不是修改您的键监听器中的状态。按顺序更新国家

    在这种情况下,您可以使用a Swing Timer

    之类的内容