www.r-krell.de
Webangebot für Schule und Unterricht, Software, Fotovoltaik und mehr

Willkommen/Übersicht  >  Informatik  >  Java-Seite b3) (2018) 2019

Informatik mit Java

Teil b3)_2018 (in der -Fassung von 2019)
Ergänzung zu Teil b2)_2017,  Programm P9,  Aufgabe 3:
Galgenmann-Spiel mit zusätzlicher Grafik



Eine vollständige Übersicht aller meiner Seiten "Informatik mit Java" gibt's auf der Informatik-Hauptseite! Bezugsseite und Vorgänger dieser Seite ist die Seite b2)_2017.

Auf dieser Seite b3)_2018 finden Sie (im Februar 2019 vollständig neu überarbeitet):


zum Seitenanfang / zum Seitenende



Aufgabenstellung: Übungs-Aufgabe 3 zum Programm P9



Auf der letzten Seite b2)_2017 war bereits das Programm P9 (auch bekannt als Glücksrad, Hangman bzw. Galgenmann/Galgenmännchen) vorgestellt worden: Die Buchstaben eines geheimen Worts werden durch Unterstriche markiert. Die Spielerin bzw. der Spieler kann einen Buchstaben des Alphabets nachfragen bzw. eintippen. Ist der gefragte Buchstabe im Wort vorhanden, wird er dort jeweils stellenrichtig angezeigt. Es geht darum, das gegebene Wort möglichst schnell, d.h. mit möglichst wenig abgefragten Buchstaben, zu erraten. Da ich inzwischen (Februar 2019) über die üblichen Spielregeln aufgeklärt wurde, muss ich jetzt richtigstellen: Normalerweise ist nicht die Gesamtzahl der abgefragten Buchstaben begrenzt, sondern nur die Zahl 'falscher' Buchstaben. Es dürfen höchstens 10 im Wort nicht vorhandene Buchstaben erfragt werden. Nur für jeden gefragten Buchstaben, der nicht im Wort vorkommt, wird ein Strich zu einer Galgenmännchen-Zeichnung hinzu gefügt. Nach 10 falschen Buchstaben bzw. 10 Strichen (wobei der Kopf als ein Strich gilt) ist die Zeichnung fertig und es kann nur noch das ganze Wort erraten werden, ohne dass weitere Buchstaben abgefragt werden dürfen. Insofern ist das Programm gegenüber P9 von Seite b2)_2017 nicht nur um die Grafik erweitert, sondern folgt auch einer veränderten Spiellogik!

Die Bilder zeigen das neue Spiel nach insgesamt 4 (davon 2 falschen) und - etwas später - nach 12 (davon 7 falschen) erfragten Buchstaben. Da die Taste "Lösung prüfen" am Schluss noch nicht gedrückt wurde, wird im Moment noch keine Richtig- oder Falsch-Meldung zum Lösungsversuch angezeigt. Natürlich kann man auch noch alle weiteren Buchstaben der vermuteten Lösung einzeln erfragen, bis das Wort komplett angezeigt wird. Denn jetzt kosten richtige erfragte Buchstaben ja keine Galgenstriche mehr!

Bildschirmfoto: Galgenmann-Spiel nach 7 gefragten Buchstaben   Bildschirmfoto: Galgenmann-Spiel nach 10 gefragten Buchstaben



Das Spiel soll in Java programmiert werden. Im Folgenden wird möglicher Java-Quelltext in zwei Versionen für zwei verschiedenen Grafik-Darstellungen (P9_A3a / _A3b) vorgestellt und besprochen. Gegenüber dem ursprünglichen Programm P9 (siehe unten auf der letzten Seite b2)_2017) kommt in der Oberfläche nur das Rechteck bzw. Panel mit der grafischen Darstellung hinzu. Wegen der neuen Spiellogik wäre allerdings auch eine Vergrößerung des Textfelds für die Anzeige der bereits gefragten Buchstaben sinnvoll; das ist hier aber noch nicht verwirklicht. Am Ende dieser Seite können die fertigen Programme auch ausprobiert werden!




zum Seitenanfang / zum Seitenende

Aufteilung in drei Klassen



Nach den bisherigen Programmierübungen müsste klar sein, dass der Programmtext sinnvollerweise auf mindestens drei Dateien/Klassen verteilt werden sollte:

  1. die Hauptklasse (inkl. der Startmethode main) für die Darstellung der Oberfläche und die Zusammenarbeit mit der Spielfunktion (Klasse 2) sowie der (austauschbaren) Einbindung eines Grafik-Fensters (Klasse 3)
  2. eine weitgehend oberflächenunabhängige Klasse 2 mit der eigentlichen Spiellogik bzw. -funktion, die insbesondere ein zu erratendes Wort bereitstellen kann, erfragte Buchstaben zählen und im Wort anzeigen kann sowie ein- bzw. übergebene Lösungswörter prüft
  3. eine Klasse für das Grafikfenster mit allen für die Darstellung benötigten Methoden, wobei die Bedienung natürlich sehr einfach sein sollte (indem einfach bei nächsterStrich der nächste passende Strich zum Galgen hinzu gezeichnet wird, ohne dass die aufrufende Stelle sagen oder auch nur wissen muss, welcher Strich das ist). Das durch diese Klasse 3 erzeugte Objekt sollte an Stelle eines normalen Java-JPanels in die Oberfläche (Klasse 1) eingebaut werden können, also praktisch ein auf die Galgenmännchen-Zeichnung spezialisiertes JPanel werden.

Für die Klasse 3 stelle ich zwei verschiedene Realisierungen vor:
    a) mit Strichzeichnungen per Java-Grafik oder
    b) mit dem Aufruf vorgefertigter Bilder, die vorab mit einem externen Zeichen- bzw. Grafikprogramm erstellt wurden, und jetzt nur passend angezeigt werden.

Der Austausch der beiden Klasse-3-Varianten a) oder b) soll nicht zu Änderungen der Klassen 1 und 2 zwingen, sieht man von den unterschiedlichen Namen ab, d.h. dass einmal die Klasse 3a oder zum anderen die Klasse 3b aufgerufen werden muss. Alles andere soll komplett gleich bleiben!

Sie als Leserin bzw. Leser sind natürlich herzlich aufgefordert, spätestens jetzt die Lektüre dieser Webseite zu unterbrechen und sich selbst Gedanken über eine passende Realisierung zu machen. Nach Fertigstellung Ihrer eigenen Version könnten Sie danach im Folgenden meinen Ansatz nachlesen, der nicht den Anspruch erhebt, die allein seeligmachende Umsetzung zu sein. Ein Vergleich verschiedener Implementationen hilft immer, wichtige Grundzüge zu erkennen.

