首页 > 解决方案 > 根据鼠标位置添加力

问题描述

我想要一个点向鼠标位置移动。目前该点只是鼠标位置。但我想要它,以便鼠标和屏幕中心之间的距离越大,加到点上的力就越小。因此,如果鼠标距离中心足够远,该点将停止进一步向外移动,因为它远离中心的力很小。中心应该始终是被观察的点。所以没有重新定位。

我真的被困在这里,因为我还很年轻,而且我在学校没有进行矢量计算(我认为这就是你需要的)。我不知道如何做我想要存档的东西。我唯一尝试的是使用中心和鼠标之间的距离(Math.hypot(width / 2 - mouseX , height / 2 - mouseY))。但它没有用。

这是我最小的可重现示例

import javax.swing.*;
import java.awt.*;

public class Example extends JPanel {
    private static final int size = 500;

public Example() {
    this.setPreferredSize(new Dimension(size, size));
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.fillOval(getWidth() / 2 - 3, getHeight() / 2 - 3, 6, 6); // center
    Point point = MouseInfo.getPointerInfo().getLocation();
    SwingUtilities.convertPointFromScreen(point, this);
    // Do calculations with the point here
    g2d.fillOval(point.x - 5, point.y - 5, 10, 10);
    repaint();
}

private static void createFrame() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(new Example());
    f.pack();
    f.setVisible(true);
}

    public static void main(String[] args) {
        EventQueue.invokeLater(Example::createFrame);
    }
}

它看起来像这样:

涂鸦.png

标签: javamath

解决方案


您可以声明一个吸引力比值,该值将根据其值将圆拉伸到屏幕中心。您还需要能够知道每个光标位置与中心的距离(以百分比表示)。

import javax.swing.*;
import java.awt.*;

public class Example extends JPanel {
    private static final int SIZE = 500;
    private static final int CENTER_CIRCLE_RADIUS = 3;
    private static final int CIRCLE_RADIUS = 5;
    private static final double ATTRACTION_RATIO = 0.75;

    public Example() {
        this.setPreferredSize(new Dimension(SIZE, SIZE));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        final int xCenterPoint = getWidth() / 2;
        final int yCenterPoint = getHeight() / 2;

        g2d.fillOval(xCenterPoint - CENTER_CIRCLE_RADIUS, yCenterPoint - CENTER_CIRCLE_RADIUS,
                CENTER_CIRCLE_RADIUS * 2, CENTER_CIRCLE_RADIUS * 2); // center
        Point point = MouseInfo.getPointerInfo().getLocation();
        SwingUtilities.convertPointFromScreen(point, this);

        final double xNearToCenter = 1 - ((double) (xCenterPoint - point.x) / xCenterPoint);
        final double yNearToCenter = 1 - ((double) (yCenterPoint - point.y) / yCenterPoint);

        g2d.fillOval((int) (xCenterPoint * (ATTRACTION_RATIO + xNearToCenter * (1 - ATTRACTION_RATIO))),
                (int) (yCenterPoint * (ATTRACTION_RATIO + yNearToCenter * (1 - ATTRACTION_RATIO))),
                CIRCLE_RADIUS * 2, CIRCLE_RADIUS * 2);

        repaint();
    }

    private static void createFrame() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Example panel = new Example();
        f.add(panel);
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(Example::createFrame);
    }
}

推荐阅读