import javax.swing.*;
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.util.Observer;
import java.util.Random;
/**
* Class that represents a Logo-style turtle. The turtle
* starts off facing north.
* A turtle can have a name, has a starting x and y position,
* has a heading, has a width, has a height, has a visible
* flag, has a body color, can have a shell color, and has a pen.
* The turtle will not go beyond the model display or picture
* boundaries.
*
* You can display this turtle in either a picture or in
* a class that implements ModelDisplay.
*
* Copyright Georgia Institute of Technology 2004
* @author Barb Ericson [email protected]
*/
public class SimpleTurtle
{
///////////////// fields ////////////////////////
/** count of the number of turtles created */
private static int numTurtles = 0;
/** array of colors to use for the turtles */
private static Color[] colorArray = { Color.green, Color.cyan, new Color(204,0,204), Color.gray};
/** who to notify about changes to this turtle */
private ModelDisplay modelDisplay = null;
/** picture to draw this turtle on */
private Picture picture = null;
/** width of turtle in pixels */
private int width = 15;
/** height of turtle in pixels */
private int height = 18;
/** current location in x (center) */
private int xPos = 0;
/** current location in y (center) */
private int yPos = 0;
/** heading angle */
private double heading = 0; // default is facing north
/** pen to use for this turtle */
private Pen pen = new Pen();
/** color to draw the body in */
private Color bodyColor = null;
/** color to draw the shell in */
private Color shellColor = null;
/** color of information string */
private Color infoColor = Color.black;
/** flag to say if this turtle is visible */
private boolean visible = true;
/** flag to say if should show turtle info */
private boolean showInfo = false;
/** the name of this turtle */
private String name = "No name";
////////////////// constructors ///////////////////
/**
* Constructor that takes the x and y position for the
* turtle
* @param x the x pos
* @param y the y pos
*/
public SimpleTurtle(int x, int y)
{
xPos = x;
yPos = y;
bodyColor = colorArray[numTurtles % colorArray.length];
setPenColor(bodyColor);
numTurtles++;
}
/**
* Constructor that takes the x and y position and the
* model displayer
* @param x the x pos
* @param y the y pos
* @param display the model display
*/
public SimpleTurtle(int x, int y, ModelDisplay display)
{
this(x,y); // invoke constructor that takes x and y
modelDisplay = display;
display.addModel(this);
}
/**
* Constructor that takes a model display and adds
* a turtle in the middle of it
* @param display the model display
*/
public SimpleTurtle(ModelDisplay display)
{
// invoke constructor that takes x and y
this((int) (display.getWidth() / 2),
(int) (display.getHeight() / 2));
modelDisplay = display;
display.addModel(this);
}
/**
* Constructor that takes the x and y position and the
* picture to draw on
* @param x the x pos
* @param y the y pos
* @param picture the picture to draw on
*/
public SimpleTurtle(int x, int y, Picture picture)
{
this(x,y); // invoke constructor that takes x and y
this.picture = picture;
this.visible = false; // default is not to see the turtle
}
/**
* Constructor that takes the
* picture to draw on and will appear in the middle
* @param picture the picture to draw on
*/
public SimpleTurtle(Picture picture)
{
// invoke constructor that takes x and y
this((int) (picture.getWidth() / 2),
(int) (picture.getHeight() / 2));
this.picture = picture;
this.visible = false; // default is not to see the turtle
}
//////////////////// methods /////////////////////////
/**
* Get the distance from the passed x and y location
* @param x the x location
* @param y the y location
*/
public double getDistance(int x, int y)
{
int xDiff = x - xPos;
int yDiff = y - yPos;
return (Math.sqrt((xDiff * xDiff) + (yDiff * yDiff)));
}
/**
* Method to turn to face another simple turtle
*/
public void turnToFace(SimpleTurtle turtle)
{
turnToFace(turtle.xPos,turtle.yPos);
}
/**
* Method to turn towards the given x and y
* @param x the x to turn towards
* @param y the y to turn towards
*/
public void turnToFace(int x, int y)
{
double dx = x - this.xPos;
double dy = y - this.yPos;
double arcTan = 0.0;
double angle = 0.0;
// avoid a divide by 0
if (dx == 0)
{
// if below the current turtle
if (dy > 0)
heading = 180;
// if above the current turtle
else if (dy < 0)
heading = 0;
}
// dx isn't 0 so can divide by it
else
{
arcTan = Math.toDegrees(Math.atan(dy / dx));
if (dx < 0)
heading = arcTan - 90;
else
heading = arcTan + 90;
}
// notify the display that we need to repaint
updateDisplay();
}
/**
* Method to get the picture for this simple turtle
* @return the picture for this turtle (may be null)
*/
public Picture getPicture() { return this.picture; }
/**
* Method to set the picture for this simple turtle
* @param pict the picture to use
*/
public void setPicture(Picture pict) { this.picture = pict; }
/**
* Method to get the model display for this simple turtle
* @return the model display if there is one else null
*/
public ModelDisplay getModelDisplay() { return this.modelDisplay; }
/**
* Method to set the model display for this simple turtle
* @param theModelDisplay the model display to use
*/
public void setModelDisplay(ModelDisplay theModelDisplay)
{ this.modelDisplay = theModelDisplay; }
/**
* Method to get value of show info
* @return true if should show info, else false
*/
public boolean getShowInfo() { return this.showInfo; }
/**
* Method to show the turtle information string
* @param value the value to set showInfo to
*/
public void setShowInfo(boolean value) { this.showInfo = value; }
/**
* Method to get the shell color
* @return the shell color
*/
public Color getShellColor()
{
Color color = null;
if (this.shellColor == null && this.bodyColor != null)
color = bodyColor.darker();
else color = this.shellColor;
return color;
}
/**
* Method to set the shell color
* @param color the color to use
*/
public void setShellColor(Color color) { this.shellColor = color; }
/**
* Method to get the body color
* @return the body color
*/
public Color getBodyColor() { return this.bodyColor; }
/**
* Method to set the body color which
* will also set the pen color
* @param color the color to use
*/
public void setBodyColor(Color color)
{
this.bodyColor = color;
setPenColor(this.bodyColor);
}
/**
* Method to set the color of the turtle.
* This will set the body color
* @param color the color to use
*/
public void setColor(Color color) { this.setBodyColor(color); }
/**
* Method to get the information color
* @return the color of the information string
*/
public Color getInfoColor() { return this.infoColor; }
/**
* Method to set the information color
* @param color the new color to use
*/
public void setInfoColor(Color color) { this.infoColor = color; }
/**
* Method to return the width of this object
* @return the width in pixels
*/
public int getWidth() { return this.width; }
/**
* Method to return the height of this object
* @return the height in pixels
*/
public int getHeight() { return this.height; }
/**
* Method to set the width of this object
* @param theWidth in width in pixels
*/
public void setWidth(int theWidth) { this.width = theWidth; }
/**
* Method to set the height of this object
* @param theHeight the height in pixels
*/
public void setHeight(int theHeight) { this.height = theHeight; }
/**
* Method to get the current x position
* @return the x position (in pixels)
*/
public int getXPos() { return this.xPos; }
/**
* Method to get the current y position
* @return the y position (in pixels)
*/
public int getYPos() { return this.yPos; }
/**
* Method to get the pen
* @return the pen
*/
public Pen getPen() { return this.pen; }
/**
* Method to set the pen
* @param thePen the new pen to use
*/
public void setPen(Pen thePen) { this.pen = thePen; }
/**
* Method to check if the pen is down
* @return true if down else false
*/
public boolean isPenDown() { return this.pen.isPenDown(); }
/**
* Method to set the pen down boolean variable
* @param value the value to set it to
*/
public void setPenDown(boolean value) { this.pen.setPenDown(value); }
/**
* Method to lift the pen up
*/
public void penUp() { this.pen.setPenDown(false);}
/**
* Method to set the pen down
*/
public void penDown() { this.pen.setPenDown(true);}
/**
* Method to get the pen color
* @return the pen color
*/
public Color getPenColor() { return this.pen.getColor(); }
/**
* Method to set the pen color
* @param color the color for the pen ink
*/
public void setPenColor(Color color) { this.pen.setColor(color); }
/**
* Method to set the pen width
* @param width the width to use in pixels
*/
public void setPenWidth(int width) { this.pen.setWidth(width); }
/**
* Method to get the pen width
* @return the width of the pen in pixels
*/
public int getPenWidth() { return this.pen.getWidth(); }
/**
* Method to clear the path (history of
* where the turtle has been)
*/
public void clearPath()
{
this.pen.clearPath();
}
/**
* Method to get the current heading
* @return the heading in degrees
*/
public double getHeading() { return this.heading; }
/**
* Method to set the heading
* @param heading the new heading to use
*/
public void setHeading(double heading)
{
this.heading = heading;
}
/**
* Method to get the name of the turtle
* @return the name of this turtle
*/
public String getName() { return this.name; }
/**
* Method to set the name of the turtle
* @param theName the new name to use
*/
public void setName(String theName)
{
this.name = theName;
}
/**
* Method to get the value of the visible flag
* @return true if visible else false
*/
public boolean isVisible() { return this.visible;}
/**
* Method to hide the turtle (stop showing it)
* This doesn't affect the pen status
*/
public void hide() { this.setVisible(false); }
/**
* Method to show the turtle (doesn't affect
* the pen status
*/
public void show() { this.setVisible(true); }
/**
* Method to set the visible flag
* @param value the value to set it to
*/
public void setVisible(boolean value)
{
// if the turtle wasn't visible and now is
if (visible == false && value == true)
{
// update the display
this.updateDisplay();
}
// set the visibile flag to the passed value
this.visible = value;
}
/**
* Method to update the display of this turtle and
* also check that the turtle is in the bounds
*/
public synchronized void updateDisplay()
{
// check that x and y are at least 0
if (xPos < 0)
xPos = 0;
if (yPos < 0)
yPos = 0;
// if picture
if (picture != null)
{
if (xPos >= picture.getWidth())
xPos = picture.getWidth() - 1;
if (yPos >= picture.getHeight())
yPos = picture.getHeight() - 1;
Graphics g = picture.getGraphics();
paintComponent(g);
}
else if (modelDisplay != null)
{
if (xPos >= modelDisplay.getWidth())
xPos = modelDisplay.getWidth() - 1;
if (yPos >= modelDisplay.getHeight())
yPos = modelDisplay.getHeight() - 1;
modelDisplay.modelChanged();
}
}
/**
* Method to move the turtle foward 100 pixels
*/
public void forward() { forward(100); }
/**
* Method to move the turtle forward the given number of pixels
* @param pixels the number of pixels to walk forward in the heading direction
*/
public void forward(int pixels)
{
int oldX = xPos;
int oldY = yPos;
// change the current position
xPos = oldX + (int) (pixels * Math.sin(Math.toRadians(heading)));
yPos = oldY + (int) (pixels * -Math.cos(Math.toRadians(heading)));
// add a move from the old position to the new position to the pen
pen.addMove(oldX,oldY,xPos,yPos);
// update the display to show the new line
updateDisplay();
}
/**
* Method to go backward by 100 pixels
*/
public void backward()
{
backward(100);
}
/**
* Method to go backward a given number of pixels
* @param pixels the number of pixels to walk backward
*/
public void backward(int pixels)
{
forward(-pixels);
}
/**
* Method to move to turtle to the given x and y location
* @param x the x value to move to
* @param y the y value to move to
*/
public void moveTo(int x, int y)
{
this.pen.addMove(xPos,yPos,x,y);
this.xPos = x;
this.yPos = y;
this.updateDisplay();
}
/**
* Method to turn left
*/
public void turnLeft()
{
this.turn(-90);
}
/**
* Method to turn right
*/
public void turnRight()
{
this.turn(90);
}
/**
* Method to turn the turtle the passed degrees
* use negative to turn left and pos to turn right
* @param degrees the amount to turn in degrees
*/
public void turn(double degrees)
{
this.heading = (heading + degrees) % 360;
this.updateDisplay();
}
/**
* Method to draw a passed picture at the current turtle
* location and rotation in a picture or model display
* @param dropPicture the picture to drop
*/
public synchronized void drop(Picture dropPicture)
{
Graphics2D g2 = null;
// only do this if drawing on a picture
if (picture != null)
g2 = (Graphics2D) picture.getGraphics();
else if (modelDisplay != null)
g2 = (Graphics2D) modelDisplay.getGraphics();
// if g2 isn't null
if (g2 != null)
{
// save the current tranform
AffineTransform oldTransform = g2.getTransform();
// rotate to turtle heading and translate to xPos and yPos
g2.rotate(Math.toRadians(heading),xPos,yPos);
// draw the passed picture
g2.drawImage(dropPicture.getImage(),xPos,yPos,null);
// reset the tranformation matrix
g2.setTransform(oldTransform);
// draw the pen
pen.paintComponent(g2);
}
}
/**
* Method to paint the turtle
* @param g the graphics context to paint on
*/
public synchronized void paintComponent(Graphics g)
{
// cast to 2d object
Graphics2D g2 = (Graphics2D) g;
// if the turtle is visible
if (visible)
{
// save the current tranform
AffineTransform oldTransform = g2.getTransform();
// rotate the turtle and translate to xPos and yPos
g2.rotate(Math.toRadians(heading),xPos,yPos);
// determine the half width and height of the shell
int halfWidth = (int) (width/2); // of shell
int halfHeight = (int) (height/2); // of shell
int quarterWidth = (int) (width/4); // of shell
int thirdHeight = (int) (height/3); // of shell
int thirdWidth = (int) (width/3); // of shell
// draw the body parts (head)
g2.setColor(bodyColor);
g2.fillOval(xPos - quarterWidth,
yPos - halfHeight - (int) (height/3),
halfWidth, thirdHeight);
g2.fillOval(xPos - (2 * thirdWidth),
yPos - thirdHeight,
thirdWidth,thirdHeight);
g2.fillOval(xPos - (int) (1.6 * thirdWidth),
yPos + thirdHeight,
thirdWidth,thirdHeight);
g2.fillOval(xPos + (int) (1.3 * thirdWidth),
yPos - thirdHeight,
thirdWidth,thirdHeight);
g2.fillOval(xPos + (int) (0.9 * thirdWidth),
yPos + thirdHeight,
thirdWidth,thirdHeight);
// draw the shell
g2.setColor(getShellColor());
g2.fillOval(xPos - halfWidth,
yPos - halfHeight, width, height);
// draw the info string if the flag is true
if (showInfo)
drawInfoString(g2);
// reset the tranformation matrix
g2.setTransform(oldTransform);
}
// draw the pen
pen.paintComponent(g);
}
/**
* Method to draw the information string
* @param g the graphics context
*/
public synchronized void drawInfoString(Graphics g)
{
g.setColor(infoColor);
g.drawString(this.toString(),xPos + (int) (width/2),yPos);
}
/**
* Method to return a string with informaiton
* about this turtle
* @return a string with information about this object
*/
public String toString()
{
return this.name + " turtle at " + this.xPos + ", " +
this.yPos + " heading " + this.heading + ".";
}
} // end of class
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.util.Observer;
import java.util.Random;
/**
* Class that represents a Logo-style turtle. The turtle
* starts off facing north.
* A turtle can have a name, has a starting x and y position,
* has a heading, has a width, has a height, has a visible
* flag, has a body color, can have a shell color, and has a pen.
* The turtle will not go beyond the model display or picture
* boundaries.
*
* You can display this turtle in either a picture or in
* a class that implements ModelDisplay.
*
* Copyright Georgia Institute of Technology 2004
* @author Barb Ericson [email protected]
*/
public class SimpleTurtle
{
///////////////// fields ////////////////////////
/** count of the number of turtles created */
private static int numTurtles = 0;
/** array of colors to use for the turtles */
private static Color[] colorArray = { Color.green, Color.cyan, new Color(204,0,204), Color.gray};
/** who to notify about changes to this turtle */
private ModelDisplay modelDisplay = null;
/** picture to draw this turtle on */
private Picture picture = null;
/** width of turtle in pixels */
private int width = 15;
/** height of turtle in pixels */
private int height = 18;
/** current location in x (center) */
private int xPos = 0;
/** current location in y (center) */
private int yPos = 0;
/** heading angle */
private double heading = 0; // default is facing north
/** pen to use for this turtle */
private Pen pen = new Pen();
/** color to draw the body in */
private Color bodyColor = null;
/** color to draw the shell in */
private Color shellColor = null;
/** color of information string */
private Color infoColor = Color.black;
/** flag to say if this turtle is visible */
private boolean visible = true;
/** flag to say if should show turtle info */
private boolean showInfo = false;
/** the name of this turtle */
private String name = "No name";
////////////////// constructors ///////////////////
/**
* Constructor that takes the x and y position for the
* turtle
* @param x the x pos
* @param y the y pos
*/
public SimpleTurtle(int x, int y)
{
xPos = x;
yPos = y;
bodyColor = colorArray[numTurtles % colorArray.length];
setPenColor(bodyColor);
numTurtles++;
}
/**
* Constructor that takes the x and y position and the
* model displayer
* @param x the x pos
* @param y the y pos
* @param display the model display
*/
public SimpleTurtle(int x, int y, ModelDisplay display)
{
this(x,y); // invoke constructor that takes x and y
modelDisplay = display;
display.addModel(this);
}
/**
* Constructor that takes a model display and adds
* a turtle in the middle of it
* @param display the model display
*/
public SimpleTurtle(ModelDisplay display)
{
// invoke constructor that takes x and y
this((int) (display.getWidth() / 2),
(int) (display.getHeight() / 2));
modelDisplay = display;
display.addModel(this);
}
/**
* Constructor that takes the x and y position and the
* picture to draw on
* @param x the x pos
* @param y the y pos
* @param picture the picture to draw on
*/
public SimpleTurtle(int x, int y, Picture picture)
{
this(x,y); // invoke constructor that takes x and y
this.picture = picture;
this.visible = false; // default is not to see the turtle
}
/**
* Constructor that takes the
* picture to draw on and will appear in the middle
* @param picture the picture to draw on
*/
public SimpleTurtle(Picture picture)
{
// invoke constructor that takes x and y
this((int) (picture.getWidth() / 2),
(int) (picture.getHeight() / 2));
this.picture = picture;
this.visible = false; // default is not to see the turtle
}
//////////////////// methods /////////////////////////
/**
* Get the distance from the passed x and y location
* @param x the x location
* @param y the y location
*/
public double getDistance(int x, int y)
{
int xDiff = x - xPos;
int yDiff = y - yPos;
return (Math.sqrt((xDiff * xDiff) + (yDiff * yDiff)));
}
/**
* Method to turn to face another simple turtle
*/
public void turnToFace(SimpleTurtle turtle)
{
turnToFace(turtle.xPos,turtle.yPos);
}
/**
* Method to turn towards the given x and y
* @param x the x to turn towards
* @param y the y to turn towards
*/
public void turnToFace(int x, int y)
{
double dx = x - this.xPos;
double dy = y - this.yPos;
double arcTan = 0.0;
double angle = 0.0;
// avoid a divide by 0
if (dx == 0)
{
// if below the current turtle
if (dy > 0)
heading = 180;
// if above the current turtle
else if (dy < 0)
heading = 0;
}
// dx isn't 0 so can divide by it
else
{
arcTan = Math.toDegrees(Math.atan(dy / dx));
if (dx < 0)
heading = arcTan - 90;
else
heading = arcTan + 90;
}
// notify the display that we need to repaint
updateDisplay();
}
/**
* Method to get the picture for this simple turtle
* @return the picture for this turtle (may be null)
*/
public Picture getPicture() { return this.picture; }
/**
* Method to set the picture for this simple turtle
* @param pict the picture to use
*/
public void setPicture(Picture pict) { this.picture = pict; }
/**
* Method to get the model display for this simple turtle
* @return the model display if there is one else null
*/
public ModelDisplay getModelDisplay() { return this.modelDisplay; }
/**
* Method to set the model display for this simple turtle
* @param theModelDisplay the model display to use
*/
public void setModelDisplay(ModelDisplay theModelDisplay)
{ this.modelDisplay = theModelDisplay; }
/**
* Method to get value of show info
* @return true if should show info, else false
*/
public boolean getShowInfo() { return this.showInfo; }
/**
* Method to show the turtle information string
* @param value the value to set showInfo to
*/
public void setShowInfo(boolean value) { this.showInfo = value; }
/**
* Method to get the shell color
* @return the shell color
*/
public Color getShellColor()
{
Color color = null;
if (this.shellColor == null && this.bodyColor != null)
color = bodyColor.darker();
else color = this.shellColor;
return color;
}
/**
* Method to set the shell color
* @param color the color to use
*/
public void setShellColor(Color color) { this.shellColor = color; }
/**
* Method to get the body color
* @return the body color
*/
public Color getBodyColor() { return this.bodyColor; }
/**
* Method to set the body color which
* will also set the pen color
* @param color the color to use
*/
public void setBodyColor(Color color)
{
this.bodyColor = color;
setPenColor(this.bodyColor);
}
/**
* Method to set the color of the turtle.
* This will set the body color
* @param color the color to use
*/
public void setColor(Color color) { this.setBodyColor(color); }
/**
* Method to get the information color
* @return the color of the information string
*/
public Color getInfoColor() { return this.infoColor; }
/**
* Method to set the information color
* @param color the new color to use
*/
public void setInfoColor(Color color) { this.infoColor = color; }
/**
* Method to return the width of this object
* @return the width in pixels
*/
public int getWidth() { return this.width; }
/**
* Method to return the height of this object
* @return the height in pixels
*/
public int getHeight() { return this.height; }
/**
* Method to set the width of this object
* @param theWidth in width in pixels
*/
public void setWidth(int theWidth) { this.width = theWidth; }
/**
* Method to set the height of this object
* @param theHeight the height in pixels
*/
public void setHeight(int theHeight) { this.height = theHeight; }
/**
* Method to get the current x position
* @return the x position (in pixels)
*/
public int getXPos() { return this.xPos; }
/**
* Method to get the current y position
* @return the y position (in pixels)
*/
public int getYPos() { return this.yPos; }
/**
* Method to get the pen
* @return the pen
*/
public Pen getPen() { return this.pen; }
/**
* Method to set the pen
* @param thePen the new pen to use
*/
public void setPen(Pen thePen) { this.pen = thePen; }
/**
* Method to check if the pen is down
* @return true if down else false
*/
public boolean isPenDown() { return this.pen.isPenDown(); }
/**
* Method to set the pen down boolean variable
* @param value the value to set it to
*/
public void setPenDown(boolean value) { this.pen.setPenDown(value); }
/**
* Method to lift the pen up
*/
public void penUp() { this.pen.setPenDown(false);}
/**
* Method to set the pen down
*/
public void penDown() { this.pen.setPenDown(true);}
/**
* Method to get the pen color
* @return the pen color
*/
public Color getPenColor() { return this.pen.getColor(); }
/**
* Method to set the pen color
* @param color the color for the pen ink
*/
public void setPenColor(Color color) { this.pen.setColor(color); }
/**
* Method to set the pen width
* @param width the width to use in pixels
*/
public void setPenWidth(int width) { this.pen.setWidth(width); }
/**
* Method to get the pen width
* @return the width of the pen in pixels
*/
public int getPenWidth() { return this.pen.getWidth(); }
/**
* Method to clear the path (history of
* where the turtle has been)
*/
public void clearPath()
{
this.pen.clearPath();
}
/**
* Method to get the current heading
* @return the heading in degrees
*/
public double getHeading() { return this.heading; }
/**
* Method to set the heading
* @param heading the new heading to use
*/
public void setHeading(double heading)
{
this.heading = heading;
}
/**
* Method to get the name of the turtle
* @return the name of this turtle
*/
public String getName() { return this.name; }
/**
* Method to set the name of the turtle
* @param theName the new name to use
*/
public void setName(String theName)
{
this.name = theName;
}
/**
* Method to get the value of the visible flag
* @return true if visible else false
*/
public boolean isVisible() { return this.visible;}
/**
* Method to hide the turtle (stop showing it)
* This doesn't affect the pen status
*/
public void hide() { this.setVisible(false); }
/**
* Method to show the turtle (doesn't affect
* the pen status
*/
public void show() { this.setVisible(true); }
/**
* Method to set the visible flag
* @param value the value to set it to
*/
public void setVisible(boolean value)
{
// if the turtle wasn't visible and now is
if (visible == false && value == true)
{
// update the display
this.updateDisplay();
}
// set the visibile flag to the passed value
this.visible = value;
}
/**
* Method to update the display of this turtle and
* also check that the turtle is in the bounds
*/
public synchronized void updateDisplay()
{
// check that x and y are at least 0
if (xPos < 0)
xPos = 0;
if (yPos < 0)
yPos = 0;
// if picture
if (picture != null)
{
if (xPos >= picture.getWidth())
xPos = picture.getWidth() - 1;
if (yPos >= picture.getHeight())
yPos = picture.getHeight() - 1;
Graphics g = picture.getGraphics();
paintComponent(g);
}
else if (modelDisplay != null)
{
if (xPos >= modelDisplay.getWidth())
xPos = modelDisplay.getWidth() - 1;
if (yPos >= modelDisplay.getHeight())
yPos = modelDisplay.getHeight() - 1;
modelDisplay.modelChanged();
}
}
/**
* Method to move the turtle foward 100 pixels
*/
public void forward() { forward(100); }
/**
* Method to move the turtle forward the given number of pixels
* @param pixels the number of pixels to walk forward in the heading direction
*/
public void forward(int pixels)
{
int oldX = xPos;
int oldY = yPos;
// change the current position
xPos = oldX + (int) (pixels * Math.sin(Math.toRadians(heading)));
yPos = oldY + (int) (pixels * -Math.cos(Math.toRadians(heading)));
// add a move from the old position to the new position to the pen
pen.addMove(oldX,oldY,xPos,yPos);
// update the display to show the new line
updateDisplay();
}
/**
* Method to go backward by 100 pixels
*/
public void backward()
{
backward(100);
}
/**
* Method to go backward a given number of pixels
* @param pixels the number of pixels to walk backward
*/
public void backward(int pixels)
{
forward(-pixels);
}
/**
* Method to move to turtle to the given x and y location
* @param x the x value to move to
* @param y the y value to move to
*/
public void moveTo(int x, int y)
{
this.pen.addMove(xPos,yPos,x,y);
this.xPos = x;
this.yPos = y;
this.updateDisplay();
}
/**
* Method to turn left
*/
public void turnLeft()
{
this.turn(-90);
}
/**
* Method to turn right
*/
public void turnRight()
{
this.turn(90);
}
/**
* Method to turn the turtle the passed degrees
* use negative to turn left and pos to turn right
* @param degrees the amount to turn in degrees
*/
public void turn(double degrees)
{
this.heading = (heading + degrees) % 360;
this.updateDisplay();
}
/**
* Method to draw a passed picture at the current turtle
* location and rotation in a picture or model display
* @param dropPicture the picture to drop
*/
public synchronized void drop(Picture dropPicture)
{
Graphics2D g2 = null;
// only do this if drawing on a picture
if (picture != null)
g2 = (Graphics2D) picture.getGraphics();
else if (modelDisplay != null)
g2 = (Graphics2D) modelDisplay.getGraphics();
// if g2 isn't null
if (g2 != null)
{
// save the current tranform
AffineTransform oldTransform = g2.getTransform();
// rotate to turtle heading and translate to xPos and yPos
g2.rotate(Math.toRadians(heading),xPos,yPos);
// draw the passed picture
g2.drawImage(dropPicture.getImage(),xPos,yPos,null);
// reset the tranformation matrix
g2.setTransform(oldTransform);
// draw the pen
pen.paintComponent(g2);
}
}
/**
* Method to paint the turtle
* @param g the graphics context to paint on
*/
public synchronized void paintComponent(Graphics g)
{
// cast to 2d object
Graphics2D g2 = (Graphics2D) g;
// if the turtle is visible
if (visible)
{
// save the current tranform
AffineTransform oldTransform = g2.getTransform();
// rotate the turtle and translate to xPos and yPos
g2.rotate(Math.toRadians(heading),xPos,yPos);
// determine the half width and height of the shell
int halfWidth = (int) (width/2); // of shell
int halfHeight = (int) (height/2); // of shell
int quarterWidth = (int) (width/4); // of shell
int thirdHeight = (int) (height/3); // of shell
int thirdWidth = (int) (width/3); // of shell
// draw the body parts (head)
g2.setColor(bodyColor);
g2.fillOval(xPos - quarterWidth,
yPos - halfHeight - (int) (height/3),
halfWidth, thirdHeight);
g2.fillOval(xPos - (2 * thirdWidth),
yPos - thirdHeight,
thirdWidth,thirdHeight);
g2.fillOval(xPos - (int) (1.6 * thirdWidth),
yPos + thirdHeight,
thirdWidth,thirdHeight);
g2.fillOval(xPos + (int) (1.3 * thirdWidth),
yPos - thirdHeight,
thirdWidth,thirdHeight);
g2.fillOval(xPos + (int) (0.9 * thirdWidth),
yPos + thirdHeight,
thirdWidth,thirdHeight);
// draw the shell
g2.setColor(getShellColor());
g2.fillOval(xPos - halfWidth,
yPos - halfHeight, width, height);
// draw the info string if the flag is true
if (showInfo)
drawInfoString(g2);
// reset the tranformation matrix
g2.setTransform(oldTransform);
}
// draw the pen
pen.paintComponent(g);
}
/**
* Method to draw the information string
* @param g the graphics context
*/
public synchronized void drawInfoString(Graphics g)
{
g.setColor(infoColor);
g.drawString(this.toString(),xPos + (int) (width/2),yPos);
}
/**
* Method to return a string with informaiton
* about this turtle
* @return a string with information about this object
*/
public String toString()
{
return this.name + " turtle at " + this.xPos + ", " +
this.yPos + " heading " + this.heading + ".";
}
} // end of class