如何设置图像以给定的速度移动?

发布于 2024-12-09 14:15:06 字数 4573 浏览 0 评论 0原文

我有一个沿 x 轴移动的人的图像。现在我想以 5 米/秒的相应速度移动该人,增量时间以纳秒为单位,这就是我的问题。你能给我一些如何做的想法吗?

任何帮助将不胜感激......

这是代码:

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;

    }
 }
}

用于人类类

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

I have an image of a man that moves in x-axis. Now I want to move the man with its corresponding speed of 5 meter/s with delta time which is in nanoseconds and that is my problem. Could you give me some idea on how to do it?

Any help would be much appreciated...

Here's the code :

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

維他命╮ 2024-12-16 14:15:06

这是构建解决方案的想法。我假设您已经计算出图像每秒必须移动多少像素才能达到您想要的速度。假设对于您的游戏或模拟来说,这意味着每秒 10 个像素。您有一个起始位置和一个结束位置。这样您就知道何时需要移动图像。使用类 ScheduledThreadPoolExecutor 及其方法ScheduleWithFixedRate 设置图像位置的定期更新,发出调用以每秒在更新的位置绘制一次图像。请记住,由于 Swing 线程正在处理其他 GUI 请求,因此定位图像的调用可能会短暂延迟。但您预定的线程不受影响。假设预定的线程要求 Swing 将图像放置在位置 x 和时间 1.0 秒处。事实上,Swing 在 1.1 秒后才触及它。但你不希望这个增量搞砸了你的时机。事实并非如此,因为scheduleWithFixedRate 将在正确时间2.0 秒而不是2.1 秒发出下一个Swing 调用。第二次图像更新恰好在正确的时间发生在正确的位置(或者足够接近,具体取决于 GUI 线程的繁忙程度)。

Here's an idea for architecting your solution. I'm going to assume you have figured out how many pixels the image has to move every second to be the speed you want. Let's say that for your game or simulation, that means 10 pixels every second. You have a starting location and an ending location. So you know when you need to move the image. Use the class ScheduledThreadPoolExecutor and its method scheduleWithFixedRate to set up a periodic update of your image's position, issuing a call to draw the image once every second, at an updated location. Remember that your call to position your image could be delayed briefly as the Swing thread is servicing other GUI requests. But your scheduled thread is not affected. Say the scheduled thread says to Swing to put your image at position x and time 1.0 seconds. In fact, Swing gets to it a touch later at time 1.1 seconds. But you don't want that delta to screw up your timing. It doesn't because scheduleWithFixedRate will issue the next Swing call at the correct time 2.0 seconds, not at 2.1 seconds. The second image update is at exactly the right spot at the right time (or close enough depending on how busy the GUI thread is).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文