Freihandzeichnen und Pfeilwurf

Die Klasse Maus

Mit Hilfe der Klasse Maus wird die aktuelle Position und der Tastenzustand der Maus abgefragt. Wird eine Taste gedrückt (also eine Bedingung erfüllt) , erfolgt eine Anweisung.

Bedingungen

if (Maus.istGedrueckt()) Stift.hoch();

Sollen mehrere Anweisungen durchgeführt werden, so müssen diese in geschweiften Klammern eingeschlossen sein:

if (Bedingung.erfuellt)
{
Anweisung1;
Anweisung2;
Anweisung3;
}

if-Abfragen können auch geschachtelt werden, d.h. in einer if-Abfrage kann eine weitere Abfrage erfolgen. Man kann auch eine zweiseitige Bedingung angeben. Sollte die Bedingung nicht erfüllt werden, wird oder werden alternative Anweisungen durchgeführt.

if (Bedingung.erfuellt)
{
Anweisung1;
Anweisung2;
}
else
{
Anweisung3;
Anweisung4;
}

Bei geschachtelten Abfragen bezieht sich die else-Anweisung immer auf die letzte if-Abfrage. Im Zweifelsfalle muss man genügend Klammern setzen. Eine Bedingung kann auch verneint werden bzw. können auch mehrere Bedingungen verknüpft werden.

if (Maus.hPosition() == 300 ) && Maus.istGedrueckt())
Stift.bewegeBis(20,30);

Der Stift wird im obigen Beispiel nur bewegt, wenn beide Bedingungen erfüllt sind. == ist ein Vergleichsoperator und hat nichts mit dem Zuweisungszeichen = zu tun. && ist eine UND-Verknüpfung. Eine UND-Verknüpfung ist nur dann wahr, wenn beide Bedingungen wahr sind.

if ((Maus.hPosition() != 300 ) || meineMaus.istGedrueckt())
Stift.bewegeBis(20,30);

Der Stift wird im obigen Beispiel nur bewegt, wenn eine oder beide Bedingungen erfüllt sind. ! ist der Verneinungsoperator (NOT) und || steht für die ODER-Verknüpfung. Eine ODER-Verknüpfung ist nur wahr, wenn mindestens eine Bedingung wahr ist.

Schleifen

while (Bedingung.erfuellt)
{
Anweisung1;
Anweisung2;
}

Zu Beginn einer Schleife wird die Bedingung überprüft. Ist sie wahr werden die folgenden Anweisungen ausgeführt. Dies geschieht so lange, wie die Bedingung wahr ist. Ist sie nicht mehr wahr, wird die Schleife verlassen. Diese Form der Schleife ist also an die Eingangsbedingung gebunden. Es kann also sein, dass die Schleife überhaupt nicht ausgeführt wird. Eine andere Variante ist die Schleife mit Ausgangsbedingung. Hier wird die Schleife mindestens einmal ausgeführt. Weitere Durchläufe erfolgen, solange die Ausgangsbedingung nicht erfüllt ist.

do
{
Anweisung1;
Anweisung2;
}
while (Bedingung.erfuellt)

In den folgenden Beispielen werden wir diese Technik benutzen, um ein Programm solange auszuführen, bis es mit einem Doppelklick der Maus beendet wird.

do
{
Anweisung1;
Anweisung2;
}
while (!Maus.doppelKlick());

Beispiel Maus 1

Eine Linie auf dem Bildschirm folgt den Bewegungen der Maus. Das Programm wird durch einen Doppelklick der Maus beendet.

import basis.*;

public class maus1
{
Fenster f;
Stift s;
Maus m;

public maus1()
{
f = new Fenster(500,300);
s = new Stift();
m = new Maus();
}

public void fuehreAus()
{
while(!m.istGedrueckt())
{
s.bewegeBis(m.hPosition(),m.vPosition());
}
s.runter();
do
s.bewegeBis(m.hPosition(),
m.vPosition());
while (!m.doppelKlick());
}
}

 

Beispiel Maus 2

