gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-11-01 02:06:43 25 4
gpt4 key购买 nike

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

           ________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);
}
}

hi riot games 请不要起诉我,反正我太年轻了

最佳答案

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

我知道我可以:

  • 计算两点之间的距离
  • 在给定的持续时间内将对象沿直线移动。

所以我们知道:

  • 起点
  • 终点

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

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

作为概念验证。抱歉,您没有提到您使用的是什么框架;)

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;

}
}
}

}

关于java - 以固定速度从起点移动一个方 block 到鼠标点击的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31041991/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com