【问题标题】:Shapes not moving on drawing panel java图形在绘图面板java上不动
【发布时间】:2014-01-21 12:23:41
【问题描述】:

我正在尝试用蝙蝠(桨)和球制作一个简单的 java 游戏。到目前为止,我已经在面板上绘制了 2 个对象,但是我无法让它们移动。我添加了球棒的关键事件和球的 move() 方法。以下是我的所有课程。

游戏类:

public class Game extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Game();
            }});
    }

    MyDrawingPanel myDrawingPanel = new MyDrawingPanel(this);
    MyUIPanel myUIPanel = new MyUIPanel(this);


    public Game()
    {
        setSize(1160,660); // you may change frame and panel sizes
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Container cp = getContentPane();    
        cp.setLayout(new FlowLayout());
        cp.add(myDrawingPanel);
        cp.add(myUIPanel);

        setVisible(true);
    }
}

MyDrawingPanel 类:

class MyDrawingPanel extends JPanel {

    Game game;

    Ball ball = new Ball(this);
    Bat bat = new Bat(this);

    public MyDrawingPanel(Game game)
    {
        this.game=game;
        setPreferredSize(new Dimension(800,600));
        setBackground(Color.RED);
        requestFocus();
    }

    public void paint(Graphics g)
    {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        ball.paint(g2d);

        Graphics2D gBat = (Graphics2D) g;
        bat.paint(gBat);
    }
}

球类:

public class Ball {

    int x = 0;
    int y = 0;
    int xa = 1;
    int ya = 1;
    private MyDrawingPanel myDrawingPanel;

    public Ball(MyDrawingPanel myDrawingPanel) {
        this.myDrawingPanel = myDrawingPanel;
    }

    public void move() {
        if (x + xa < 0)
            xa = 1;
        if (x + xa > myDrawingPanel.getWidth() - 30)
            xa = -1;
        if (y + ya < 0)
            ya = 1;
        if (y + ya > myDrawingPanel.getHeight() - 30)
            ya = -1;

        x = x + xa;
        y = y + ya;
    }

    public void paint(Graphics2D  g) {
        g.fillOval(x, y, 30, 30);
    }
}

蝙蝠类:

public class Bat{

    int x = 0;
    int xa = 0;
    private MyDrawingPanel myDrawingPanel;

    public Bat(MyDrawingPanel myDrawingPanel)
    {
        this.myDrawingPanel = myDrawingPanel;
    }

    public void move(){
        if(x + xa > 0 && x + xa <myDrawingPanel.getWidth()-60 )
            x = x + xa;
    }

    public void paint(Graphics2D g)
    {
        g.setColor(Color.BLUE);
        g.fillRoundRect(x, 500, 100, 20, 10, 10);
    }

    public void keyPressed(KeyEvent e)
    {
        if(e.getKeyCode() == KeyEvent.VK_LEFT)
            xa = -1;
        if(e.getKeyCode() == KeyEvent.VK_RIGHT)
            xa = 1;
    }

    public void keyReleased(KeyEvent e)
    {
        xa = 0;
    }
}

【问题讨论】:

  • 对于您的面板,您应该覆盖 paintComponent 并调用 super.paintComponent 而不是 paintsuper.paint
  • 如需尽快获得更好的帮助,请发帖MCVE
  • 另外,Bat 不是 似乎是一个组件类,但您正在尝试 paint 并在其中使用 keyevents
  • 大家好,感谢您的帮助,我是 java 新手,所以真的不知道该怎么做@peeskillet 我只是在绘图面板中更改方法名称和现有绘制方法的超级调用班级。这能解决我的问题吗?
  • 另外,MyUIPanel 到底是什么?我在任何地方都没有看到

标签: java swing paintcomponent


【解决方案1】:

没有KeyListener 实现,keyPressedkeyReleased 等方法不会执行任何操作。所以目前,你的方法是没用的。你应该做什么让DrawingPanel 类实现KeyListener,像这样

public class DrawingPanel extends JPanel implements KeyListener {
    ...
}

keyPressedkeyReleased 方法应该在该类中。您还需要 setter 方法,用于在 Bat 类中更新任何变量,例如 xxa,这些是决定 Bat 移动的变量。

所以在keyPressed 中,它应该在DrawingPanel 类中,它可能看起来像这样

public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
        bat.setXa(bat.getXa() - 1);
        repaint();
    }
    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
        bat.setXa(1);
        repaint();
    }
}

注意我如何称呼repaint()。这就是你移动某物后需要做的事情。

这应该会让你朝着正确的方向开始


编辑

忘记上面的大部分答案。

而不是使用KeyListener 虽然我会推荐使用键绑定。使用KeyListener 可能会遇到焦点问题。我为DrawingPanel 实现了键绑定,它工作正常。它会给你一些想法。

class MyDrawingPanel extends JPanel {

    Game game;

    Ball ball = new Ball(this);
    Bat bat = new Bat(this);

    public MyDrawingPanel(Game game) {
        this.game = game;
        setPreferredSize(new Dimension(800, 600));
        setBackground(Color.RED);
        requestFocus();

        Action rightAction = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                bat.x += 10;
                repaint();
            }
        };
        Action leftAction = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                bat.x -= 10;
                repaint();
            }
        };

        InputMap inputMap = getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = getActionMap();

        inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "rightAction");
        actionMap.put("rightAction", rightAction);
        inputMap.put(KeyStroke.getKeyStroke("LEFT"), "leftAction");
        actionMap.put("leftAction", leftAction);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        ball.paint(g2d);

        Graphics2D gBat = (Graphics2D) g;
        bat.paint(gBat);
    }
}

How to use key bindings

【讨论】:

  • 那么我应该把 kyepressed 带出蝙蝠班还是有必要?我需要添加 setter 和 getter 方法还是只在 bat 类中添加 setter?
  • 是的,你不需要它
  • 好的,我还需要从 bat 类中删除现有的 keyReleased 吗?对于我在 bat 类中的 setter 方法,我是否必须向它传递任何参数?
  • 看看我的EDIT。将您的 DrawingPanel 类替换为上面的类。你会看到它的工作。
  • 您好,已经成功了。可以通过释放键并按下键的方式完成吗?
猜你喜欢
  • 2012-11-27
  • 2019-07-15
  • 2015-10-27
  • 2014-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
  • 1970-01-01
相关资源
最近更新 更多