Und während im Leistungskurs oder später auch hier im Grundkurs vor der Programmierung ein Modell bzw. Konzept erarbeitet werden soll, wobei graphische Mittel wie z.B. UML-Klassendiagramme sowie eine Schnittstellenbeschreibung für die anstehende Modellierung eingesetzt werden, will ich hier im Anfangsunterricht des ersten Grundkursjahrs noch nicht darauf bestehen: Nach meiner Erfahrungen machen solche Mittel im Unterricht erst Sinn, wenn die Schülerinnen und Schüler erfahren haben, dass Sie ohne Konzept das Zusammenspiel verschiedener Klassen nicht ausreichend durchschauen bzw. planen können. Erst dann sind sie bereit, sich mit Modellierung und Modellierungswerkzeugen zu beschäftigen - vorher werden solche Maßnahmen eher als zusätzliche Schwierigkeit statt als willkommene Hilfe angesehen. (Hinweise auf Modellierungen und geschickte Klassenaufteilung findet man auf vielen meiner Ausführlichen Seiten zur Informatik mit Java c) bis k) sowie DB3 bei den jeweils dort entwickelten Programmen, außerdem natürlich konzentriert auch auf den beiden Seiten zum Software-Engineering SWE und SWE-2 -- auf der letztgenannten Seite SWE-2 konkret am Beispiel eines Kartenspiel-Projekts).




zum Seitenanfang / zum Seitenende

Klasse 1: Oberfläche
P9_A3_Galgenmann.java



Die Programm-Oberfläche wird mit dem im Javaeditor eingebauten GUI-Builder bequem per drag & drop in einen neuen JFrame zusammen gezogen. Der Javaeditor erzeugt dabei den zugehörigen Quelltext automatisch, wobei Namen und Texte im Objekt-Inspektor geändert bzw. eingegeben werden. Nur wenige Zeilen müssen nachher noch "von Hand" in den so erhaltenen Programmtext eingefügt werden. Und wenn die Klasse P9_A3a_Panel.java schon kompiliert wurde, reicht ein Rechtsklick auf das Panel-Icon (das graue Quadrat in der Werkzeugleiste), um an Stelle des normalen JPanels ein P9_A3a_Panel in die Oberfläche einzubinden. (Den sehr empfehlenswerten Javaeditor stelle ich im Teil a) von Informatik mit Java vor; die offizielle Webseite ist javaeditor.org. Die folgende Abbildung zeigen die im Mai 2018 aktuelle Version 15.21 - bei den früher erstellten Programmen in meinem Web-Angebot kamen die damaligen Versionen zum Einsatz. Im Februar 2019 ist die Version 16.18 aktuell).

Bildschirmfoto: Javaeditor mit GUI-Builder für Galgenmann-Programm

Im nachfolgenden, vollständigen Quelltext sind die von Hand eingefügten Zeilen durch rote Zeilennummern gekennzeichnet (wobei Zeile 37 eigentlich doch automatisch erstellt wurde - per Rechtsklick auf das JPanel-Werkzeug, s.o.. Und auch Zeile 51 wurde automatisch erstellt und der Titel im Objektinspektor eingetragen. Wirklich 'von Hand' hinzugefügt wurden in den Zeilen 37 und 51 nur die Kommentare). Im Februar 2019 wurde der vorher hier gezeigte Programmtext so ergänzt, dass jetzt nicht mehr alle, sondern nur noch die 'falschen' (=im Wort nicht vorhandenen) erfragten Buchstaben zu Strichen im Galgen führen. Dazu wurde die Methode jBtBuchstabe_ActionPerformed neu entwickelt, die ab Zeile 139 beginnt.



  001 import java.awt.*;
  
002 import java.awt.event.*;
  
003 import javax.swing.*;
  
004 import javax.swing.event.*;
  
005 
  
006 /**
  
007   * P9_A3a_Galgenmann 
  
008   * Wort-Raten aus erfragten Buchstaben ("Glücksrad", "Galgenmännchen", "Hangman"..)
  
009   *
  
010   * @version vom 2.2.2019 für http://www.r-krell.de/if-java-b3_2018.htm
  
011   * @author  R. Krell (www.r-krell.de)
  
012   * 
  
013   * Lösung der Übungs-Aufgabe 3 zu P9 auf http://www.r-krell.de/if-java-b2_2017.htm;
  
014   * Variante a: mit per Java-Befehlen gezeichnetem Galgenmännchen (in P9_A3a_Panel;
  
015   * Variante b: mit Anzeige extern vorgefertigter Galgenbilder (in P9_A3b_Panel;
  
016   * (vgl. Zeilen 37 und 51; sonst hier und in P9_A3_GalgenmammFkt alles gleich)
  
017   * 
  
018   * Der Quelltext dieser Klasse wurde im Wesentlichen mit dem GUI-Builder des Javaeditors
  
019   * (javaeditor.org) erzeugt; von Hand eingetragene Zeilen haben rote Zeilennummern
  
020   * 
  021   */
  
022 
  
