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

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

           ________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

速度是一个常数(在我的例子中为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));

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

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;

            }
        }
    }

}
https://stackoverflow.com/questions/31041991/moving-a-square-from-a-starting-point-to-the-position-of-a-mouse-click-at-a-fixe

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:java – 将一个方块从起点移动到以固定速度点击鼠标的位置