Implemented turtle layer and turtle class

This commit is contained in:
ngb
2021-12-31 15:28:09 +01:00
parent 271b65bce1
commit 1201bbc708
3 changed files with 391 additions and 304 deletions

View File

@@ -0,0 +1,313 @@
package schule.ngb.zm.turtle;
import schule.ngb.zm.Color;
import schule.ngb.zm.Layer;
import schule.ngb.zm.Options;
import schule.ngb.zm.Vector;
import schule.ngb.zm.formen.FilledShape;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.Stack;
public class TurtleLayer extends Layer {
// Rotating by the clock
public static final int H1 = 30;
public static final int H2 = 60;
public static final int H3 = 90;
public static final int H4 = 120;
public static final int H5 = 150;
public static final int H6 = 180;
public static final int H7 = 210;
public static final int H8 = 240;
public static final int H9 = 270;
public static final int H10 = 300;
public static final int H11 = 330;
public static final int H12 = 360;
private static Stack<Color> turtleColors;
static {
turtleColors = new Stack<>();
turtleColors.add(Color.ORANGE);
turtleColors.add(Color.YELLOW);
turtleColors.add(Color.MAGENTA);
turtleColors.add(Color.GREEN);
turtleColors.add(Color.RED);
turtleColors.add(Color.BLUE);
}
private Turtle mainTurtle = null;
private ArrayList<Turtle> turtles = new ArrayList<Turtle>(6);
public TurtleLayer() {
super();
mainTurtle = newTurtle();
}
public TurtleLayer( int width, int height ) {
super(width, height);
mainTurtle = newTurtle();
}
public Turtle newTurtle() {
Turtle newTurtle = new Turtle();
newTurtle.position.x = getWidth() / 2;
newTurtle.position.y = getHeight() / 2;
newTurtle.direction.x = 0.0;
newTurtle.direction.y = -1.0;
synchronized( turtles ) {
if( !turtleColors.isEmpty() ) {
newTurtle.setStrokeColor(turtleColors.pop());
}
turtles.add(newTurtle);
}
return newTurtle;
}
public Turtle getTurtle() {
return mainTurtle;
}
public Turtle getTurtle( int i ) {
return turtles.get(i);
}
/*
@Override
public void clear() {
drawing.setBackground(STD_BACKGROUND.getColor());
drawing.clearRect(0, 0, buffer.getWidth(), buffer.getHeight());
}
*/
@Override
public void draw( Graphics2D graphics ) {
super.draw(graphics);
synchronized( turtles ) {
for( Turtle t : turtles ) {
if( t.visible ) {
t.draw(graphics);
}
}
}
}
// Begin of delegate methods (auto-generated)
public void fill() {
mainTurtle.fill();
}
public void fd( double dist ) {
mainTurtle.fd(dist);
}
public void forward( double dist ) {
mainTurtle.forward(dist);
}
public void bk( double dist ) {
mainTurtle.bk(dist);
}
public void back( double dist ) {
mainTurtle.back(dist);
}
public void left() {
mainTurtle.left();
}
public void lt( double angle ) {
mainTurtle.lt(angle);
}
public void left( double angle ) {
mainTurtle.left(angle);
}
public void right() {
mainTurtle.right();
}
public void rt( double angle ) {
mainTurtle.rt(angle);
}
public void right( double angle ) {
mainTurtle.right(angle);
}
public void penUp() {
mainTurtle.penUp();
}
public void penDown() {
mainTurtle.penDown();
}
public void moveTo( double x, double y ) {
mainTurtle.moveTo(x, y);
}
// End of delegate methods (auto-generated)
public class Turtle extends FilledShape {
boolean penDown = true;
boolean visible = true;
Vector position = new Vector(0, 0);
Vector direction = new Vector(0, -1);
Path2D.Double path = new Path2D.Double();
boolean pathOpen = false;
Turtle() {}
private void addPosToPath() {
if( !pathOpen ) {
path.reset();
path.moveTo(position.x, position.y);
pathOpen = true;
} else {
path.lineTo(position.x, position.y);
}
}
private void closePath() {
if( pathOpen ) {
addPosToPath();
path.closePath();
pathOpen = false;
}
}
public void fill() {
closePath();
if( fillColor != null && fillColor.getAlpha() > 0 ) {
drawing.setColor(fillColor.getColor());
drawing.fill(path);
}
}
public boolean isVisible() {
return visible;
}
@Override
public void draw( Graphics2D graphics ) {
Shape shape = new RoundRectangle2D.Double(
-12, -5, 16, 10, 5, 3
);
AffineTransform verzerrung = new AffineTransform();
verzerrung.translate(position.x, position.y);
verzerrung.rotate(-1 * direction.angle());
shape = verzerrung.createTransformedShape(shape);
graphics.setColor(strokeColor.getColor());
graphics.fill(shape);
graphics.setColor(Color.BLACK.getColor());
graphics.setStroke(createStroke());
graphics.draw(shape);
}
public void fd( double dist ) {
this.forward(dist);
}
public void forward( double dist ) {
addPosToPath();
Vector positionStart = position.copy();
position.add(Vector.setLength(direction, dist));
if( penDown ) {
drawing.setColor(strokeColor.getColor());
drawing.setStroke(createStroke());
drawing.drawLine((int) positionStart.x, (int) positionStart.y, (int) position.x, (int) position.y);
}
}
public void bk( double dist ) {
this.forward(-1 * dist);
}
public void back( double dist ) {
this.forward(-1 * dist);
}
public void left() {
this.left(90);
}
public void lt( double angle ) {
this.left(-angle);
}
public void left( double angle ) {
direction.rotate(-angle);
}
public void right() {
this.right(90);
}
public void rt( double angle ) {
this.right(angle);
}
public void right( double angle ) {
direction.rotate(angle);
}
public void penUp() {
penDown = false;
}
public void penDown() {
penDown = true;
}
public void moveTo( double x, double y ) {
addPosToPath();
position.x = x;
position.y = y;
if( penDown ) {
drawing.setColor(strokeColor.getColor());
drawing.setStroke(createStroke());
drawing.drawLine((int) x, (int) y, (int) position.x, (int) position.y);
}
}
}
}