023 public class P9_A3a_Galgenmann extends JFrame {
  
024   P9_A3_GalgenmannFkt f = new P9_A3_GalgenmannFkt();  // für a und b gleich
  
025 
  
026   // Anfang Attribute
  
027   private JButton jBtNeu = new JButton();
  
028   private JTextField jTfAnzeige = new JTextField();
  
029   private JTextField jTfverbraucht = new JTextField();
  
030   private JTextField jTfBuchstabe = new JTextField();
  
031   private JButton jBtBuchstabe = new JButton();
  
032   private JTextField jTfLoesung = new JTextField();
  
033   private JButton jBtPruefen = new JButton();
  
034   private JLabel jLabel1 = new JLabel();
  
035   private JLabel jLabel2 = new JLabel();
  
036   private JLabel jLabel3 = new JLabel();
  
037   private P9_A3a_Panel galgen = new P9_A3a_Panel();  // bzw. _A3b_ für andere Version
  
038   // Ende Attribute
  
039   
  
040   public P9_A3a_Galgenmann() { 
  
041     // Frame-Initialisierung
  
042     super();
  
043     setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
  
044     int frameWidth = 444
  
045     int frameHeight = 303;
  
046     setSize(frameWidth, frameHeight);
  
047     Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
  
048     int x = (d.width - getSize().width) / 2;
  
049     int y = (d.height - getSize().height) / 2;
  
050     setLocation(x, y);
  
051     setTitle("P9_A3a_Galgenmann  (r-krell.de)");  // bzw. _A3b_ für andere Version
  
052     setResizable(false);
  
053     Container cp = getContentPane();
  
054     cp.setLayout(null);
  
055     // Anfang Komponenten
  
056     
  
057     jBtNeu.setBounds(241623325);
  
058     jBtNeu.setText("Neues Spiel / neues Wort");
  
059     jBtNeu.setMargin(new Insets(2222));
  
060     jBtNeu.addActionListener(new ActionListener() { 
  
061       public void actionPerformed(ActionEvent evt) { 
  
062         jBtNeu_ActionPerformed(evt);
  
063       }
  
064     });
  
065     jBtNeu.setToolTipText("(Neu-)Start des Spiels mit einem neuen Rate-Wort");
  
066     cp.add(jBtNeu);
  
067     jTfAnzeige.setBounds(245623325);
  
068     jTfAnzeige.setEditable(false);
  
069     jTfAnzeige.setToolTipText("Maskierte Anzeige des zu erratenden Worts: _ durch Buchstaben ersetzen!");
  
070     cp.add(jTfAnzeige);
  
071     jTfverbraucht.setBounds(2411214525);
  
072     jTfverbraucht.setEditable(false);
  
073     jTfverbraucht.setFont(new Font("Courier New", Font.PLAIN, 12));
  
074     jTfverbraucht.setToolTipText("Anzahl (gesamt/falsch) und Liste der bisher gefragten Buchstaben");
  
075     cp.add(jTfverbraucht);
  
076     jTfBuchstabe.setBounds(1761122525);
  
077     jTfBuchstabe.setHorizontalAlignment(SwingConstants.CENTER);
  
078     jTfBuchstabe.setToolTipText("Bitte hier Buchstabe eintippen, der im Wort vermutet wird");
  
079     cp.add(jTfBuchstabe);
  
080     jBtBuchstabe.setBounds(2081124925);
  
081     jBtBuchstabe.setText("ok");
  
082     jBtBuchstabe.setMargin(new Insets(2222));
  
083     jBtBuchstabe.addActionListener(new ActionListener() { 
  
084       public void actionPerformed(ActionEvent evt) { 
  
085         jBtBuchstabe_ActionPerformed(evt);
  
086       }
  
087     });
  
088     jBtBuchstabe.setToolTipText("Eingetippten ('gefragten') Buchstaben im Wort suchen");
  
089     cp.add(jBtBuchstabe);
  
090     jTfLoesung.setBounds(2416823325);
  
091     jTfLoesung.setToolTipText("Hier kann ein vermutetes Wort zur Prüfung eingegeben werden");
  
092     cp.add(jTfLoesung);
  
093     jBtPruefen.setBounds(2420823325);
  
094     jBtPruefen.setText("Lösung prüfen");
  
095     jBtPruefen.setMargin(new Insets(2222));
  
096     jBtPruefen.addActionListener(new ActionListener() { 
  
097       public void actionPerformed(ActionEvent evt) { 
  
098         jBtPruefen_ActionPerformed(evt);
  
099       }
  
100     });
  
101     jBtPruefen.setToolTipText("Programmbeschreibung auf www.r-krell.de/if-java-b3_2018.htm");
  
102     cp.add(jBtPruefen);
  
103     jLabel1.setBounds(248814419);
  
104     jLabel1.setText("gefragte Buchstaben");
  
105     cp.add(jLabel1);
  
106     jLabel2.setBounds(2414414719);
  
107     jLabel2.setText("Lösung / erratenes Wort");
  
108     cp.add(jLabel2);
  
109     jLabel3.setBounds(176889917);
  
110     jLabel3.setText("nächster Bst.");
  
111     cp.add(jLabel3);
  
112     galgen.setBounds(27216137217);
  
113     galgen.setBackground(Color.WHITE);
  
114     galgen.setToolTipText("Für jeden nicht vorhandenen gefragten Buchstaben wird (mit Java) ein Strich gezeichnet -- maximal 10");
  
115     cp.add(galgen);
  
116     // Ende Komponenten
  
117     
  
118     setVisible(true);
  
119   } // end of public P9_A3a_Galgenmann
  
120   
  
121   // Anfang Methoden
  
122   
  
123   public static void main(String[] args) {
  
124     new P9_A3a_Galgenmann();
  
125   } // end of main
  
126   
  
127   public void jBtNeu_ActionPerformed(ActionEvent evt) {
  
128     f.nächstesWort();
  
129     jTfAnzeige.setText(f.anzeige());
  
130     jTfverbraucht.setText(f.verwendeteBuchstaben);
  
131     jTfBuchstabe.setText("");
  
132     jTfLoesung.setText("");
  
133     jBtPruefen.setEnabled(true);
  
134     jBtBuchstabe.setEnabled(true);
  
135     jTfBuchstabe.requestFocus();
  
136     galgen.loesche();
  
137   } // end of jBtNeu_ActionPerformed
  
138 
  
139   public void jBtBuchstabe_ActionPerformed(ActionEvent evt) {
  
140     if (galgen.zahl() < 10)
  
141     {
  
142       String alteAnzeige = jTfAnzeige.getText();
  
143       int alt = f.verwendeteBuchstaben.length();  // Gesamtzahl der bisher gefragten Buchstaben
  
144       char bst = (jTfBuchstabe.getText()+"?").charAt(0); // neu gefragter Buchstabe
  
145       f.nimmBuchstaben(bst);       // Übergabe des gefragten Buchstabens an die Funktion
  
146       int neu = f.verwendeteBuchstaben.length();  // Gesamtzahl jetzt gefragter Buchstaben     
  
147       if (neu > alt)               // falls gültiger Buchstabe gefragt wurde
  
148       {
  
149         String neueAnzeige = f.anzeige();   // Wort evtl mit neu gefragtem/n Buchstaben 
  
150         if (!neueAnzeige.equals(alteAnzeige))
  
151         {
  
152           jTfAnzeige.setText(neueAnzeige);  // neuen Buchstaben im Wort anzeigen..   
  
153         }
  
154         else
  
155         {
  
156           galgen.nächsterStrich();          // .. oder nächsten Strich vom Galgenmann zeichnen          
  
157         }
  
158         jTfverbraucht.setText(""+neu+"/"+galgen.zahl()+": "+f.verwendeteBuchstaben);  // Zahl/davon_falsch ..  
  
159       }                                   // ..und alle bis jetzt gefragten Buchstaben anzeigen 
  
160       jTfBuchstabe.setText("");    // letzte Buchstaben-Eingabe löschen
  
161       jTfBuchstabe.requestFocus(); // Cursor in Eingabefeld für weitere Buchstaben 
  
162       jTfLoesung.setText("");      // evtl. getestetes Lösungs-Wort löschen 
  
163     }
  
164     if (galgen.zahl() >= 10)
  
165     {
  
166       jBtBuchstabe.setEnabled(false);     // OK-Knopf für weitere Buchstaben sperren
  
167       jTfLoesung.requestFocus();          // Feld für Lösungseingabe hervorheben
  
168     }
  
169     if ((f.anzeige()).indexOf('_')<0)     // keine Lücke mehr: alle Buchstaben bekannt, Wort vollständig
  
170     {                                                                
  
171       jTfLoesung.setText("Glückwunsch, Wort erraten!");  // Lob für richtige Lösung
  
172       jBtPruefen.setEnabled(false);       // Weitere Lösungsprüfungen..
  
173       jBtBuchstabe.setEnabled(false);     // ..und Buchstabeneingaben abschalten
  
174       jBtNeu.requestFocus();              // Neu-Knopf hervorheben
  
175     } 
  
176   } // end of jBtBuchstabe_ActionPerformed
  
177 
  
178   public void jBtPruefen_ActionPerformed(ActionEvent evt) {
  
179     String lsg = jTfLoesung.getText().trim();
  
180     if (f.prüfeLösung(lsg))
  
181     {
  
182       jTfAnzeige.setText(f.aktuellesWort);  // Wort vollständig anzeigen
  
183       jTfLoesung.setText("*"+lsg+"* ist richtig!");  // Lob für richtige Lösung
  
184       jBtPruefen.setEnabled(false);       // Weitere Lösungsprüfungen..
  
185       jBtBuchstabe.setEnabled(false);     // ..und Buchstabeneingaben abschalten
  
186       jBtNeu.requestFocus();              // Neu-Knopf hervorheben
  
187     } // end of if
  
188     else
  
189     {
  
190       jTfLoesung.setText("*"+lsg+"* ist falsch!");   // Ablehnen falscher Lösung
  
191     }
  
192   } // end of jBtPruefen_ActionPerformed
  
193 
  
194   // Ende Methoden
  
195 } // end of class P9_A3a_Galgenmann
  

