/** Der Herbert ist los! * Dieser Hamster hat die Fähigkeit beliebige Drehungen zu machen, ist also * nicht an ein Gitternetz gebunden * Es ist möglich den Hamster beliebig viele Bewegungsabläufe wiederholen zu * lassen * * @author ( (c) Thilo Beckmann ) * @version ( 14.03.2004 ) * **/ import java.applet.*; import java.awt.event.*; import java.awt.*; public class Herbert2 extends Applet implements ActionListener { Hamster Herbert = new Hamster(); // Zeichenfläche Hamster Vorschau = new Hamster(); // Richtungsvorschau TextField schritt; // Für die Weite des Schrittes zuständig TextField winkel; // Für den Winkel zuständig TextField wholung; // Für die Wiederholung der eingestellten schrittweite und winkel TextField verzoeg; // Für die zeitliche Verzögerung Label schrittl; // Beschriftung für die gemachten Schritte Label winkell; // Beschriftung für die momentane Ausrichtung Label verzoegl; // Zum Einschalten der zeitlichen Verzögerung Label wholungl; // Für die Anzahl der Umläufe bis zur ursprünglichen Orientierung Label wholunglinfo; // Information zu Wiederholung Label koordina; // Anzeige der Koordinaten Label info; // Für Copyright etc... Button wholungb; // Klicken, Hamster führt eingestellte Bewegung aus Button schrittb; // Klicken, Hamster läuft vorwärts Button winkelb; // Klicken, Hamster dreht sich nach links Button wholungspez; // Klicken, Hamster läuft solange, bis er die alte Orient. hat Button bildLoeschen;// Klicken, um das Feld zu löschen Checkbox malen; // Markieren, damit der Hamster eine Spur hinterlässt String s; // Zum Übertragen der Eingegebenen Werte int schritti = 0; // Anzahl der gelaufenen Schritte int winkeli = 0; // Aktuelle Orientierung in Grad (0=rechts) int schritteBis360i = 0; // Anzahl Wiederholungen für "vollen" Igel int schrittialt = 0;// alter Wert für schritteBis360i int b=100; // Breite des Hamsterfeldes int h=100; // Hoehe des Hamsterfeldes int r=5; // Rand um Hamsterfeld public void init () { b = getWidth() - 2*r - 160; h = getHeight()- 2*r - 30; this.setBackground(Color.lightGray); setLayout(null); // Initialisierung der Steuerelemente: schritt = new TextField("300", 3); schrittb = new Button("vorwärts"); schrittl = new Label("Schritte gelaufen: 0"); winkel = new TextField("130", 3); winkelb = new Button("° drehen"); winkell = new Label("Richtung: 0° "); bildLoeschen= new Button("Bild löschen"); malen = new Checkbox("Spur hinterlassen", null, true); wholung = new TextField("36", 3); wholungb = new Button("mal gehen"); wholungspez = new Button("zeichne Igel"); wholungl = new Label("0 Runden"); wholunglinfo= new Label("Ein Igel mit 130° braucht:"); verzoeg = new TextField("25",3); verzoegl = new Label("msec. Verzög."); info = new Label("(c) Thilo Beckmann 14.03.04"); koordina = new Label("x: 0 | y: 0"); // Initialisierung von Herbert: Herbert.setSize(b,h); Herbert.setBackground(Color.white); Herbert.setBounds(r,r,b,h); add(Herbert); Herbert.init(); Vorschau.setSize(65,60); Vorschau.setBackground(Color.lightGray); Vorschau.setBounds(b+2*r+90,230,65,60); Vorschau.setStartPos(33.0,30.0); add(Vorschau); Vorschau.init(); groesseAngleichen(); add(verzoeg); add(verzoegl); add(schritt); add(schrittb); schrittb.addActionListener(this); add(winkel); add(winkelb); winkelb.addActionListener(this); add(schrittl); add(winkell); add(koordina); add(wholung); add(wholungb); wholungb.addActionListener(this); add(wholunglinfo); add(wholungl); add(wholungspez); wholungspez.addActionListener(this); add(malen); add(bildLoeschen); bildLoeschen.addActionListener(this); add(info); } public void paint(Graphics g) { groesseAngleichen(); } public void groesseAngleichen() { b = getWidth() - 2*r - 160; h = getHeight()- 2*r - 30; Herbert.setBounds(r,r,b,h); Vorschau.setBounds(b+2*r+90,230,65,60); // Positionierung der Steuerelemente verzoeg. setBounds(b+2*r, 50, 50,30); verzoegl. setBounds(b+2*r+70, 50,100,30); schritt. setBounds(b+2*r,100, 50,30); schrittb. setBounds(b+2*r+70,100, 80,30); winkel. setBounds(b+2*r,150, 50,30); winkelb. setBounds(b+2*r+70,150, 80,30); schrittl. setBounds(b+2*r,200,150,30); schrittl.setBackground(Color.lightGray); winkell. setBounds(b+2*r,230, 85,30); winkell. setBackground(Color.lightGray); koordina. setBounds(b+2*r,260, 85,30); koordina.setBackground(Color.lightGray); wholung. setBounds(b+2*r,300, 50,30); wholungb. setBounds(b+2*r+70,300, 80,30); wholunglinfo. setBounds(b+2*r,330,150,30); wholungl. setBounds(b+2*r,360, 70,30); wholungspez. setBounds(b+2*r+70,360, 80,30); malen. setBounds(b+2*r,420,150,30); bildLoeschen. setBounds(b+2*r,450,150,30); info. setBounds(10,h+2*r,400,30); Herbert.zeichneRahmen(); Vorschau.zeichneRahmen(); } public int laengePause() { return Integer.parseInt(verzoeg.getText()); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand() == "vorwärts") { s = schritt.getText(); Herbert.geheVor(Integer.parseInt(s)); } if (e.getActionCommand() == "° drehen") { s = winkel.getText(); Herbert.dreheZeiger(Integer.parseInt(s)); Vorschau.dreheZeigerBig(Integer.parseInt(s)); } if (e.getActionCommand() == "Bild löschen") { Herbert.allesLoeschen(); } if (e.getActionCommand() == "mal gehen") { igelZeichnen(Integer.parseInt(wholung.getText())); } // Es wird ein Igel gezeichnet if (e.getActionCommand() == "zeichne Igel") { igelZeichnen(schritteBisStart()); } aktualisieren(); } public void igelZeichnen(int anzahlwiederholungen) { int schrittweite = Integer.parseInt(schritt.getText()); int grad = Integer.parseInt(winkel.getText()); int w=winkeli + grad; int zuMachendeSchritte = anzahlwiederholungen; if (schrittialt == zuMachendeSchritte) { for (int k=0; k 50) { Vorschau.dreheZeigerBig(grad); aktualisieren(); pause(laengePause()); } } } schrittialt = zuMachendeSchritte; } public void aktualisieren () { // Die Informations-Felder werden aktualisiert: schrittl.setText ("Schritte gelaufen: " + schritti); winkell. setText ("Richtung: " + winkeli+ "°"); koordina.setText ("x: "+(int)Herbert.xpos + " | y: "+(int)Herbert.ypos); // Der Rahmen wird nachgezogen Herbert.zeichneRahmen(); Herbert.dreheZeiger(0); Vorschau.dreheZeigerBig(0); } // Zum Ausrechnen, wieviele Schritte gemacht werden müssen, um wieder // die alte Orientierung zu haben public int schritteBisStart () { int grad = Integer.parseInt(winkel.getText()); int w=Math.abs(winkeli)+grad; int i=1; while (w%360 != Math.abs(winkeli) ) { w = w + grad; i++; if (i>360) break; // Weil nur "ganze" Winkel eingegeben werden // können ist mit 360 spätestens Schluss. } wholunglinfo.setText("Ein Igel mit "+grad+"° braucht:"); wholungl.setText(""+i+" Schritte"); return i; } // Pause-Methode zum Zeitverzögern (in MilliSekunden) public void pause (int dauer) { try { Thread.sleep(dauer); } catch(InterruptedException e) { return; } } /********************************************************************************/ /** Die Hamster-Klasse, in der alle Methoden declariert sind, die man benötigt */ /** um den Hamster zu steuern und die Malfläche anzusteuern. */ /********************************************************************************/ public class Hamster extends Canvas implements MouseMotionListener, MouseListener { Graphics g; double xpos=50.0, ypos=275.0; // die x- und y-Position des Pfeiles double alphaInRad = 0; // der eingestellte Winkel im Bogenmaß int alphaInGrad = 0; // der eingestellte Winkel in Grad int xstart=0, ystart=0; // Zum Festlegen der Richtung mit der Maus int xalt=0, yalt=0; // Zum Löschen des Richtungs-Striches boolean mouseGedrueckt = false; // Ist eine Maustaste gedrückt? // Der Konstruktor des "Hamsters" public Hamster () { addMouseMotionListener(this); // Für die Bewegung der Maus addMouseListener(this); // Für die Tasten der Maus } // Initialisierung des Hamsters public void init() { g = getGraphics(); } // Methode, die den Startpunkt neu festlegt public void setStartPos (double xstartpos, double ystartpos) { xpos = xstartpos; ypos = ystartpos; koordina.setText ("x: "+(int)xpos + " | y: "+(int)ypos); } /** Methoden, die durch den MouseMotionListener erzwungen werden: */ /** mouseMoved und mouseDragged */ public void mouseMoved(MouseEvent e) { } // Mit der Maus kann man den Startpunkt des Hamsters neu festlegen // sowie die Orientierung neu bestimmen. public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); if (mouseGedrueckt) { zeiger(Color.white,5); g.setColor(Color.white); g.drawLine(xstart,ystart,xalt,yalt); g.setColor(Color.black); g.drawLine(xstart,ystart,x,y); xalt = x; yalt = y; zeiger(Color.white,5); winkeli = (int)((Math.atan2(-(ystart-y),xstart-x)*180)/Math.PI)+180; winkell.setText("Richtung: "+winkeli+"°"); zeiger(Color.red,5); } } /** Methoden, die durch den MouseListener erzwungen werden: */ /** mouseClicked, mouseEntered, mouseExited, mousePressed und*/ /** mouseReleased */ // Der Hamster wird auf die Stelle, an die der Mauszeiger zeigt, gesetzt public void mouseClicked(MouseEvent e) { int x=e.getX(), y=e.getY(); zeiger(Color.white,5); setStartPos((double)x,(double)y); zeiger(Color.red,5); } public void mouseEntered(MouseEvent e) { zeichneRahmen(); geheVor(0); } public void mouseExited(MouseEvent e) { zeichneRahmen(); geheVor(0); } // Wenn eine Maustaste gedrückt wird, dann kann die neue Orientierung // durch ziehen der Maus eingestellt werden public void mousePressed(MouseEvent e) { int x=e.getX(), y=e.getY(); zeiger(Color.white,5); zeiger(Color.red,5); mouseGedrueckt = true; xstart = (int)xpos; ystart = (int)ypos; } // Wenn die Maustaste wieder losgelassen wird, dann wird die neue // Orientierung des Hamsters festgelegt und der "Zieh"-Modus beendet public void mouseReleased(MouseEvent e) { int x=e.getX(), y=e.getY(); mouseGedrueckt = false; // Festlegung der neuen Richtung: g.setColor(Color.white); g.drawLine(xstart,ystart,x,y); zeiger(Color.white,5); winkeli = (int)((Math.atan2(-(ystart-y),xstart-x)*180)/Math.PI)+180; if (xstart==x & ystart==y) { winkeli = alphaInGrad; } winkell.setText("Richtung: "+winkeli+"°"); zeiger(Color.red,5); } // Methode, die den Pfeil um den angegebenen Weg unter Berücksichtigung // der Richtung nach vorne laufen lässt und dabei eine Spur hinterlässt, // die der angegebenen Farbe entspricht. public void move(int weg, Color farbe) { g.setColor(farbe); double xweg = (weg*Math.cos(alphaInRad)), yweg = (weg*Math.sin(alphaInRad)); g.drawLine ((int)xpos, (int)ypos, (int)(xpos + xweg), (int)(ypos - yweg)); xpos = xpos + xweg; ypos = ypos - yweg; } // Methode, die den Pfeil um den angegebenen Weg unter Berücksichtigung // der Richtung nach vorne laufen lässt. public void geheVor(int weg) { zeiger(Color.white,5); if (malen.getState()) move(weg, Color.black); // Weg zeichnen else move(weg, Color.white); // Weg loeschen schritti = schritti + weg; zeiger(Color.red,5); } // Umrechnung des eigegebenen Winkels ins Bogenmaß public void drehe(int winkel) { if (mouseGedrueckt) { alphaInGrad = winkeli; } else winkeli = alphaInGrad; alphaInGrad=(alphaInGrad + winkel) % 360; alphaInRad = ((double)(alphaInGrad)) * Math.PI/ 180.0; winkeli = alphaInGrad; } // Methode, die die Richtung des Pfeiles um den angegebenen Winkel // nach links dreht. Dabei wird der alte Hamsterkopf gelöscht, der // neue Winkel eingestellt und der neue Hamsterkopf gezeichnet. public void dreheZeiger(int winkel) { zeiger(Color.white,5); drehe(winkel); zeiger(Color.red,5); } // Für die Vorschau wird der Hamsterkopf "groß" gezeichnet public void dreheZeigerBig(int winkel) { g.setColor(Color.black); g.drawRect(0,0,64,59); g.setColor(Color.lightGray); g.fillRect(1,1,63,58); drehe(winkel); zeiger(Color.red,15); } // Der Hamsterkopf: public void zeiger (Color f, int weite) { drehe(150); move(weite, f); drehe(180); move(weite,f); drehe(-120); move(weite,f); drehe(180); move(weite,f); drehe(-30); } // Die gesamte Fläche wird gelöscht public void allesLoeschen () { g.setColor(Color.white); g.fillRect(0,0,500,500); } // Zeichnet einen schwarzen Rahmen um die Hamsterfläche public void zeichneRahmen() { int weite = getWidth(); int hoehe = getHeight(); g.setColor(Color.black); g.drawRect(0,0,weite-1,hoehe-1); } } }