Mit einem Druck auf die Maustaste wird ein Punkt an der Mausposition gezeichnet. Das Programm wird durch einen Doppelklick der Maus beendet. Die Maustaste soll gedrückt gehalten werden und anschließend soll die Maus schnell eine kurze Strecke über den Bildschirm gezogen werden.

import basis.*;

public class maus2
{
Fenster f;
Stift s;
Maus m;

public maus1()
{
f = new Fenster(500,300);
s = new Stift();
m = new Maus();
}

public void fuehreAus()
{
do
{
s.bewegeBis(m.hPosition(),
m.vPosition());
if (m.istGedrueckt())
s.zeichneKreis(1);
}
while (!m.doppelKlick());
}
}

Beispiel Maus 3

Solange die Maustaste gedrückt ist, folgt eine Linie auf dem Bildschirm den Bewegungen der Maus. Das Programm wird durch einen Doppelklick beendet.

import basis.*;

public class maus1
{
Fenster f;
Stift s;
Maus m;

public maus1()
{
f = new Fenster(500,300);
s = new Stift();
m = new Maus();
}

public void fuehreAus()
{
do
{
s.runter();
while (m.istGedrueckt())
s.bewegeBis(m.hPosition(),
m.vPosition());
s.hoch();
while (!m.istGedrueckt())
s.bewegeBis(m.hPosition(),m.vPosition());
}
while (!m.doppelKlick());
}

Die Tastatur

Die Klasse Tastatur erkennt die eingegebenen Tastaturzeichen in der Reihenfolge ihrer Eingabe. Dazu werden die Zeichen intern in einem Puffer gespeichert. Dieser Puffer wird vom Programm ausgelesen. Es gibt eine Klasse namens Zeichen, welche z.B. die folgende Konstanten
als Tastatureingabe zur Verfügung stellt: ESCAPE, ENDE, POS1, PFEILLINKS usw.

import basis.*;

public class maus1
{
Fenster f;
Stift s;
Maus m;
Tastatur t;
public maus1()
{
f = new Fenster(500,300);
s = new Stift();
m = new Maus();
t = new Tastatur();
}

public void fuehreAus()
{
char ch;
s.bewegeBis(50,50);
do
{
if (t.wurdeGedrueckt())
{
ch = t.zeichen();
switch (ch)
{
case 'A' : s.schreibeText("Anton");break;
// Problem: Bei Eingabe des Großbuchstabens ‘A‘ wird auch die
// Shift-Taste als eigenes Zeichen interpretiert.
case Zeichen.PFEILRECHTS:
s.schreibeText("Pfeilrechts"); break;
default: s.schreibeText("unbekannt");
}
}
}
while (!m.doppelKlick());
}
}

Beispiel Tastatur 1

Der Rechner wartet auf Tastatureingaben. Es werden nur die 4 Pfeiltasten akzeptiert. Wird die Pfeilrechts-Taste gedrückt, so erscheint eine 50 Pixel lange Linie nach rechts. Analog wird bei den anderen Pfeiltasten reagiert. Das ganze wird solange durchgeführt, bis ein Mausdoppelklick erfolgt.

import basis.*;

public class maus1
{
Fenster f;
Stift s;
Maus m;
Tastatur t;
public maus1()
{
f = new Fenster(500,300);
s = new Stift();
m = new Maus();
t = new Tastatur();
}

public void fuehreAus()
{
char ch;
s.bewegeBis(f.breite()/2,
f.hoehe()/2);
s.runter();
do
{
if (t.wurdeGedrueckt())
{
ch = t.zeichen();
switch (ch)
{
case Zeichen.PFEILRECHTS:
    s.dreheBis(0);
    s.bewegeUm(50);
    break;
case Zeichen.PFEILLINKS:
    s.dreheBis(180);
    s.bewegeUm(50);
    break;
case Zeichen.PFEILOBEN:
    s.dreheBis(90);
    s.bewegeUm(50);
    break;
case Zeichen.PFEILUNTEN:
    s.dreheBis(270);
    s.bewegeUm(50);
    break;
}
}
}
while (!m.doppelKlick());
}
}

Beispiel Tastatur 2

Wie Aufgabe 1. Zusätzlich werden die Ziffer 1 und die Buchstaben h, r und v akzeptiert. Bei Eingabe der Ziffer 1 dreht sich der Stift um 10 Grad nach links, die Buchstaben h und r sorgen dafür, dass der Stift hoch gehoben bzw. runter gelassen wird. Der Buchstabe v bewirkt ein Vorwärtsgehen des Stiftes um 50 Pixel. Letzteres ist sinnvoll, falls der Winkel des Stiftes vorher geändert wurde.

...
case '1':s.dreheUm(10);break;
case 'h': s.hoch();break;
case 'r':s.runter();break;
case 'v':s.bewegeUm(50);break;
...

Projekt Pfeilwurf

Mit Hilfe des Stiftes wird eine Dartscheibe mit 4 farbigen Kreisen gezeichnet. Nun soll ein Pfeil von der linken Bildschirmseite her zur Scheibe fliegen. An einer gedachten Linie bleibt der Pfeil stehen. Beim Starten des Programms fällt der Pfeil zunächst von oben senkrecht nach unten. Mit einem Mausdruck wird der Pfeil abgefeuert. Einmal abgefeuert kann der Pfeil durch Drücken einer Maustaste seine Flugrichtung entgegen dem Urzeigersinn ändern. Wird das Zentrum getroffen, wird eine Meldung ausgegeben. Wenn der Spieler nicht aufpasst, läuft der Pfeil aus dem unteren Bildschirmrand heraus. In diesem Fall soll er wieder nach oben gesetzt werden.

import basis.*;

public class maus1
{
Fenster f;
Stift s;
Maus m;
Tastatur t;
TextBereich tf;
public maus1()
{
f = new Fenster(800,600);
s = new Stift();
m = new Maus();
}


public void fuehreAus()
{
int a=30;
zeichneZielscheibe();
s.bewegeBis(30,30);
s.dreheBis(30);
zeichnePfeil();
while (!m.wurdeGeklickt())
{
s.radiere();
zeichnePfeil();
s.bewegeBis(30,a);
a=a+1;
s.normal();
zeichnePfeil();
warte(10);
if (a==600) a=30;
}
pfeilFlieg();
}

private void pfeilFlieg()
{
do
{
s.radiere();
zeichnePfeil();
s.bewegeUm(1);
if (m.istGedrueckt()) s.dreheUm(2);
s.normal();
zeichnePfeil();
warte(10); // ungefähre Anzahl in Millisekunden
}
while (s.hPosition() <= 655);

if (((s.hPosition()>685) || (s.hPosition()<715)) && ((s.vPosition()>85)||(s.vPosition()<115)))
{
tf=new TextBereich(10,10,50,50);
tf.setzeText("Treffer");
}
}

private void zeichnePfeil()
{
s.runter();
s.bewegeUm(50);
s.dreheUm(150);
s.bewegeUm(3);
s.bewegeUm(-3);
s.dreheUm(-300);
s.bewegeUm(3);
s.bewegeUm(-3);
s.dreheUm(150);
s.bewegeUm(-50);
}

private void zeichneZielscheibe()
{
s.setzeFuellMuster(Muster.GEFUELLT);
s.bewegeBis(700, 100);
s.setzeFarbe(Farbe.BLAU);
s.zeichneKreis(90);
s.setzeFarbe(Farbe.GELB);
s.zeichneKreis(65);
s.setzeFarbe(Farbe.BLAU);
s.zeichneKreis(40);
s.setzeFarbe(Farbe.GELB);
s.zeichneKreis(15);
s.setzeFarbe(Farbe.SCHWARZ);
}
public void warte(long msec){
long startzeit=System.currentTimeMillis();
while(System.currentTimeMillis()-startzeit<msec);
}
}

Das programm verwendet die Methode warte. Der Inhalt ist eigentlich selbsterklärend. Neu ist die Verwendung eines Editors. Hier wird die Klasse TextBereich verwendet.