2014-01-28 29 views
0

我正在研究一個採用船舶物體並將其移動的程序。我遇到的麻煩是,如果它經過一邊,那麼它應該繞回另一邊。如何讓對象環繞屏幕?

任何幫助將是巨大的:)

這裏是我的船級:此舉的方法是什麼,我需要幫助。該代碼我已經不工作:/

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.geom.AffineTransform; 
import java.awt.image.AffineTransformOp; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 

import junit.framework.TestCase; 

public class Ship { 

private BufferedImage _image; 
private static final int WIDTH = 50; 

private Point location; 
private Vector speed = new Vector(); 
private double facing; 

/** 
* Generate ship at the given starting location and currently stopped 
* 
* @param starting 
*   location to copy for this ship 
*/ 
public Ship(Point starting) { 
    try { 
     // Use the RunConfigurations >> Arguments > Working Directory tab so 
     // that this works. Don't just place the nave.png file in the bin 
     // directory! 
     _image = ImageIO.read(new File("nave.png")); 
    } catch (IOException e) { 
     System.err.println("Cannot find ship _image: " + e.getMessage()); 
    } 
    location = starting.clone(); 
    facing = Math.PI; 
} 

public void accelerate(double force) { 
    // TODO change the speed (velocity, really) by force in the direction 
    // the ship is facing. 
    // add a vector of appropriate magnitude by the facing direction 

    Vector acc = new Vector(facing); 

    acc = acc.scale(force); 

    speed = speed.add(acc); 

} 

public void rotate(double angle) { 
    // TODO change the direction the ship is facing. Can accept any angle 
    // as a parameter but should store it as in [0,2*pi) 

    while (angle <= 0.0f) { 
     angle += (Math.PI * 2); 
    } 
    while (angle >= Math.PI) { 
     angle -= (Math.PI * 2); 
    } 

    facing += angle; 

} 

public void move(Dimension bounds) { 
    // TODO Move the ship its speed. The ship should wrap around 
    // within its box. (Hint: move the ship by the size of the 
    // bounding area to wrap it around; you may need to do this 
    // more than once if the ship is moving fast enough.) 

    location = speed.move(location); 

    while (location.getX() > bounds.width) { 
     Vector v = new Vector(location.getX() - WIDTH); 
     location = v.move(location); 
    } 

    while (location.getX() < -WIDTH) { 
     Vector v = new Vector(location.getX() + WIDTH); 
     location = v.move(location); 
    } 

    while (location.getY() > bounds.height) { 
     Vector v = new Vector(location.getY() - WIDTH); 
     location = v.move(location); 
    } 

    while (location.getY() < -WIDTH) { 
     Vector v = new Vector(location.y() + WIDTH); 
     location = v.move(location); 
    } 

} 

public void draw(Graphics g2d) { 
    double locationX = _image.getWidth()/2; 
    double locationY = _image.getHeight()/2; 
    AffineTransform tx = AffineTransform.getRotateInstance(facing, 
      locationX, locationY); 
    AffineTransformOp op = new AffineTransformOp(tx, 
      AffineTransformOp.TYPE_BILINEAR); 

    // Drawing the rotated image at the required drawing locations 
    // Code for rotating adapted from StackOverflow. 
    g2d.drawImage(op.filter(_image, null), location.getX(), 
      location.getY(), null); 
} 

這裏是我的矢量類:所有這些代碼工作:)