View File

@@ -1,304 +0,0 @@
package schule.ngb.zm.turtle;
import schule.ngb.zm.Ebene;
import schule.ngb.zm.Farbe;
import schule.ngb.zm.Vektor;
import schule.ngb.zm.formen.Fuellform;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.Stack;
public class Turtleebene extends Ebene {
private static Stack<Farbe> turtleFarben;
static {
turtleFarben = new Stack<>();
turtleFarben.add(Farbe.ORANGE);
turtleFarben.add(Farbe.GELB);
turtleFarben.add(Farbe.MAGENTA);
turtleFarben.add(Farbe.GRUEN);
turtleFarben.add(Farbe.ROT);
turtleFarben.add(Farbe.BLAU);
}
private Turtle ersterTurtle = null;
private ArrayList<Turtle> turtles = new ArrayList<Turtle>(6);
public Turtleebene() {
super();
}
public Turtleebene( int pWidth, int pHeight ) {
super(pWidth, pHeight);
}
public Turtle neueTurtle() {
Turtle newTurtle = new Turtle();
newTurtle.position.x = getBreite() / 2;
newTurtle.position.y = getHoehe() / 2;
newTurtle.richtung.x = 0.0;
newTurtle.richtung.y = -1.0;
synchronized( turtles ) {
if( !turtleFarben.isEmpty() ) {
newTurtle.setKonturFarbe(turtleFarben.pop());
}
turtles.add(newTurtle);
}
return newTurtle;
}
private Turtle t() {
if( ersterTurtle == null ) {
ersterTurtle = neueTurtle();
}
return ersterTurtle;
}
@Override
public void leeren() {
zeichnung.setBackground(STD_HINTERGRUND);
zeichnung.clearRect(0, 0, puffer.getWidth(), puffer.getHeight());
}
public void vor( double pStrecke ) {
t().vor(pStrecke);
}
public void links( double pWinkel ) {
t().links(pWinkel);
}
public void rechts( double pWinkel ) {
t().rechts(pWinkel);
}
public void rechts() {
t().rechts(90);
}
public void links() {
t().links(90);
}
public void stiftRunter() {
t().stiftRunter();
}
public void stiftHoch() {
t().stiftHoch();
}
public Color getFuellfarbe() {
return t().getFuellfarbe();
}
public void setFuellfarbe( Color pFarbe ) {
t().setFuellfarbe(pFarbe);
}
public void setFuellfarbe( int gray ) {
t().setFuellfarbe(gray);
}
public void keineFuellung() {
t().keineFuellung();
}
public void setFuellfarbe( int gray, int alpha ) {
t().setFuellfarbe(gray, alpha);
}
public void setFuellfarbe( int red, int green, int blue ) {
t().setFuellfarbe(red, green, blue);
}
public void setFuellfarbe( int red, int green, int blue, int alpha ) {
t().setFuellfarbe(red, green, blue, alpha);
}
public Color getKonturFarbe() {
return t().getKonturFarbe();
}
public void setKonturFarbe( Color pKonturFarbe ) {
t().setKonturFarbe(pKonturFarbe);
}
public void setKonturFarbe( int gray ) {
t().setKonturFarbe(gray);
}
public void keineKontur() {
t().keineKontur();
}
public void setKonturFarbe( int gray, int alpha ) {
t().setKonturFarbe(gray, alpha);
}
public void setKonturFarbe( int red, int green, int blue ) {
t().setKonturFarbe(red, green, blue);
}
public void setKonturFarbe( int red, int green, int blue, int alpha ) {
t().setKonturFarbe(red, green, blue, alpha);
}
public double getKonturDicke() {
return t().getKonturDicke();
}
public void setKonturDicke( double pDicke ) {
t().setKonturDicke(pDicke);
}
public int getKonturArt() {
return t().getKonturArt();
}
public void setKonturArt( int konturArt ) {
t().setKonturArt(konturArt);
}
public void bewegeNach( double x, double y ) {
t().bewegeNach(x, y);
}
public void fuellen() {
t().fuellen();
}
@Override
public void zeichnen( Graphics2D graphics ) {
super.zeichnen(graphics);
synchronized( turtles ) {
for( Turtle t : turtles ) {
if( t.sichtbar ) {
t.zeichnen(graphics);
}
}
}
}
class Turtle extends Fuellform {
boolean stiftUnten = true;
boolean sichtbar = true;
Vektor position = new Vektor(0, 0);
Vektor richtung = new Vektor(0, -1);
Path2D.Double path = new Path2D.Double();
boolean pathOpen = false;
private void addPosToPath() {
if( !pathOpen ) {
path.reset();
path.moveTo(position.x, position.y);
pathOpen = true;
} else {
path.lineTo(position.x, position.y);
}
}
private void closePath() {
if( pathOpen ) {
addPosToPath();
path.closePath();
pathOpen = false;
}
}
public void fuellen() {
closePath();
if( fuellFarbe != null && fuellFarbe.getAlpha() > 0 ) {
zeichnung.setColor(fuellFarbe);
zeichnung.fill(path);
}
}
public void vor( double pStrecke ) {
addPosToPath();
Vektor positionStart = position.kopie();
position.addieren(Vektor.setLaenge(richtung, pStrecke));
if( stiftUnten ) {
zeichnung.setColor(konturFarbe);
zeichnung.setStroke(createStroke());
zeichnung.drawLine((int) positionStart.x, (int) positionStart.y, (int) position.x, (int) position.y);
}
}
public boolean istSichtbar() {
return sichtbar;
}
@Override
public void zeichnen( Graphics2D graphics ) {
Shape shape = new RoundRectangle2D.Double(
-12, -5, 16, 10, 5, 3
);
AffineTransform verzerrung = new AffineTransform();
verzerrung.translate(position.x, position.y);
verzerrung.rotate(-1 * richtung.winkel());
shape = verzerrung.createTransformedShape(shape);
graphics.setColor(konturFarbe);
graphics.fill(shape);
graphics.setColor(Color.BLACK);
graphics.setStroke(createStroke());
graphics.draw(shape);
}
public void links() {
links(90);
}
public void links( double pWinkel ) {
richtung.drehen(Math.toRadians(-1 * pWinkel));
}
public void rechts() {
rechts(90);
}
public void rechts( double pWinkel ) {
richtung.drehen(Math.toRadians(pWinkel));
}
public void stiftHoch() {
stiftUnten = false;
}
public void stiftRunter() {
stiftUnten = true;
}
public void bewegeNach( double x, double y ) {
addPosToPath();
position.x = x;
position.y = y;
if( stiftUnten ) {
zeichnung.setColor(konturFarbe);
zeichnung.setStroke(createStroke());
zeichnung.drawLine((int) x, (int) y, (int) position.x, (int) position.y);
}
}
}
}

