我有 Jbutton(由信封表示)和一个 ArrayList 行,信封将沿着这些行。谁能帮我?任何想法或教程将不胜感激。
3 回答
我假设您的目标是沿线为信封设置动画,以提供正在传输的数据的动画。
对于每条线,您首先需要找到线方程。线方程的形式为y = a * x + b
。如果您在提到的内容中已经有了它,List
那很好。另一方面,如果您有两个点(开始位置和结束位置),请使用带有上述等式的点来查找每条线的a
, b
。
获得线条方程后,您可以使用动画(可能使用 aSwingWorker
或 a )定期SwingTimer
增加信封的坐标,然后使用线条方程计算新坐标。x
y
我希望这会有所帮助
更新:SwingTimer
添加了用于演示的移动框的代码片段
package keymovement;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
public class TestMovingObject {
static class Envelope {
double x;
double y;
void setPosition(double x, double y) {
this.x = x;
this.y = y;
}
}
static class DrawArea extends JPanel {
Envelope envelope = new Envelope();
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
int x = (int) Math.round(envelope.x);
int y = (int) Math.round(envelope.y);
g.drawRect(x, y, 20, 20);
}
public Envelope getEnvelope() {
return envelope;
}
}
/**
* @param args
*/
public static void main(String[] args) {
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
throw new RuntimeException(e);
}
JFrame window = new JFrame("Moving box");
window.setPreferredSize(new Dimension(500, 400));
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final DrawArea mainArea = new DrawArea();
window.add(mainArea);
window.pack();
window.setLocationRelativeTo(null);
window.setVisible(true);
int delay = 20; // execute every 20 milliseconds i.e. 50 times per second
Timer timer = new Timer(delay, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Envelope envelope = mainArea.getEnvelope();
double x = envelope.x + 1; // use smaller increments depending on the desired speed
double y = 0.5 * x + 2; // moving along the line y = 0.5 * x + 2
envelope.setPosition(x, y);
mainArea.repaint();
}
});
timer.setRepeats(true);
timer.start();
}
});
}
}
你能告诉我一个非常简单的例子吗?
在这个游戏中,敌人每次向玩家前进一行或一列,不计算任何中间点。当目的地静止时,路径是一条直线。动画以javax.swing.Timer
. 参见RCModel#move()
和RCView#timer
实现。
有一些数学事情要为你做。查看这篇文章:http ://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
这个简单的算法将告诉您两点之间的一条线上的每个 X、Y 坐标。您可以使用此算法计算它需要访问的所有位置,将坐标存储在数组中,并在更新位置时迭代数组。
有一个替代的助手类:
package snippet;
import java.awt.geom.Point2D;
public class MyVelocityCalculator {
public static void main(String[] args) {
Point2D.Double currentPosition = new Point2D.Double();
Point2D.Double destinationPosition = new Point2D.Double();
currentPosition.setLocation(100, 100);
destinationPosition.setLocation(50, 50);
Double speed = 0.5;
System.out.println("player was initially at: " + currentPosition);
while (currentPosition.getX() > destinationPosition.getX()
&& currentPosition.getY() > destinationPosition.getY()) {
Point2D.Double nextPosition = MyVelocityCalculator.getVelocity(currentPosition, destinationPosition, speed);
System.out.println("half seconds later player should be at: " + nextPosition);
currentPosition = nextPosition;
}
System.out.println("player destination is at: " + destinationPosition);
}
public static final Point2D.Double getVelocity(Point2D.Double currentPosition, Point2D.Double destinationPosition,
double speed) {
Point2D.Double nextPosition = new Point2D.Double();
double angle = calcAngleBetweenPoints(currentPosition, destinationPosition);
double distance = speed;
Point2D.Double velocityPoint = getVelocity(angle, distance);
nextPosition.x = currentPosition.x + velocityPoint.x;
nextPosition.y = currentPosition.y + velocityPoint.y;
return nextPosition;
}
public static final double calcAngleBetweenPoints(Point2D.Double p1, Point2D.Double p2) {
return Math.toDegrees(Math.atan2(p2.getY() - p1.getY(), p2.getX() - p1.getX()));
}
public static final Point2D.Double getVelocity(double angle, double speed) {
double x = Math.cos(Math.toRadians(angle)) * speed;
double y = Math.sin(Math.toRadians(angle)) * speed;
return (new Point2D.Double(x, y));
}
}
而不是打印出控制台上的位置,您需要在该位置绘制控件到您的图形元素。