In den Programmtext wurden einige Feinheiten eingebaut, um die Bedienung zu erleichtern: mit requestFocus wird dafür gesorgt, dass der Eingabe-Cursor anschließend im angegebenen Feld blinkt bzw. der genannte Button vorausgewählt wird. So wird zu Anfang (Zeile 135) und jeweils nach der Frage nach einem Buchstaben (Zeile 161) die Buchstaben-Eingabe ausgewählt, damit man ohne zusätzlichen Mausklick den nächsten Buchstaben fragen kann. Nach 10 falschen Buchstaben wird hingegen die Lösungs-Eingabe ausgewählt, weil keine Buchstaben mehr erfragt werden dürfen (Zeilen 164 bzw. 167 - deshalb wird der zugehörige OK-Knopf dann auch abgeschaltet und nur noch ausgegraut und funktionslos angezeigt: s. Zeilen 173 und 185). Und nach erfolgreicher Lösung wird man vermutlich ein neues Wort haben wollen - s. Zeilen 174 und 186. Durch Mausklick kann man die Voreinstellungen natürlich überwinden, also z.B. statt einen weiteren Buchstaben zu erfragen, ins Lösungsfeld klicken und dort die erratene Lösung eingeben.

Übrigens: Vor dem if in Zeile 169 hätte gerne noch ein else stehen können, weil der letzte fehlende Buchstabe in einem Wort nicht gleichzeitig mit dem zehnten Galgenstrich möglich ist.

Das Zusammenspiel mit den beiden anderen Klassen bzw. den dadurch erzeugten Objekten f und galgen lässt sich aus den sprechenden Namen der dort selbstprogrammierten Methoden und dem Kommentar entnehmen. Besonders hingewiesen wird nur auf Zeile 156: durch den Aufruf galgen.nächsterStrich() soll das in Zeile 37 eingebundene erweiterte JPanel namens galgen seinen internen Strichzähler erhöhen sowie die entsprechende Grafik erzeugen und darstellen. Der dafür nötige Programmtext steht aber nicht hier, sondern gekapselt in der Klasse P9_A3a_Panel bzw. P9_A3b_Panel (s.u.)! Hier, in der oben dargestellten zentralen Klasse, sollen eben keine Details der Grafik behandelt werden, sodass die beiden Grafikpanels a und b mit ihren ganz unterschiedlichen Anzeigemechanismen problemlos ausgetauscht werden können.




zum Seitenanfang / zum Seitenende

Klasse 2: Spiellogik bzw. -funktion
P9_A3_GalgenmannFkt.java



Hier müssen jetzt die Funktionen hinterlegt bzw. programmiert werden, die oben (z.B. in den Zeilen 128 bis 130 oder auch in den Zeilen 143, 145, 146.. der vorstehenden Klasse 1 vom Objekt f verlangt werden. Dabei ist f das nach dem folgendem Bauplan erzeugte Objekt, das alle dort beschriebenen Eigenschaften und Fähigkeiten hat.

Der zugehörige Quelltext kann vollständig von Hand in eine neue Editor-Seite (Datei > Neu > Java) eingetippt werden. Auf Wunsch erzeugt der Java-Editor aber auch halbautomatisch-interaktiv die Rahmen der benötigten Klasse mit Attributen und allen benötigten Methoden, die anschließend 'nur noch' mit dem Programmtext gefüllt werden müssen. Aber schon der leere Rahmen kann kompiliert werden, sodass damit auch der Quelltext der Klasse 1 fehlerfrei kompilierbar ist - auch wenn das so erzeugte Programm noch nicht richtig funktioniert. Ein solcher Rahmen wird mit dem Befehl UML > Neue Klasse erzeugt. Da in Zeile 128 des obigen Programmtextes der 1. Klasse der Aufruf f.nächstesWort() ohne Ausgabe und ohne Zuweisung erfolgt, scheint die Methode nächstesWort keinen Rückgabewert zu benötigen (Rückgabe void bei einer "Prozedur"). Durch den Gebrauch von f.verwendeteBuchstaben() als Argument in setText oben in Zeile 130 wird hingegen offenbar verlangt, dass die Methode verwendeteBuchstaben einen Text zurück gibt, also einen Rückgabewert vom Typ String hat. Sie muss deshalb als Funktion mit passendem Rückgabe-Typ angelegt werden, wie im Bild gezeigt ist:

Bildschirmfoto: Javaeditor mit UML-Klassen-Editor für GalgenmannFkt



Tatsächlich habe ich im Folgenden den gerade gezeigten UML-Klasseneditor des Javaeditors selbst nicht benutzt, sondern den Quelltext lieber vollständig von Hand eingegeben. [Der Java-Editor verfügt nicht nur praktisch über alle von BlueJ bekannten Möglichkeiten inkl. dem Testen von Klassen ohne main-Methode; er kann noch mehr und vereint den Programmtext-Editor mit Syntax-Hervorhebung, Blockstrukturdarstellung, Code-Vervollständigung u.v.a.m. noch mit einem GUI-Builder, dem UML-Klasseneditor und einem Struktogrammeditor. Die letzten drei integrierten Zusatzwerkzeuge erzeugen jeweils automatisch passenden Quelltext! Und natürlich lassen sich auch von händisch eingetipptem Programmtext UML-Diagramme zeichnen (s.u.), während der Struktogramm-Editor z.B. auf meiner folgenden Seite b4)_2018 zum Einsatz kommt]




