2011-10-12 42 views
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; 
} 
} 
+0

屏幕上5公里/小時? 5公里〜10000屏幕/ 20000個窗口,1小時= 3600秒,你會讓你的傢伙在大約三分之一秒的時間內行走屏幕。如果是人造速度,試試看看什麼感覺/看起來不錯。 –

+0

爲了更快地獲得更好的幫助,請發佈[SSCCE](http://pscode.org/sscce.html)。 –

+0

@Captain長頸鹿不在屏幕上,但對世界。它現在好了,我已經解決了它; ;-) – sack

回答

1

下面是架構解決方案的想法。我會假設你已經計算出圖像每秒移動多少像素才能達到你想要的速度。假設對於您的遊戲或模擬,這意味着每秒鐘10個像素。你有一個起始位置和一個結束位置。所以你知道什麼時候需要移動圖像。使用類ScheduledThreadPoolExecutor及其方法scheduleWithFixedRate設置圖像位置的定期更新,並在更新的位置發出一個調用,以便每秒鐘繪製一次圖像。請記住,由於Swing線程正在處理其他GUI請求,所以您調用放置圖像的位置可能會暫時延遲。但是你的預定線程不受影響。說預定的線程說Swing把你的圖像放在位置x和時間1.0秒。事實上,Swing在1.1秒之後纔會觸及它。但你不希望這個三角洲搞砸你的時間。這並不是因爲scheduleWithFixedRate將在正確的時間2.0秒發出下一個Swing呼叫,而不是2.1秒。第二個映像更新在正確的時間正好在正確的位置(或者根據GUI線程的忙碌程度,足夠靠近)。

+0

tnx這個想法.. ;-) – sack

相關問題