Java 如何设置图像以给定速度移动?
我有一个在x轴上移动的男人的图像。现在,我想以5米/秒的速度移动这个人,时间增量为纳秒,这就是我的问题。你能告诉我怎么做吗 任何帮助都将不胜感激 代码如下:Java 如何设置图像以给定速度移动?,java,swing,awt,Java,Swing,Awt,我有一个在x轴上移动的男人的图像。现在,我想以5米/秒的速度移动这个人,时间增量为纳秒,这就是我的问题。你能告诉我怎么做吗 任何帮助都将不胜感激 代码如下: public class Board extends Canvas { public double meter;//PIXEL private final java.util.List<Sprite> sprites = new ArrayList<Sprite>(); private final java.
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;
}
}
}
公共类板扩展画布
{
公共双表;//像素
private final java.util.List sprites=new ArrayList();
private final java.util.List z_sorted_sprites=new ArrayList();
私人缓冲战略;
int x0_像素;
int-y0_像素;
int-x1_像素;
int y1_像素;
双x1_世界;
双y1_世界;
公用板(双表)
{
此.setIgnoreRepaint(true);
这个。米=米;
init();
addComponentListener(新的ComponentAdapter()
{
@凌驾
公共无效组件已恢复(组件事件e)
{
render();
}
});
}
公共void init()
{
人类=新人类(这个,2,2,0);
精灵。添加(人类);
精灵。添加(人类);
}
@凌驾
公共空间涂料(图g)
{
}
公共无效呈现()
{
设置策略();
x0_像素=0;
y0_像素=0;
x1_像素=getWidth();
y1_像素=获取高度();
x1_世界=x1_像素/米;
y1_世界=y1_像素/米;
Graphics2D g2d=(Graphics2D)strategy.getDrawGraphics();
g2d.挫折背景(颜色:浅灰色);
g2d.clearRect(0,0,x1_像素,y1_像素);
g2d.setColor(Color.BLACK);
对于(双x=0;x
人类阶级
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;
}
}
公共类HumanBeing扩展了Sprite实现的ImageObserver
{
私有java.awt.Image humanImage;
私人终审委员会;
私人双x;
私人双y;
私人整数速度;
private java.util.List objects=new ArrayList();
私人互联网;
公众人物(棋盘,整数x,整数y,整数速度)
{
this.board=董事会;
这个.x=x;
这个。y=y;
速度=速度;
URL iU=this.getClass().getResource(“human.jpg”);
ImageIcon图标=新的ImageIcon(iU);
humanImage=icon.getImage();
对象。添加(此);
}
公共映像getImage()
{
返回humanImage;
}
@凌驾
公共无效移动(长ns)
{
x+=0.001;
}
@凌驾
公共无效渲染(Graphics2D g2d)
{
仿射变换t=g2d.getTransform();
最终双人高度=1.6;//米
最终双宽度=1.8;//米
最终双脚位置=人高/2;
最终双足位置=人宽;
int xx=board.convertToPixelX(x-foot_position_x);//查找左上角
int yy=board.convertToPixelY(y+foot_position_y);//查找左上角
翻译(xx,yy);
//实际图像大小的比率
双x_预期_像素=人高*板米;
双y_预期_像素=humanWidth*board.meter;
双w=((ToolkitImage)humanImage.getWidth();
双h=((ToolkitImage)humanImage.getHeight();
双x_s=x_预期像素/w;
双y_s=y_预期像素/h;
g2d.比例(x_s,y_s);
g2d.drawImage(getImage(),0,0,this);//左上角
g2d.setColor(Color.BLACK);
g2d.setTransform(t);
}
@凌驾
公共空间移动(双倍距离x,双倍距离y)
{
这.x=距离x;
这.y=距离_y;
}
@凌驾
公共布尔图像更新(图像img、int-infoflags、int-x、int-y、int-width、int-height)
{
返回false;
}
}
这里有一个设计解决方案的想法。我假设你已经计算出图像每秒要移动多少像素才能达到你想要的速度。比方说,对于游戏或模拟,这意味着每秒10个像素。您有一个起始位置和一个结束位置。因此,您知道何时需要移动图像。使用类及其方法scheduleWithFixedRate设置图像位置的定期更新,并发出调用以在更新的位置每秒绘制一次图像。请记住,由于Swing线程正在为其他GUI请求提供服务,因此定位图像的调用可能会短暂延迟。但您的计划线程不受影响。假设计划的线程说Swing将图像放置在位置x,时间为1.0秒。事实上,Swing会在1.1秒后触摸到它。但你不想让三角洲搞砸你的时间。这不是因为scheduleWithFixedRate将在正确的时间2.0秒发出下一个Swing调用,而不是在2.1秒发出。第二次图像更新在正确的时间恰好在正确的位置(或者足够近,取决于GUI线程的繁忙程度)。5 km/h屏幕?5公里~10000个屏幕/20000个窗口,1小时=3600秒,你会让你的人在大约三分之一秒的时间内移动屏幕。如果是人为的速度,