java - 根据鼠标位置添加力
问题描述
我想要一个点向鼠标位置移动。目前该点只是鼠标位置。但我想要它,以便鼠标和屏幕中心之间的距离越大,加到点上的力就越小。因此,如果鼠标距离中心足够远,该点将停止进一步向外移动,因为它远离中心的力很小。中心应该始终是被观察的点。所以没有重新定位。
我真的被困在这里,因为我还很年轻,而且我在学校没有进行矢量计算(我认为这就是你需要的)。我不知道如何做我想要存档的东西。我唯一尝试的是使用中心和鼠标之间的距离(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);
}
}
它看起来像这样:
解决方案
您可以声明一个吸引力比值,该值将根据其值将圆拉伸到屏幕中心。您还需要能够知道每个光标位置与中心的距离(以百分比表示)。
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);
}
}
推荐阅读
- html - 无法从我的烧瓶 CRUD 应用程序中从 mysql 表中检索数据,即使它被插入而没有任何错误
- python - Concurrent.futures 问题
- php - 无法在 php8 上运行 laravel 5.7
- angular - 如何在角度 5 中修剪 primeNg Dropdown(p-dropdown)过滤器中的空间?
- python - Python Pandas 运行总列
- python - 在 Python 中使用网格方法时出错
- c# - 使用流利的 api 在 ApplicationDbContext 中创建复合键
- heroku - 无法登录 Heroku
- python - 如何在 Pandas 中检查哪些客户同时持有这两种产品
- sql - 如何报告与不同来源的 ID 匹配的测试结果?