View File

@@ -0,0 +1,78 @@
package schule.ngb.zm;
import schule.ngb.zm.turtle.TurtleLayer;
import schule.ngb.zm.turtle.TurtleLayer.Turtle;
public class TestTurtle extends Zeichenmaschine {
public static void main( String[] args ) {
new TestTurtle();
}
TurtleLayer turtle;
TurtleLayer.Turtle t1, t2;
public void setup() {
turtle = new TurtleLayer();
addLayer(turtle);
t1 = turtle.getTurtle();
t2 = turtle.newTurtle();
t1.setStrokeWeight(2.0);
t2.setStrokeWeight(1.4);
t1.setFillColor(244, 64, 22);
t2.setFillColor(33, 64, 255);
}
@Override
public void update( double delta ) {
//t1.right(1);
t1.penUp();
t1.moveTo(100, 100);
t1.penDown();
t2.penUp();
t2.moveTo(200, 200);
t2.penDown();
}
public void draw() {
turtle.clear();
star(5, 80, 40, t1);
star(5, 80, 40, t2);
}
void star( int corners, int size ) {
star(5, size, 40, t1);
}
void star( int corners, int size, int angle, Turtle t ) {
int angle2 = (180 - (360/corners) - angle) / 2;
t.penUp();
t.left();
t.fd(size*1.25);
t.right();
t.penDown();
for( int i = 0; i < corners; i++ ) {
t.right(360/corners);
t.right(angle2);
t.fd(size);
t.left(2*angle2);
t.fd(size);
t.right(angle2);
}
t.fill();
t.penUp();
t.right();
t.fd(size*1.25);
t.left();
t.penDown();
}
}