001 public class P9_A3_GalgenmannFkt
002 // eigentliche Spielfunktion von Galgenmann, unabhängig von der Oberfläche und
003 // davon, ob/wie Grafik angezeigt wird -- 5/2018 & 2/2019 r-krell.de
004 {
005   String[] wort = {"Ratespiel","Buchstabe","Wegesrand","Butterbrot","Turboabitur","Suppenteller",
006     "Musikakademie","Altbierglas","Nacktschnecke","Computermaus","Kaffeemaschine","Kuchengabel",
007     "Trinkbecher","Rotstift","Niedrigpreis","Schlussverkauf","Campingplatz","Ledersofa",
008     "Bleistiftspitzer","Filialleiterin"};    // bel. erweiterbare Wortliste
009   int max = wort.length;      // Anzahl der vorstehend genannten, möglichen Wörter
010   int nr = 0;                 // Anzahl der bereits verwendeten Wörter
011   
012   String aktuellesWort = "";  // aktuell ausgewähltes/verwendetes Wort
013   boolean[] sichtbZeichen = new boolean[26]; 
014   String verwendeteBuchstaben = "";
015   
016       
017   public void nächstesWort()  // wählt zufällig ein bisher nicht benutzes Wort
018   {
019     String gefunden = "";
020     if (nr<max)               // sofern noch nicht alle Wörter verwendet wurden
021     {
022       int pos;
023       do {
024         pos = (int)(Math.random() * max); // zufällige Position in der Wortliste 
025       } while (wort[pos].equals("")); // bei gelöschten Wörtern erneut versuchen
026       gefunden = wort[pos];   // zufällig gefundenes Wort zwischenspeichern
027       wort[pos]="";           // gefundenes Wort aus der Wortliste löschen
028       nr++;                   // Anzahl verwendeter Wörter um 1 erhöhen
029     }
030     aktuellesWort = gefunden.toUpperCase(); // gefundenes Wort wird aktuelles Wort
031     keineBuchstabenBenutzt(); // für neues aktuelle Wort wurden noch keine..
032   }                           // ..Buchstaben geraten: verwendete Buchstaben löschen
033 
034   public void keineBuchstabenBenutzt()    // löscht verwendete Buchstaben
035   {
036     for (int i=0; i<26; i++)    // setzt alle 26 Buchstaben A .. Z des Alphabets
037     {
038       sichtbZeichen[i] = false// auf bisher nicht gefragt und daher nicht anzuzeigen
039     } // end of for
040     verwendeteBuchstaben = "";  // Liste der bisher gefragten Buchstaben leeren
041   }
042   
043   public void nimmBuchstaben (char bst) // prüft und verwendet eingegebenes Zeichen
044   {
045     if ('a' <= bst && bst <='z')   // verwandelt ggf. Kleinbuchstaben in Großbuchstaben
046     {
047       bst = (char)((int)bst-(int)'a'+(int)'A');
048     } // end of if
049     if ('A' <= bst && bst <= 'Z')  // nur bei echten Buchstaben (ungültige Zeichen werden ignoriert!)
050     {
051       sichtbZeichen[(int)bst-(int)'A']=true;   // Buchstabe als sichtbar markieren und
052       verwendeteBuchstaben = verwendeteBuchstaben + bst; // zu verwendeten Buchstaben dazu
053     } // end of if
054   }
055
   
056   public String anzeige () // Wort aus Unterstrichen und gefragten/verwendeten Buchstaben 
057   {                        // jeweils mit einem Leerzeichen Zwischenraum
058     String aus = "";
059     for (int i=0; i<aktuellesWort.length() ;i++) 
060     {
061       if (sichtbZeichen[(int)aktuellesWort.charAt(i)-(int)'A'])
062       {
063         aus = aus + " " + aktuellesWort.charAt(i); // sichtbarer Buchstabe
064       } // end of if
065       else 
066       {
067         aus = aus + " _";  // Leerzeichen für noch nicht gefragten Buchstaben
068       } // end of if-else
069     } // end of for   
070     return (aus);
071   }
072   
073   public boolean prüfeLösung (String eingabe)  // Prüfen des eingegeben Lösungsversuchs 
074   {
075     return (eingabe.equalsIgnoreCase(aktuellesWort));
076   }
077 }
 

Die gleiche Klasse wurde schon in der Original-Version des Programms P9 verwendet, da die Spiellogik unabhängig von der Oberfläche und der Grafik ist.

In der Methode nimmBuchstaben (ab Zeile 43 im gelb unterlegten Text) wird überprüft, ob der übergebene Buchstabe bst gültig ist. Dabei gilt auch ein schon früher erfragter Buchstabe als weitere gültige Frage (und bst wird nochmal zur Liste der bereits gefragten Buchstaben hinzugefügt). Unbeabsichtigt zu langes (=doppeltes) Drücken des OK-Knopfs schadet hingegen nicht, weil der gefragte Buchstabe sofort aus dem Eingabefeld entfernt wird (Zeile 160 in Klasse 1) und dann dort nichts mehr steht, was beim erneuten Knopfdruck bzw. beim Aufruf von jBtBuchstabe_ActionPerformed genommen werden könnte (bzw. ein '?' erkannt wird wegen Zeile 144 in Klasse 1, da ein einzelnes Schriftzeichen vom Typ char nicht leer sein darf). Ziffern, Leer- und Sonderzeichen werden aber einfach ignoriert, nicht gezählt und nicht extra gemeldet. Während sich das bei P9 bewährt hat, wurde bei meinem ersten Versuch der Klasse P9_A3_Galgenmann gelegentlich trotzdem Buchstaben gezählt, obwohl kein gefragter Buchstabe hinzu gekommen war. In der Klasse 1 frage ich daher jetzt mit den Zeilen 143, 146 und 147 ab, ob die Funktion f einen gültigen Buchstaben erkannt hat (wodurch neu größer wird als alt). Da der Galgen seit Februar 2019 nur weiter gezeichnet werden soll, wenn der gefragte Buchstabe nicht im Wort vorkommt, vergleiche ich nun das neue und das alte angezeigte Wort (Klasse 1, Zeilen 142, 149 und 150). Ohne Unterschied zeichne ich dann den nächsten Strich vom Galgen (Klasse 1, Zeile 156). Das bedeutet aber auch, dass ein mehrfach abgefragter Buchstabe, der bereits im Wort vorkam, als falscher Buchstabe gewertet und die Unaufmerksamkeit der Doppelabfrage mit einem Galgenstrich bestraft wird. Ausgelöst wird das Zeichnen dann vom Aufruf galgen.nächsterStrich(); in Zeile 156 der Klasse 1; programmiert wird das Zeichnen in der nächsten Klasse, der Klasse 3.