public class Vector { 

private final double _dx, _dy; 

public Vector() { 
    _dy = 0.0; 
    _dx = 0.0; 
} 

public Vector(double x, double y) { 
    _dx = x; 
    _dy = y; 
} 

public Vector(Point a, Point b) { 
    _dx = b.x() - a.x(); 
    _dy = b.y() - a.y(); 
} 

public Vector(double angle) { 
    _dx = Math.cos(angle); 
    _dy = Math.sin(angle); 
} 

public double dx() { 
    return _dx; 
} 

public double dy() { 
    return _dy; 
} 

public Point move(Point b) { 

    double x = b.x(); 
    double y = b.y(); 
    x += _dx; 
    y += _dy; 

    return new Point(x, y); 

} 

public Vector add(Vector a) { 
    double x = (a._dx + _dx); 
    double y = (a._dy + _dy); 

    return new Vector(x, y); 
} 

public Vector scale(double s) { 
    double x = _dx * s; 
    double y = _dy * s; 

    return new Vector(x, y); 
} 

public double magnitude() { 
    double x = Math.pow(_dx, 2); 
    double y = Math.pow(_dy, 2); 

    return Math.sqrt(x + y); 
} 

public Vector normalize() { 
    double x = _dx/magnitude(); 
    double y = _dy/magnitude(); 
    return new Vector(x, y); 
} 

public Vector rotate(double rads) { 
    double theta = angle(); 
    theta += rads; 
    return new Vector(theta); 
} 

public double angle() { 
    double alpha = Math.acos(dx()/magnitude()); 
    if (dy() < 0) 
     alpha = Math.PI - alpha; 
    return alpha; 
} 

@Override 
public String toString() { 
    String vector = "[" + _dx + "," + _dy + "]"; 
    return vector; 
} 

@Override 
public boolean equals(Object obj) { 
    if (obj instanceof Vector) { 
     Vector vector = (Vector) obj; 
     if ((Math.abs(_dx - vector._dx) <= (1/10000000000f)) 
       && (Math.abs(_dy - vector._dy) <= (1/10000000000f))) 
      return true; 
     else 
      return false; 
    } else 
     return false; 
} 

@Override 
public int hashCode() { 
    return (int) Math.round((angle() * 180)/Math.PI); 
} 

}

+1

有幾件事。您發佈了大量代碼,其中大部分代碼可能與您的問題無關。另外,不要使用'Vector',因爲它已被棄用。改爲嘗試'ArrayList '。最後,當你需要某些東西來循環(或重新開始)溢出時考慮模數... – BlackVegetable

+0

Doh,我看到這是一個自定義向量。忽略我最後評論的那部分內容。 – BlackVegetable

+0

你能否提供模數運算的任何代碼?上面的方法與while循環做的事情基本相同 – Programatic

回答

2

在建議擴大使用模,你可以使用它可以很容易地繞回,不用循環:

// Assuming move is called for each time frame 
// We can update the location of ship using modulo when it exceeds the bounds 
public void move(Dimension bounds) { 
    // TODO Move the ship its speed. The ship should wrap around 
    // within its box. (Hint: move the ship by the size of the 
    // bounding area to wrap it around; you may need to do this 
    // more than once if the ship is moving fast enough.) 

    location = speed.move(location); 

    if (location.getX() > bounds.width) { 
     location.setLocation(location.getX() % bounds.width), location.getY()); 
    } 
    else if (location.getX() < 0) { 
     location.setLocation(bounds.width - location.getX(), location.getY()); 
    } 

    if (location.getY() > bounds.height) { 
     location.setLocation(location.getX(), location.getY() % bounds.height); 
    } 
    else if (location.getY() < 0) { 
     location.setLocation(location.getX(), bounds.height - location.getY()); 
    } 
} 

你已經提供了很多代碼,所以我可能錯過了wh Ÿ您需要這樣做,但不是創建一個新的Delta Vector來移動位置,而是可以通過setLocation方法確定船舶應該設置的新包裝位置。

我希望這會有所幫助。

+0

這幾乎就是我想到的。我不記得Java如何用負值處理模數運算,但根據這一點,您可能甚至不需要條件檢查。 +1 – BlackVegetable

+0

@BlackVegtable有趣的建議,從我收集的內容來看,如果x%y = z,則-x%y = -z。 y的符號對結果沒有影響。 – xlm

+0

@BlackVegetable代碼可以說是簡化了,但仍然需要一些條件測試,即三元運算符,因爲需要將負座標添加到適當的綁定軸才能正確包裝。不管這是否可以理解,我不太確定,但我喜歡你的建議。 – xlm