无法在主

时间:2016-12-13 17:00:06

标签: java swing mouseevent

我正在尝试做什么

制作Pong游戏,Y轴根据应用程序从光标中获取值

我尝试了什么

private void pallet() {
    ycur=(int)MouseInfo.getPointerInfo().getLocation().getY();
}

这样我根据我的显示器而不是应用程序获得Y值。

我也尝试使用MouseEvent.getY(),但是在尝试从main调用此方法时出现错误。

private void pallet() {
    ycur=(int)MouseInfo.getPointerInfo().getLocation().getY();
}

这就是我的代码的样子,我认为问题在于我如何使用main和方法,但我不确定。

public class MyFirst extends JPanel {

    public int x = 500, y = 300, border = 30;
    public boolean goingDown = true;
    public int ycur, cursor;


    public void moveBall() {
        x++;
        if (goingDown == true) {
            y++;
        } else if (goingDown == false) {
            y--;
        }

        if (y == getHeight() - border) {
            goingDown = false;
        } else if (y == 0) {
            goingDown = true;
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillOval(x, y, 30, 30);
        g.fillRect(30, ycur, 15, 100);
    }

    public static void main(String[] args) throws InterruptedException     {
        JFrame frame = new JFrame("Pong");
        frame.pack();
        frame.setSize(1000, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);

        MyFirst game = new MyFirst();
        frame.add(game);
        while (true) {
            game.pallet(e);
            game.moveBall();
            game.repaint();
            Thread.sleep(10);
        }
    }

    public void pallet(MouseEvent e) {
        ycur=e.getY();
    }

}

1 个答案:

答案 0 :(得分:2)

代码问题:

  • 如前所述,您正在与Swing的事件驱动架构作斗争。而不是一个真正的循环,使用侦听器,包括MouseMotionListener或跟踪鼠标位置的变化,以及绑定到Swing Timer的ActionListener来移动球。
  • 避免在Swing GUI中使用Thread.sleep(...),除非非常小心,因为这会让整个应用程序进入休眠状态。
  • 避免在主方法中加入太多逻辑。这个方法应该简短,应该创建关键对象,连接它们,设置程序运动,就是这样。
  • 使用paintComponent方法绘制,而不是绘制方法。通过双缓冲可以使动画更加流畅。

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class MoveBallTest extends JPanel{
    private static final int PREF_W = 1000;
    private static final int PREF_H = 600;
    private static final int TIMER_DELAY = 12;
    private static final int SPRITE_WIDTH = 30;
    private static final Color OVAL_SPRITE_COLOR = Color.RED;
    private static final Color RECT_SPRITE_COLOR = Color.BLUE;
    private static final int DELTAY_Y = 1;
    private boolean goingDown = true;
    private Timer timer = new Timer(TIMER_DELAY, this::timerActionPerformed);
    private int ovalSpriteY;
    private int rectSpriteY;

    public MoveBallTest() {
        timer.start();
        MyMouse myMouse = new MyMouse();
        addMouseMotionListener(myMouse);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(OVAL_SPRITE_COLOR);
        g.fillOval(SPRITE_WIDTH, ovalSpriteY, SPRITE_WIDTH, SPRITE_WIDTH);
        g.setColor(RECT_SPRITE_COLOR);
        g.fillRect(SPRITE_WIDTH, rectSpriteY, SPRITE_WIDTH / 2, SPRITE_WIDTH * 3);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    public void timerActionPerformed(ActionEvent e) {
        if (ovalSpriteY <= 0) {
            goingDown = true;
        } else if (ovalSpriteY >= getHeight() - SPRITE_WIDTH) {
            goingDown = false;
        }

        ovalSpriteY += goingDown ? DELTAY_Y : -DELTAY_Y;
        repaint();
    }

    private class MyMouse extends MouseAdapter {
        @Override
        public void mouseMoved(MouseEvent e) {
            rectSpriteY = e.getY();
        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("MoveBallTest");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new MoveBallTest());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}