简体   繁体   中英

How can I set the image to move at the given speed?

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

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM