我有一个在x轴上移动的人的图像。现在我想以5米/秒的相应速度移动该人,其中delta时间以纳秒为单位,这是我的问题。你能告诉我怎么做的吗?
非常感谢任何帮助......
以下是代码:
public class Board extends Canvas
{
public double meter;//PIXEL
private final java.util.List<Sprite> sprites = new ArrayList<Sprite>();
private final java.util.List<Sprite> z_sorted_sprites = new ArrayList<Sprite>();
private BufferStrategy strategy;
int x0_pixel;
int y0_pixel;
int x1_pixel;
int y1_pixel;
double x1_world;
double y1_world;
public Board(double meter)
{
this.setIgnoreRepaint(true);
this.meter = meter;
init();
addComponentListener(new ComponentAdapter()
{
@Override
public void componentResized(ComponentEvent e)
{
render();
}
});
}
public void init()
{
HumanBeing humanBeing = new HumanBeing(this, 2, 2, 0);
sprites.add(humanBeing);
z_sorted_sprites.add(humanBeing);
}
@Override
public void paint(Graphics g)
{
}
public void render()
{
setupStrategy();
x0_pixel = 0;
y0_pixel = 0;
x1_pixel = getWidth();
y1_pixel = getHeight();
x1_world = x1_pixel / meter;
y1_world = y1_pixel / meter;
Graphics2D g2d = (Graphics2D) strategy.getDrawGraphics();
g2d.setBackground(Color.lightGray);
g2d.clearRect(0, 0, x1_pixel, y1_pixel);
g2d.setColor(Color.BLACK);
for (double x = 0; x < x1_world; x++)
{
for (double y = 0; y < y1_world; y++)
{
int xx = convertToPixelX(x);
int yy = convertToPixelY(y);
g2d.drawOval(xx, yy, 2, 2);
}
}
for (Sprite z_sorted_sprite : z_sorted_sprites)
{
z_sorted_sprite.render(g2d);
}
g2d.dispose();
strategy.show();
Toolkit.getDefaultToolkit().sync();
}
public int convertToPixelX(double distance)
{
return (int) (distance * meter);
}
public int convertToPixelY(double y_world)
{
return (int) (y1_pixel - (y_world * meter));
}
public void onZoomUpdated(int value)
{
meter = value;
render();
}
private void setupStrategy()
{
if (strategy == null)
{
this.createBufferStrategy(2);
strategy = this.getBufferStrategy();
}
}
public void start() throws InterruptedException
{
long previousTime = System.nanoTime();
while (true)
{
long now = System.nanoTime();
long dt = now - previousTime;
for (Sprite sprite : sprites)
{
sprite.move(0);
}
render();
Thread.sleep(1);
previousTime = now;
}
}
}
for Human Class
public class HumanBeing extends Sprite implements ImageObserver
{
private java.awt.Image humanImage;
private final Board board;
private double x;
private double y;
private int speed;
private java.util.List<Sprite> objects = new ArrayList<Sprite>();
private int cImage;
public HumanBeing(Board board, int x, int y, int speed)
{
this.board = board;
this.x = x;
this.y = y;
this.speed = speed;
URL iU = this.getClass().getResource("human.jpg");
ImageIcon icon = new ImageIcon(iU);
humanImage = icon.getImage();
objects.add(this);
}
public Image getImage()
{
return humanImage;
}
@Override
public void move(long ns)
{
x += 0.001;
}
@Override
public void render(Graphics2D g2d)
{
AffineTransform t = g2d.getTransform();
final double humanHeight = 1.6;// meter
final double humanWidth = 1.8; //meter
final double foot_position_x = humanHeight / 2;
final double foot_position_y = humanWidth;
int xx = board.convertToPixelX(x - foot_position_x); // to find the upper-left corner
int yy = board.convertToPixelY(y + foot_position_y); // to find the upper-left corner
g2d.translate(xx, yy);
// ratio for actual Image size
double x_expected_pixels = humanHeight * board.meter;
double y_expected_pixels = humanWidth * board.meter;
double w = ((ToolkitImage) humanImage).getWidth();
double h = ((ToolkitImage) humanImage).getHeight();
double x_s = x_expected_pixels / w;
double y_s = y_expected_pixels / h;
g2d.scale(x_s, y_s);
g2d.drawImage(getImage(), 0, 0, this); // upper left corner
g2d.setColor(Color.BLACK);
g2d.setTransform(t);
}
@Override
public void moveAt(double distance_x, double distance_y)
{
this.x = distance_x;
this.y = distance_y;
}
@Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
return false;
}
}
答案 0 :(得分:1)
这是构建解决方案的想法。我假设你已经知道图像每秒移动多少像素就是你想要的速度。让我们说,对于您的游戏或模拟,这意味着每秒10像素。您有一个起始位置和一个结束位置。所以你知道什么时候需要移动图像。使用类ScheduledThreadPoolExecutor及其方法scheduleWithFixedRate设置图像位置的定期更新,每秒在更新的位置发出一次调用图像。请记住,当Swing线程为其他GUI请求提供服务时,您对图像的定位调用可能会被短暂延迟。但是您的预定线程不受影响。假设计划的线程告诉Swing将您的图像放在位置x和时间1.0秒。实际上,Swing稍后会在1.1秒时触及它。但你不希望这个三角洲搞砸你的时间。这不是因为scheduleWithFixedRate将在2.0秒的正确时间发出下一个Swing调用,而不是2.1秒。第二次图像更新恰好位于正确的时间点(或者足够接近,具体取决于GUI线程的繁忙程度)。