如何在屏幕上放置对象?

时间:2014-01-28 00:45:39

标签: java coordinate-transformation

我正在研究一个采用船舶对象并移动它的程序。我遇到的麻烦是,如果它越过一侧,那么它应该在另一侧回绕。

任何帮助都会很棒:)

这是我的船类:移动方法是我需要帮助的。我的代码不起作用:/

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 个答案:

答案 0 :(得分:2)

扩展使用modulo的建议,你可以按照以下方式使用它来轻松环绕而不用循环:

// 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());
   }
}

你已经提供了很多代码,所以我可能已经错过了你为什么需要这样做,而不是创建一个新的delta Vector来移动位置,你也可以确定船应该是新的包裹位置按照setLocation方法设置它。

我希望这会有所帮助。

相关问题