zum Seitenanfang / zum Seitenende

Klasse 3: Grafikpanel
P9_A3a_Panel.java bzw. P9_A3b_Panel.java



Im Anfangsunterricht muss nicht unbedingt der Vererbungsmechanismus ausführlich thematisiert werden: Es reicht zu wissen, dass man das von Java mitgelieferte JPanel durch eigene Methoden (wie nächsterStrich oder zahl) ergänzen und die vorhandene Methode paint so abändern (überschreiben) kann, dass sie nicht nur das leere Panel, sondern darauf auch das Galgenmännchen zeichnen kann. Außerdem muss einmal mitgeteilt werden, dass die Methode paint nicht direkt aufgerufen wird. Besser soll die im System vorhandene (nicht selbst zu [über-]schreibende) Methode repaint aufgerufen werden. repaint erledigt neben weiteren benötigten Hintergrund-Aufgaben immer auch den Aufruf von paint (weswegen die paint-Mathode innen zwar abgeändert werden kann, aber nicht anders benannt werden darf). repaint wird auch automatisch vom Computer aufgerufen, wenn das Fenster mit dem Programm verdeckt war oder der Bildschirm erneuert wird. Deswegen ist es sinnvoll, mit paint immer die gesamte bisherige Galgenfigur zu zeichnen und nicht nur den letzten Strich.



a) Grafik durch Zeichnen einzelner Striche mit Java

Handskizze: Galgenfigur als Entwurf für Zeichnung auf Grafik-PanelAuf Kästchenpapier habe ich zunächst eine grobe Skizze des zu zeichnenden Galgenmännchens angefertigt, um die Koordinaten der Endpunkte der einzelnen Striche (Strecken) ablesen zu können. Dabei habe ich bewusst darauf verzichtet, die echte Pixelzahl des in der Oberflächenklasse per Mausklick recht willkürlich aufgezogenen Panels zu verwenden, sondern gebe im Folgenden die Endpunkte 'relativ' an: so beginnt der Rumpf nicht im Punkt (7|5), sondern die x-Koordinate wird mit 7 Elfteln der Breite b und die y-Koordinate mit 5 Siebzehnteln der Höhe h angegeben: drawLine ((int)(7.0*b/11.0),(int)(5.0*h/17.0), (int)(8.0*b/11.0),(int)(9.0*h/17.0)), weil ich zufällig ein Seitenverhältnis von 11 zu 17 gewählt hatte. Die vielen (int)s führen ein TypeCasting auf die nächste, nicht größere ganze Zahl durch, d.h. schneiden die bei der Division evtl. auftretenden Kommastellen zum Schluss ab. Damit vorher aber richtig mit Kommastellen gerechnet wird, sind die Koordinaten als Dezimalzahlen 7.0 statt 7 angegeben. Der in Java als Rumpf des Männchens gezeichnete Strich ist übrigens etwas kürzer ausgefallen als geplant: nach meiner Skizze müsste der untere Punkt bei (8|10) bzw. (int)(8.0*b/11.0),(int)(10.0*h/17.0) liegen (statt wie in Zeile 71 programmiert bei (8|9)). Da die letztlich in der Oberfläche per Maus gewählte Bildgröße nicht genau das Seitenverhältnis 11 zu 17 hat (vgl. Klasse 1, Zeile 112), erscheint im Programm die Figur etwas schmaler als auf dem Papier und der Kopf wirkt länglich statt kreisrund. Andererseits würde auch bei einer Vergrößerung oder Verkleinerung des Grafikpanels in (oder mit) der Oberfläche die Figur immer bildfüllend angepasst gezeichnet und es müssen nicht immer wieder Pixel gezählt und verwendet werden.




001 import java.awt.*;
002 import javax.swing.*;
003 import javax.swing.event.*;
004 
005 public class P9_A3a_Panel extends JPanel   // erweitert/ändert normales Java-JPanel 
006 // spezielles Grafik-Panel für die Galgenmann-Oberfläche zur Anzeige des Galgenmanns
007 // aus Linien und einem Kreis per Java-Zeichenbefehlen -- 17.5.2018 & 2.2.2019  r-krell.de
008 {
009   int zahl = 0;   // Anzahl der bereits gezeichneten Striche
010   
011   public void loesche()   // löscht das Panel, indem alles weiß überstrichen wird
012   {
013     zahl = 0;
014     setBackground(Color.WHITE);
015     repaint();   // Systembefehl repaint ruft u.a. Methode paint zum Zeichnen auf
016   }
017   
018   public void nächsterStrich()
019   {
020     if (zahl<10)
021     {
022       zahl++;    // erhöht Anzahl der gezeichneten bzw. zu zeichnenden Striche
023       repaint(); // und ruft indirekt nachfolgende Zeichenmethode paint auf
024     }
025   }
026   
027   public int zahl()   // gibt auf Wunsch die Zahl der gezeichneten Striche aus
028   {
029     return (zahl);
030   }
031   
032 //  @Override    // kann verdeutlichen, dass eine JPanel-Methode überschrieben wird
033   public void paint (Graphics g) // erweitert Standard-Methode um Galgenmann-Striche
034   {
035     super.paintComponent(g); // übergeordnete Graphikmethode für Hintergrund, Ränder..)
036     Graphics2D g2d = (Graphics2D) g;
037     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
038       RenderingHints.VALUE_ANTIALIAS_ON);
039     g2d.setStroke(new BasicStroke(3 /*, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND */ ));
040     int h = getHeight();     // misst Höhe h und ..
041     int b = getWidth ();     // .. Breite b des Panels/Graphikfensters auf Oberfläche
042     
043     if (zahl > 4)            // ändert Zeichenfarbe fürs Männchen auf blau
044     {
045       g2d.setColor (Color.BLUE);  
046     }
047     else                     // während der Galgen und der Strick schwarz sind
048     {
049       g2d.setColor (Color.BLACK);  
050     }  
051   
052     switch (zahl)
053     // Achtung: Alle Fälle ohne "break", damit auch jeweils alle früheren Teile 
054     // nochmal gezeichnet werden. Wichtig, falls Fenster durch anderes Programm
055     // verdeckt war. 
056     {
057       case 10:   setBackground(new Color(0xFFAFAF)); // farbiger Hintergrund signalisiert Ende
058                  g2d.drawLine ((int)(8*b/11.0),(int)(9.0*h/17.0),
059                    (int)(9.0*b/11.0),(int)(14.0*h/17.0));  // re. Bein  
060                       
061       case  9:   g2d.drawLine ((int)(8.0*b/11.0),(int)(9.0*h/17.0),
062                    (int)(6*b/11.0),(int)(14.0*h/17.0)); // li. Bein  
063                            
064       case  8:   g2d.drawLine ((int)(7.3*b/11.0),(int)(6.0*h/17.0),
065                    (int)(10.0*b/11.0),(int)(9.5*h/17.0));  // re. Arm  
066         
067       case  7:   g2d.drawLine ((int)(7.3*b/11.0),(int)(6.0*h/17.0),
068                    (int)(5.0*b/11.0),(int)(10.0*h/17.0));  // li. Arm  
069         
070       case  6:   g2d.drawLine ((int)(7.0*b/11.0),(int)(5.0*h/17.0),
071                    (int)(8.0*b/11.0),(int)(9.0*h/17.0));   // Rumpf  
072     
073       case  5:   g2d.drawArc ((int)(5.0*b/11.0),(int)(4.0*h/17.0),
074                    (int)(2.0*b/11.0),(int)(2.0*h/17.0),0,360);  // Kopf
075       
076       case  4:   g2d.setColor (Color.BLACK);         // Zeichenfarbe für Galgen und Seil
077                  g2d.setStroke(new BasicStroke(1));  // Seil wird dünner gezeichnet
078                  g2d.drawLine((int)(7.0*b/11.0),(int)(1.0*h/17.0),
079                    (int)(7.0*b/11.0),(int)(5.0*h/17.0));   // Seil        
080         
081       case  3:   g2d.setStroke(new BasicStroke(3));   // breitere Strichstärke für Galgen
082                  g2d.drawLine((int)(1.0*b/11.0),(int)(3.0*h/17.0),
083                    (int)(3.0*b/11.0),(int)(1.0*h/17.0));   // Galgen-Aussteifungs-Schräge  
084               
085       case  2:   g2d.drawLine((int)(1.0*b/11.0),(int)(1.0*h/17.0),
086                    (int)(8.0*b/11.0),(int)(1.0*h/17.0));   // Galgen-Arm (horizontaler Ausleger) 
087         
088       case  1:   g2d.drawLine((int)(1.0*b/11.0),(int)(16.0*h/17.0),
089                    (int)(1.0*b/11.0),(int)(1.0*h/17.0));   // Galgen-Vertikale
090         
091     } // end of switch    
092   }
093 }
 

