将一个正方形从起点移动到以固定速度点击鼠标的位置

当我点击时,我正试图将一个正方形从它的原始位置移动到我的鼠标坐标。 我有点工作的代码,但广场不直接鼠标点击。 它对角线有点偏离,然后进入鼠标点击,如图所示。 我试图让它成为一条直线运动路径,但我想不出办法。 我很确定错误与下面的第一种方法有关。

________X ← the mouse click / / ↑ / ← = movement path / / _____/ | | ← character |___| 

以下是目前涉及的3种方法(请不要批评我的代码太多)

  //int x and int y are the positions of the mouse, champion = the character public static Champion calculateChampionMovement(int x, int y, Champion champion) { if (x != champion.x || y != champion.y) { //x and y dist = the distance between the character and the cursor int xDist = x - champion.x; int yDist = y - champion.y; //the angle plrAngle = Math.atan2(yDist, xDist) * 180 / Math.PI; //the speed of the character on the x and y axis //(character diagonally moves at the speed of "champion.speed") plrXSpeed = champion.speed * Math.cos(plrAngle * Math.PI / 180); plrYSpeed = champion.speed * Math.sin(plrAngle * Math.PI / 180); //calls the method below that actually moves the character playerMain.champion = (Champion) Entity.moveChampions(x, y, champion, champion.speed, plrXSpeed, plrYSpeed); champion.moving = true; } return playerMain.champion; } 

第二个……

  //called by the method above public static Entity moveChampions(int x, int y, Champion champion, float speed, double xSpeed, double ySpeed) { //if the distance between the character on the x and y axis is not //exactly divisible by "speed", then this helps the character stop. if (Math.abs(x - champion.x) <= speed) { champion.x = x; } if (Math.abs(y - champion.y) <= speed) { champion.y = y; } //stops the character if (x == champion.x && y == champion.y) { champion.moving = false; } //moves the character if (champion.moving) { champion.x += xSpeed; champion.y += ySpeed; } return champion; } 

最后一个方法调用“calculateChampionMovement”和“moveChampions”,并在“moving”为真时移动角色

 public static void buttonTest() { if (RIGHTCLICK == true) { //mouse x and y positions cursorClickX = (int) (mapX + MOUSE_X); cursorClickY = (int) (mapY + MOUSE_Y); //first method (setup the x and y speed) playerMain.champion = PlayerMain.testMainChampionMove(cursorClickX, cursorClickY, playerMain.champion); // if character is already moving } else if (playerMain.champion.moving == true) { //move the character playerMain.champion = (Champion) Entity.moveChampions(cursorClickX, cursorClickY, playerMain.champion, champAsdf.speed, plrXSpeed, plrYSpeed); } } 

嗨暴乱游戏请不要告诉我,我太年轻了

遇到问题时,我倾向于回归基础知识,我该怎么做?

我知道我可以:

  • 计算两点之间的距离
  • 在给定的持续时间内将对象移动一长行。

所以我们知道:

  • 起点
  • 终点

由此我们可以计算出两点之间的距离。

 double distance = Math.sqrt( (startX - targetX) * (startX - targetX) + (startY - targetY) * (startY - targetY)); 

有了这个,我们可以根据所需的速度计算在两点之间行进所需的时间

 time = distance / speed 

speed是一个常数(在我的例子中0.1 ,使其变小以使其变慢)

有了这些信息,我们知道我们必须走多长时间,我们可以根据开始时(点击鼠标时)和现在之间的差异来计算沿线/路径的进度。

假设startTime是我们开始移动的时间, runningTime是我们需要运行的时间以保持恒定的速度

然后,我们可以使用类似……

 long duration = System.currentTimeMillis() - startTime; double progress = duration / runTime; 

由此我们可以根据当前持续时间计算沿线的位置……

 double x = (int) (startX + ((targetX - startX) * progress)); double y = (int) (startY + ((targetY - startY) * progress)); 

MoveAlongLine

作为概念的certificate。 对不起,您没有提到您正在使用的框架;)

 import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class TestMove { public static void main(String[] args) { new TestMove(); } public TestMove() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private Rectangle champion; private Line2D path; private double speed = 0.1; private Timer timer; private Long startTime; private double targetX, targetY; private double startX, startY; private double runTime; public TestPane() { champion = new Rectangle(95, 95, 10, 10); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { timer.stop(); calculateChampionMovement(e.getX(), e.getY(), champion); startTime = System.currentTimeMillis(); timer.start(); } }); timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (targetX == champion.getCenterX() && targetY == champion.getCenterY()) { System.out.println("Stopped as same"); timer.stop(); } long duration = System.currentTimeMillis() - startTime; double progress = duration / runTime; if (progress >= 1.0) { System.out.println("Stopped out of time"); progress = 1.0; timer.stop(); } double x = (int) (startX + ((targetX - startX) * progress)); double y = (int) (startY + ((targetY - startY) * progress)); // x/y are the center points, need to adjust them so the shape // moves about the center point champion.setRect(x - 5, y - 5, 10, 10); repaint(); } }); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.draw(champion); if (path != null) { g2d.setColor(Color.RED); g2d.draw(path); } g2d.dispose(); } public void calculateChampionMovement(double x, double y, Rectangle champion) { if (x != champion.getCenterX() || y != champion.getCenterY()) { targetX = x; targetY = y; startX = champion.getCenterX(); startY = champion.getCenterY(); path = new Line2D.Double( champion.getCenterX(), champion.getCenterY(), x, y); double distance = Math.sqrt( (startX - targetX) * (startX - targetX) + (startY - targetY) * (startY - targetY)); runTime = distance / (double)speed; } } } }