mirror of
https://github.com/jneug/zeichenmaschine.git
synced 2026-04-14 06:33:34 +02:00
Implemented turtle layer and turtle class
This commit is contained in:
313
src/schule/ngb/zm/turtle/TurtleLayer.java
Normal file
313
src/schule/ngb/zm/turtle/TurtleLayer.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
78
test/src/schule/ngb/zm/TestTurtle.java
Normal file
78
test/src/schule/ngb/zm/TestTurtle.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user