Die Mehrfach-Verzweigung switch..case wurde extra absteigend angelegt und ohne break geschrieben, damit bei jeder (Strich-) zahl immer auch alle vorangegangenen Striche mit niedrigerer Nummer nochmal gezeichnet werden, damit nie etwas fehlt, wenn das Bild zwischenzeitlich von einem anderen Programm verdeckt war.

In Zeile 39 könnte beim Einstellen der Strickdicke mit setStroke auch die Form des Zeichenwerkzeugs und die Art der Verbindung aneinander stoßender Linien gewählt werden. Die Standardeinstellungen bewähren sich aber, sodass zusätzliche Parameter wieder auskommentiert wurden. Auch die Zeilen 37 und 38 wären bei dieser einfachen Zeichnung wohl entbehrlich: bei schrägen Linien soll damit die sonst eventuell etwas stärker sichtbare Treppenstruktur reduziert werden.

Und natürlich könnte der jetzt auf zwei Zeilen verteilte Befehl setRenderingHint in den Zeilen 37 und 38 ebenso in eine Zeile geschrieben werden wie alle drawLine-Befehle in der Mehrfach-Verzweigung.




zum Seitenanfang / zum Seitenende



b) Grafik durch Anzeigen vorgefertigter Bilder

Wer sich nicht mit Koordinaten und dem drawLine-Befehl beschäftigen will, kann alternativ das Galgenmännchen auch ganz anders darstellen. In einem beliebigen Mal- oder Zeichen-Programm wird das Galgenmännchen einfach Strich für Strich gezeichnet und nach jedem Strich das Bild unter einem neuen Dateinamen gespeichert. Wer mit einem geeigneten Grafikprogramm vertraut ist, kann so einigermaßen schnell und ohne langes Nachdenken eine Bilderserie erzeugen (am besten wird die Bildgröße genau passend zur Größe des Panels galgen in Zeile 112 von Klasse 1 gewählt!). Die Bilder könnten etwa wie folgt aussehen, wobei auch ein leeres Bild gespeichert wurde und das letzte Bild andere Farben hat, um auf das Ende der Buchstaben-Abfrage hinzuweisen.

Bildschirmfoto: Windows-Explorer zeigt Serie von 11 Galgen-Bildern



Weiterhin ist es vorteilhaft, die Bilder fortlaufend zu nummerieren, statt Dateinamen wie "eins.gif", "zwei.gif",.. oder .. "mit_linkem_Bein.gif", "mit_rechtem_Bein.gif",.. zu verwenden. Mit Nummer kann nämlich im Programmtext auf eine Mehrfachauswahl verzichtet werden. Weil die Bilder schon vollständig sind, könnten die Fälle in einer switch..case-Anweisung sowohl aufsteigend wie absteigend notiert werden, müssten aber immer mit break abgeschlossen werden. Aber bei Dateinamen mit Nummer kann das Programm den richtigen Dateinamen mit immer der gleichen, einen Zeile 41 erzeugen:




001 import java.awt.*;
002 import javax.swing.*;
003 import javax.swing.event.*;
004 import javax.imageio.*;
005 
006 public class P9_A3b_Panel extends JPanel   // erweitert/ändert normales Java-JPanel 
007 // spezielles Grafik-Panel für die Galgenmann-Oberfläche zur Anzeige des Galgenmanns
008 // aus vorgefertigten Bildern -- 17.5.2018 & 2.2.2019  r-krell.de
009 {
010   int zahl = 0;   // Anzahl der bereits gezeichneten Striche
011   
012   public void loesche()   // löscht das Panel, in dem alles weiß überstrichen wird
013   {
014     zahl = 0;
015     setBackground(Color.WHITE);
016     repaint();   // Systembefehl repaint ruft u.a. Methode paint zum Zeichnen auf
017   }
018   
019   public void nächsterStrich()
020   {
021     if (zahl<10)
022     {
023       zahl++;    // erhöht Anzahl der gezeichneten bzw. zu zeichnenden Striche
024       repaint(); // und ruft indirekt nachfolgende Zeichenmethode paint auf
025     }
026   }
027   
028   public int zahl()   // gibt auf Wunsch die Zahl der gezeichneten Striche aus
029   {
030     return (zahl);
031   }
032   
033 //  @Override    // kann verdeutlichen, dass eine JPanel-Methode überschrieben wird
034   public void paint (Graphics g) // erweitert Standard-Methode um Galgenmann-Bildanzeige
035   { 
036     if (zahl >=0 && zahl <= 10)
037     {
038       Image bild = null;    // kein Bild, falls fertiges Bild nicht gefunden wird 
039       super.paintComponent(g);
040       Graphics2D g2d = (Graphics2D) g;
041       String dateiname = "bilder/g_"+zahl+".gif";  // mit Name des Unterverzeichnis ..
042                                            // .. unter dem Ordner des Programmtextes
043       try
044       {
045         bild = ImageIO.read(getClass().getResource(dateiname));
046       }                                    // Befehl zum Holen des Bildes
047       catch (Exception ex)
048       {
049         System.out.println("** Grafikprobleme ["+dateiname+"]: "+ex);   // falls Bilddatei nicht .. 
050       }                                    // .. gefunden/geholt werden konnte
051       
052       if ( bild != null )
053       {
054         g2d.drawImage(bild, 00this );  // zeigt gefundenes Bild ab linker oberer Ecke (0|0) ..
055       }                                    // .. in diesem Panel ('this') an
056     }
057   }  
058 }
 

