按下键时改变球的方向

时间:2014-04-12 09:28:03

标签: java swing paintcomponent keylistener frames

我一直试图让球在任何按键被按下时改变方向。如果球在向侧面移动时按下按键,球将开始向下移动,当它接触到底部时,它会向上移回......我想我已经写了正确的代码,我发现它没有任何错误。 有人可以告诉我这段代码有什么问题吗?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ASS2 extends JFrame {

    public static void main(String args[]) {
        ASS2 g = new ASS2();
        g.setLayout(new BorderLayout());
        g.setSize(500, 500);
        MyPanel mp = new MyPanel();
        g.add(mp);
        mp.setSize(500, 500);
        mp.setBackground(Color.black);
//mp.addKeyListener(mp);
        g.setVisible(true);
        g.setDefaultCloseOperation(EXIT_ON_CLOSE);

    }
}

class MyPanel extends JPanel implements KeyListener {

    {
        addKeyListener(this);
    }
    int xpos = 20, ypos = 200;
    int xtop = 15, ytop = 15;
    int xtemp = 250, ytemp = 250;
    int xbot = 450, ybot = 400;
    int flag = 1, flag1 = 1;

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.white);
        g2d.fill(new Ellipse2D.Double(xpos, ypos, 50, 50));
        if (xpos < xbot && flag == 1) {
            xpos++;
            if (xpos == xbot) {
                flag = 0;
            }
        } else if (xpos > xtop && flag == 0) {
            xpos--;
            if (xpos == xtop) {
                flag = 1;
            }
        }

        try {
            Thread.sleep(05);
        } catch (Exception e) {
        }
        repaint(1000);

    }

    public void keyPressed(KeyEvent ae) {

    }

    public void keyReleased(KeyEvent ae) {
        Object t = ae.getKeyCode();
        if (t.equals(KeyEvent.VK_DOWN)) {
            if (ypos < ybot && flag1 == 1) {
                ypos++;
                if (ypos == ybot) {
                    flag1 = 0;
                }
            } else if (ypos > ytop && flag1 == 0) {
                ypos--;
                if (ypos == ytop) {
                    flag1 = 1;
                }
            }
            repaint();
        } else if (t.equals(KeyEvent.VK_RIGHT)) {
            if (xpos < xbot && flag == 1) {
                xpos++;
                if (xpos == xbot) {
                    flag = 0;
                }
            } else if (xpos > xtop && flag == 0) {
                xpos--;
                if (xpos == xtop) {
                    flag = 0;
                }
            }
            repaint();
        }

    }
}

1 个答案:

答案 0 :(得分:1)

欢迎来到“为什么你不应该使用KeyListener s”的精彩世界。

基本上,KeyListener只会在连接侦听器的组件可聚焦且具有焦点时引发事件。

相反,你应该使用Key Bindings来控制它们触发关键事件的焦点水平。

  • 不要在EDT中调用的任何方法中使用Thread.sleep,尤其是paint方法。
  • 不要在任何绘制方法中调用repaint(1000);或调用任何可能在repaint方法中触发paint的方法
  • 不要在paint方法中修改状态,paint方法绘制,这就是全部。
  • 使用某种“更新”线程/进程,负责更新游戏模型并请求更新视图。 java.swing.Timer是一个很好的简单选择。请参阅How to use Swing Timers
  • 当Swing Timer变得限制您尝试执行的操作并开始探索Thread的使用时,请不要修改EDT之外的任何UI组件。有关详细信息,请参阅Concurrency in Swing
  • 始终在EDT的上下文中启动您的程序,有关详细信息,请参阅Initial Threads ...