import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics2D; import java.awt.Stroke; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import jp.digitalmuseum.mr.Matereal; import jp.digitalmuseum.mr.entity.Robot; import jp.digitalmuseum.mr.gui.*; import jp.digitalmuseum.mr.gui.utils.VectorFieldPainter; import jp.digitalmuseum.mr.hakoniwa.Hakoniwa; import jp.digitalmuseum.mr.hakoniwa.HakoniwaRobotWithPen; import jp.digitalmuseum.mr.message.Event; import jp.digitalmuseum.mr.message.EventListener; import jp.digitalmuseum.mr.message.ImageUpdateEvent; import jp.digitalmuseum.mr.resource.Wheels; import jp.digitalmuseum.mr.resource.WheelsController; import jp.digitalmuseum.mr.task.Follow; import jp.digitalmuseum.mr.task.Move; import jp.digitalmuseum.mr.task.Task; import jp.digitalmuseum.mr.task.VectorFieldTask; import jp.digitalmuseum.utils.Location; import jp.digitalmuseum.utils.Position; import jp.digitalmuseum.utils.ScreenPosition; import jp.digitalmuseum.utils.Vector2D; /** * Click to navigate one robot. The other robot will follow him. * Test of assigning tasks to robots. * * @author Jun KATO */ public class ClickAndFollowQuickDef { private Hakoniwa hakoniwa; private VectorFieldTask follow; private ScreenPosition goal = null; public static void main(String[] args) { new ClickAndFollowQuickDef(); } public ClickAndFollowQuickDef() { // Run hakoniwa. hakoniwa = new Hakoniwa(); hakoniwa.start(); final Robot followee; final Robot follower; followee = new HakoniwaRobotWithPen("followee", new Location(hakoniwa.getRealWidth()/2 - 30, hakoniwa.getRealHeight()/2, -Math.PI*3/4)); follower = new HakoniwaRobotWithPen("follower", new Location(hakoniwa.getRealWidth()/2 + 30, hakoniwa.getRealHeight()/2, -Math.PI*3/4)); follow = new VectorFieldTask() { public void getUniqueVectorOut(Position position, Vector2D vector) { Position destination = getLocationProvider().getLocation(followee).getRelativePosition(0, -70); vector.set( destination.getX()-position.getX(), destination.getY()-position.getY()); vector.normalize(); vector.mul(getMinimalNorm()); } }; follow.assign(follower); follow.start(); // Make a window for showing captured image. final DrawableFrame frame = new DrawableFrame() { private static final long serialVersionUID = 1L; private transient final VectorFieldPainter vectorFieldPainter = new VectorFieldPainter(hakoniwa); private transient final Stroke stroke = new BasicStroke(5); private transient final AlphaComposite alphaComp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .3f); private transient final AlphaComposite alphaComp2 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .7f); @Override public void dispose() { super.dispose(); Matereal.getInstance().dispose(); } @Override public void paint2D(Graphics2D g) { final Task task = followee.getAssignedTask(WheelsController.class); g.setColor(Color.white); g.fillRect(0, 0, getFrameWidth(), getFrameHeight()); final Composite comp = g.getComposite(); // Draw vectors. g.setComposite(alphaComp); g.setColor(Color.red); vectorFieldPainter.paint(follow, g); g.setComposite(alphaComp2); g.setColor(Color.black); g.fillRect(0, 0, getFrameWidth(), 35); // Draw status. g.setComposite(comp); g.drawLine(0, 35, getFrameWidth(), 35); g.setColor(Color.white); if (goal == null) { g.drawString("Click to set the destination.", 10, 30); } else { if (task != null) { g.drawString("Status: "+task, 10, 30); } else { g.drawString("Status: Stopped", 10, 30); } Stroke s = g.getStroke(); g.setStroke(stroke); g.setColor(Color.black); g.drawLine( goal.getX()-5, goal.getY()-5, goal.getX()+5, goal.getY()+5); g.drawLine( goal.getX()-5, goal.getY()+5, goal.getX()+5, goal.getY()-5); g.setStroke(s); } hakoniwa.drawImage(g); } }; frame.setResizable(false); frame.setFrameSize(hakoniwa.getWidth(), hakoniwa.getHeight()); // Bring the clicked object to the location in front of the user. frame.getPanel().addMouseListener(new MouseAdapter() { public void mouseReleased(MouseEvent e) { int x = e.getX(), y = e.getY(); goal = new ScreenPosition(x, y); Task task = followee.getAssignedTask(Wheels.class); if (task != null) task.stop(); Move move = new Move(hakoniwa.screenToReal(goal)); if (move.assign(followee)) move.start(); } }); // Repaint the window every time the image is updated. hakoniwa.addEventListener(new EventListener() { public void eventOccurred(Event e) { if (e instanceof ImageUpdateEvent) { frame.repaint(); } } }); } }