Die Zeilen 1 bis 34 sind natürlich genau wie bei der Variante a). Auch gilt alles dort gesagte zum Einsatz von repaint. Der Quelltext der Methode paint ist ohne switch..case kürzer; allerdings sieht man hier zusätzlich eine try..catch-Anweisung. Weil Java Dateioperationen wie das Holen von Bildern für besonders fehleranfällig hält - vielleicht wurde der Ordner mit den Bildern versehentlich gelöscht, wurde der USB-Stick mit den Dateien gar nicht eingesteckt, sind die Dateinamen doch anders oder wurden die Bilder in einem von Java nicht unterstützten Format abgespeichert - darf die Zeile 45 nicht einfach so hin hingeschrieben werden, sondern kann nur versuchsweise (im try-Block) ausprobiert werden. Wenn das Bild nicht geholt werden kann, springt das Programm in den catch-Block, hier zu einer Fehlermeldung. Ein erfolgreich geholtes Bild wird schließlich in Zeile 54 angezeigt (wobei drawImage aus Zeile 54 eigentlich auch direkt nach Zeile 45 im try-Block stehen könnte, was die if-Abfrage in Zeile 52 überflüssig macht).

Jetzt muss in der Klasse 1 nur noch die Zeile 37 (und der Titel in Zeile 51) auf _A3b_ abgeändert werden, und das Galgenmann-Spiel kann mit dieser Grafik gespielt werden.




zum Seitenanfang / zum Seitenende

 UML-Diagramm zum Zusammenspiel der Klassen



Das nachfolgende, mit dem Javaeditor erstellte UML-Diagramm verdeutlicht am Beispiel von P9_A3a nochmal den Zusammenhang zwischen den drei gerade vollständig vorgestellten Klassen. Der Javaeditor zeigt auch die Attribute an (hier f und galgen), die der Verknüpfung der Klassen durch Kompositionen dienen, und hebt sie sogar fett hervor. Normalerweise werden aber die von Java bzw. Swing mitgelieferten Oberklassen JFrame und JPanel nicht dargestellt; sie wurden hier extra angedeutet.

Bildschirmansicht: Javeeditor mit UML-Diagramm von P9_A3a


zum Seitenanfang / zum Seitenende

 Ausprobieren von P9_A3a und P9_A3b



Zum Ausprobieren biete ich die beiden lauffähigen, spielbaren Galgenmann-Programme an, jetzt in der Version vom Februar 2019. Das Aussehen von P3_A3a kennen Sie ja bereits vom Anfang dieser Seite; die andere Version sieht fast genau so aus. Es lässt sich am fertigen Programm nicht ohne Weiteres erkennen, wie die Grafik erzeugt wird.

Wenn Ihr Browser das zulässt (und Sie die Java-JRE 1.5 oder höher installiert haben - es muss hier nicht die allerneueste Fassung sein), können Sie jedes der beiden Programme direkt hier aus dem Browser heraus starten ("Webstart"). Gibt es Probleme oder wollen Sie Galgenmännchen auch unabhängig vom Besuch dieser Webseite spielen, empfiehlt sich das Herunterladen der jar-Datei(en). Der Download sollte immer gelingen. Bei installierter JRE können Sie die herunter geladene (=gespeicherte) jar-Datei später auf Ihrem Computer per Doppelklick ausführen und so das Galgenmännchen spielen.

[Die kostenlose, aktuelle JRE (Java Runtime Environment; Java Ausführungs-Umgebung) erhalten Sie immer direkt von Oracle (https://java.com/de/download/, wo im Februar 2019 die auch für 64-Bit-Betriebssysteme völlig ausreichende und empfohlene 32-Bit-Version 1.8 bzw. "Version 8 Update 201" von Mitte Januar 2019 angeboten wurde), oder - nicht immer ganz so aktuell - auch von den Webseiten vieler Computerzeitschriften, wie etwa vom PC-Magazin)].




Neue Versionen
vom Februar 2019
Webstart
(jnlp-Datei nicht speichern/herunterladen, sondern mit dem Launcher öffnen und Risiko akzeptieren zum Ausführen)
Download
(jar-Datei auf den eigenen Rechner herunter laden und dort später ausführen) *)
Wort-Raten mit Java-Grafik Webstart   P9_A3a_Galgenmann.jnlp P9_A3a_Galgenmann(r-krell.de).jar   (12kB)
Wort-Raten mit DiaShow Webstart   P9_A3b_Galgenmann.jnlp P9_A3b_Galgenmann(r-krell.de).jar   (35kB)

*) Achtung: Manche Browser (wie etwa MS Edge) verändern beim Download einer .jar-Datei deren Endung automatisch und ungefragt in .zip. Sollte das bei Ihnen passieren, müssen Sie die Endung (trotz Warnung) erst wieder in .jar ändern. Durch das Umbenennen wird die Datei keineswegs unbrauchbar, sondern ist im Gegenteil erst dann wieder durch Doppelklick auf den Dateinamen ausführbar. Voraussetzung für den Programmstart per Doppelklick ist eine installierte Java-Laufzeitumgebung (JRE).

zum Seitenanfang / zum Seitenende


zurück zur Informatik-Hauptseite

zurück zur vor-vorigen Seite (Programme P1 bis P4)  Seite b1)_2017
zurück zur vorigen Seite (Programme P5 bis P9)  Seite b2)_2017
weiter zur nächsten Seite (Programme P10 bis P12)  Seite b4)_2018


zum Anfang dieser Seite
Willkommen/Übersicht  -  Was ist neu?  -  Software  -  Mathematik  -  Physik  -  Informatik  -   Schule: Lessing-Gymnasium und -Berufskolleg  -  Fotovoltaik  -  & mehr  -  Kontakt: e-Mail,  News-Abo, Gästebuch, Impressum  -  Grußkarten, site map, Download und Suche

Diese Seite ist Teil des Webangebots http://www.r-krell.de.