Как я могу настроить изображение для перемещения с заданной скоростью? - PullRequest
0 голосов
/ 12 октября 2011

У меня есть изображение человека, который движется по оси 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;
}
}

1 Ответ

1 голос
/ 12 октября 2011

Вот идея для разработки вашего решения.Я предполагаю, что вы выяснили, на сколько пикселей изображение должно перемещаться каждую секунду, чтобы достичь желаемой скорости.Допустим, для вашей игры или симуляции это означает 10 пикселей каждую секунду.У вас есть начальная локация и конечная локация.Таким образом, вы знаете, когда вам нужно переместить изображение.Используйте класс ScheduledThreadPoolExecutor и его метод scheduleWithFixedRate, чтобы настроить периодическое обновление позиции вашего изображения, отправляя вызов для рисования изображения один раз в секунду в обновленном местоположении.Помните, что ваш вызов для позиционирования вашего изображения может быть ненадолго задержан, поскольку поток Swing обслуживает другие запросы графического интерфейса.Но ваш запланированный поток не затронут.Скажите, что запланированная тема говорит Swing, чтобы поместить ваше изображение в положение x и время 1,0 секунды.На самом деле, Swing получает к нему прикосновение позже, на время 1,1 секунды.Но вы не хотите, чтобы эта дельта испортила вам время.Это не потому, что scheduleWithFixedRate отправит следующий вызов Swing в правильное время 2,0 секунды, а не в 2,1 секунды.Второе обновление изображения находится в нужном месте в нужное время (или достаточно близко, в зависимости от того, насколько занят поток графического интерфейса).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...