C++

Einleitung

In der folgenden Facharbeit werden ich ein wenig auf die Geschichte der Programmiersprachen, ihren Aufbau und ihre Verwandtschaft zueinander eingehen. Dabei werde ich mich vor allem auf die, im professionellen Bereich am meisten verbreitete Programmiersprache C / C++ konzentrieren. Anschlie├čend werde ich anhand eines Beispiel Programms den Vorgang der Programmierung in der Praxis erl├Ąutern und die Probleme beschreiben die dabei auftreten k├Ânnen. Mein Praktikum, welches ich bei der Stadt Bielefeld in der Abteilung f├╝r Technikunterst├╝tzte Informationsverarbeitung (TuI) im Neuen Rathaus verbracht habe werde ich dabei nicht ber├╝cksichtigen, da mein T├Ątigkeitsbereich dort sehr eingeschr├Ąnkt war. Die einzigen Aufgaben, die mir zugeteilt wurden, waren meist PCs oder PC-Zubeh├Âr vom Lager in ein B├╝ros zu bringen oder umgekehrt. Des weiteren durfte ich einmal einen Schaltschrank zusammenschrauben, bei zwei PCs die Festplatten formatieren und noch in einer Au├čenstelle PCs verkabeln. Insgesamt l├Ąsst sich sagen das mindestens f├╝nfzig Prozent der Zeit in der ich dort war nichts zu tun war, das lag daran, dass zu diesem Zeitpunkt mehrere Leute wegen Krankheit ausgefallen waren. Deshalb fand ich das Praktikum zeitweise etwas Langweilig, aber da ich dort einen PC zur Verf├╝gung gestellt bekommen habe, ├╝ber den ich die zwei Wochen frei verf├╝gen konnte hielt sich die Langeweile in Grenzen. Die Zeit, in der nichts zu tun war, verbrachte ich damit, meine Programmierkenntnisse etwas zu vertiefen. So habe ich w├Ąhrend, dieser zwei Wochen eine Menge ├╝ber das Programmieren in C erfahren, beziehungsweise mir selbst beigebracht. Des weiteren habe ich noch etwas ├╝ber das St├Ądtische Netzwerk gelernt, ├╝ber die Funktionsweise, Probleme und die Absicherung f├╝r den Datenschutz. Doch um darauf n├Ąher einzugehen, fehlt mir das erforderliche Fachwissen, da ich w├Ąhrend meiner Praktikums Zeit nur einen kleinen Einblick in diesen Themenkomplex bekommen habe. Am vorletzten Tag des Praktikums hatte ich dann die M├Âglichkeit, mit einem der dortigen "Programmierer" zu sprechen. Zu meiner Entt├Ąuschung stelle ich fest, dass sich die Aufgaben f├╝r den Programmierer dort praktisch nur auf den Bereich der Fehlerbehebung beziehen. Die Programmierer dort programmieren nahezu keine Anwendungen selbst, sondern passen nur gegebene Programme an die jeweiligen Aufgabenbereiche an oder korrigieren Fehler in bestehenden Programmen. Die dort eingesetzte Programmiersprache stellt COBOL dar. Au├čerdem werden dort noch einige Programmteile in Assembler geschrieben. Des weiteren wird noch teilweise Access, ein speziell f├╝r die Verwaltung von Datenbanken ausgelegtes Programm eingesetzt. Mit COBOL werden die Programme geschrieben bzw. ver├Ąndert die im st├Ądtischen Netzwerk betrieben werden. Access wird im Gegensatz zu COBOL jedoch nur als Einzelplatz Anwendung eingesetzt, da es mehr Speicherplatz verbraucht und somit nicht so gut als Netzwerk Anwendung geeignet ist.

Programmiersprachen

Programmiersprachen sind Sprachen, die dazu dienen, Anwendungen auf dem Computer zu erstellen. Da ein Computer nur die Maschinensprache versteht, die von Maschine zu Maschine unterschiedlich ist. Die eigentliche Maschinensprache ist extrem schwer bis gar nicht zu verstehen, deshalb wurde die Sprache Assembler entwickelt. Assembler ist eine Programmiersprache, die jedem Maschinenbefehl einen entsprechenden symbolischen Namen gibt, so werden die Maschinenbefehle leichter verst├Ąndlich. Ein Beispiel f├╝r Assembler siehe ungef├Ąhr so aus:

mov ax, 0x0e07
xor bx, bx
int 0x10

Der so entstandene Quell Code kann jedoch nicht ausgef├╝hrt werden, sondern muss erst in Maschinensprache umgewandelt werden. Dazu gib es im wesentlichen zwei Wege, einmal den Weg ├╝ber einen Compiler, andererseits den Weg ├╝ber den Interpreter. Der Interpreter setzt dabei den Quell Code in Echtzeit in die Maschinenbefehle um und erm├Âglicht so das direkte ausf├╝hren des Quell Codes mit Hilfe des Interpreters ohne l├Ąngere Wartezeiten und ist so n├╝tzlich, um kleinere Probleme zu finden und zu beheben. Der Compiler geht einen ├Ąhnlichen Weg, nur setzt er den Quell Code nicht in Echtzeit um, sondern ├╝bersetzt den Quell Code zuerst komplett in Maschinen Sprache.

Der Weg, den der Compiler dabei geht f├╝hrt oft vorher ├╝ber einen Precompiler (C, C++), dieser sorgt daf├╝r, dass statt Symbolischen Konstanten die entsprechenden Zahlen gesetzt werden und das Makros entsprechend eingesetzt werden, au├čerdem werden hierbei noch die Kommentare im Quell Code entfernt. Der so vorbearbeitete Quell Code wird nun an den Compiler ├╝bergeben.

Der Vorteil von Assembler liegt darin, dass jedem Befehl im Quell Code genau ein Maschinenbefehl zugeordnet ist und so die ├ťbersetzung extrem leicht f├Ąllt. Ein zweiter Vorteil von Assembler ist, dass man damit extrem Maschinen Nah programmieren kann, was die Voraussetzung f├╝r schnelle Programme ist. Der Nachteil an Assembler liegt in der Portabilit├Ąt, das hei├čt Assembler Programme k├Ânnen nur auf einem bestimmten Rechnertyp laufen. H├Âhere Programmiersprachen, z.B. C/C++, gehen einen anderen Weg. Sie sind nicht so konzipiert, dass sie jedem Maschinenbefehl genau ein Kommando gegen├╝berstellen, sondern arbeiten mit abstrakteren Befehlen, die im allgemeinen leichter verst├Ąndlich sind. Ein ber├╝hmtes Beispiel Programm in C w├Ąhre:

#include <stdio.h>
> main () {
printf ("hello, world\n");
}

Dieses Programm w├╝rde den Text hello, world auf den Bildschirm schreiben.

Im wesentlichen bestehen alle modernen Programmiersprachen im wesentlichen aus zwei Bestandteilen, Variablen und Funktionen. Einige Programmiersprachen unterscheiden noch zwischen Funktionen und Prozeduren, aber in C gibt es zwischen ihnen keinen wesentlichen Unterschied. Eine Variable ist ein Objekt, welches je nach Klassifizierung den Wert einer Ganzzahl (Integer), Kommazahl (Float), eines Buchstabens (Char) oder eines Wortes (String) annehmen kann, unter Umst├Ąnden stehen jedoch noch mehr Typen zur Klassifizierung zur Verf├╝gung. Meist m├╝ssen Variablen erst definiert werden, um sp├Ąter im Programm benutzt werden zu k├Ânnen. Au├čerdem steht meist noch die M├Âglichkeit zur Verf├╝gung Datenfelder (auch Array oder Vector genannt) zu definieren, diese bieten die M├Âglichkeiten sozusagen eine Tabelle zu erstellen, bei der man ├╝ber die Angabe von Koordinaten auf die einzelnen Felder zugreifen kann, im Gegensatz zu einer normalen Tabelle k├Ânnen die Datenfelder meist jedoch nicht nur in 2 Dimensionen, sondern in beliebig vielen Dimensionen definiert werden.

Eine Funktion oder eine Prozedur ist ein Unterprogramm, welches eine bestimmte Aufgabe erf├╝llen soll, zum Beispiel in dem obigen Programm, erf├╝llt die Funktion printf, die Aufgabe die Zeichenkette hello, world in die Standard Ausgabe (hier der Bildschirm) zu schreiben. In anderen Programmiersprachen w├Ąre printf eine Prozedur, da es nur zur Ausgabe auf den Bildschirm f├╝hrt. Eine Funktion w├Ąre ein Unterprogramm, das ein Resultat liefer, zum Beispiel:

a = wurzel (4);

In diesem Fall w├╝rde a den Wert 2 annehmen, da die Funktion wurzel als Resultat die Wurzel aus 4 h├Ątte. In diesem Fall ist es deutlich, dass wurzel eine Funktion sein muss, jedoch ist auch printf eine Funktion, da sie als Resultatwert die L├Ąnge der Zeichenkette liefert. Dieses ist ein Vorteil von C gegen├╝ber anderen Programmiersprache, wie zum Beispiel BASIC oder PASCAL. Der Resultatwert wird oft benutzt um Fehler anzuzeigen, in diesem Fall nimmt er meist den Wert -1 an, oder um Werte f├╝r den weiteren Programmverlauf zu liefern, wie zum Beispiel printf die L├Ąnge der Zeichenkette liefert.

Ein weiterer wichtiger Bestandteil von Programmiersprachen ist die if Abfrage, diese f├╝r eine Anweisung aus wenn eine Bedingung erf├╝llt ist. Es gibt zudem die M├Âglichkeit alternative Anweisungen bereitzustellen mit else oder die alternative Anweisung nochmals von einer Bedingung abh├Ąngig zu machen mit elseif. In einigen Programmiersprache kommt nach der Bedingung ein then, bei C ist dieses jedoch unn├Âtig, da die Bedingung in Klammern steht.

/* C: */
if (Bedingung)
Anweisung;
elseif (Bedingung)
Anweisung;
else
Anweisung;
REM BASIC:
IF Bedingung THEN
Anweisung
ELSEIF Bedingung THEN Anweisung
ELSE Anweisung
ENDIF

Ein weiterer wichtiger Teil von Programmiersprachen sind Schleifen, diese bewirken, dass eine Reihe von Kommando so lange ausgef├╝hrt werden bis eine Bedingung war wird oder so lange eine Bedingung war bleibt. Au├čerdem gibt es noch eine Art von Schleifen (meist FOR - Schleife genannt) die ein Variable nach einem vorgegebenen Muster ver├Ąndern bis eine Bedingung erf├╝llt ist.

Geschichte von C

C entstand Anfang der siebziger Jahre in Zusammenhang mit dem Betriebssystem UNIX an den AT&T Bell Laboratories. Als Hauptentwickler der Programmiersprache gelten Dennis Ritchie und Brian W. Kernighan. Einige Ideen wurden dabei aus der Programmiersprache BCPL von M. Richards ├╝bernommen. Unmittelbarer Vorg├Ąnger von C ist das von K. Thompson 1970 im Zusammenhang mit der UNIX Entwicklung entstandene B. Des weiteren gingen noch Konzepte von ALGOL 60 und von ALGOL 68 in die Programmiersprache C ├╝ber. 1983 richtete das American National Standards Institute (ANSI) eine Kommission mit dem Ziel ein, eine eindeutige und Maschinen unabh├Ąngige Definition der Sprach C zu erarbeiten. Das Ergebnis dieser Arbeit war der ANSI - Standart f├╝r C. Dieser Standard definiert C nun eindeutiger und pr├Ąziser. Au├čerdem enth├Ąlt der Standard nun neue Definitionen f├╝r den Aufruf von Funktionen.

C stellt im Gegensatz zu den ersten h├Âheren Programmiersprache FORTRAN, ALGOL 60 (wissenschaftliche - technische Berechnung) und COBOL (kommerzielle Anwendungen) eine universell nutzbare Programmiersprache zur dar. Der Sprachumfang von C ist dagegen im Gegensatz zu ALOG 68 stark begrenzt, stellt jedoch eine ungeheure Flexibilit├Ąt zur Verf├╝gung. Es ist in C m├Âglich sowohl Maschinen nah zu programmieren, als auch portable, das hei├čt Maschinen unabh├Ąngige, Programme zu schreiben.

C++, der "Nachfolger" von C, wurde ebenfalls in den AT&T Bell Laboratories entwickelt. Die Hauptrolle bei der Entwicklung spielte Bjarne Stroustrup. C++ erweitert die M├Âglichkeiten von C f├╝r objektorientierte Programmierung.

Programmbeispiel

Soweit zur Theorie. Nun werde ich anhand eines kleinen Computer Spieles die Anwendung einer Programmier Sprache zeigen. Die verwendete Programmiersprache ist BASIC.

Das Spiel welches ich erstellen werde, basiert urspr├╝nglich auf dem Film Tron und ist f├╝r zwei Spieler gedacht. Es soll in etwa so aussehen, dass man einen Pixel (Punkt auf dem Bildschirm), im Film Tron war es ein Motorrad, steuern kann und dieser eine Linie hinter sich zeichnet. Diese Linie bildet ein Wand und wenn einer der Spieler auf die Wand trifft bekommt der Gegner einen Punkt und das Spiel startet von neuem. Das Geschehen sieht man dabei von oben ohne Scrolling, damit der Programmieraufwand m├Âglichst gering bleibt und die gr├Â├čte m├Âgliche ├ťbersicht gegeben ist. Weitere Eigenschaften des Spieles werde ich sp├Ąter genauer erl├Ąutern. Dieses kleine Spiel habe ich vor einigen Jahren schon einmal in BASIC programmiert. Am zweiten Tag des Praktikums war wenig zu tun und da ich dort einen Computer zur Verf├╝gung gestellt bekommen habe und dort Q-BASIC vorhanden war, habe ich dieses BASIC Programm erneut programmiert, um etwas Besch├Ąftigung zu bekommen. Des weiteren habe ich dieses Spiel in den n├Ąchsten Tagen noch leicht ver├Ąndert und optimiert. Da in den n├Ąchsten Tagen auch nicht besonders viel zu tun war, habe ich mir mit diesem Spiel und einem anderen Praktikanten, als zweiten Spieler, der dort die erste Woche war, die Zeit vertrieben.

Fangen wir also zuerst mal mit der Initialisierung des Grafik Bildschirms an, hierzu verwendet man das Kommando "SCREEN 12". Die Zahl gib den Grafik - Modus an, in diesem Fall 640*480 Pixel und 16 Farben. Nun wird die Steuerung erstellt, ich werde die gesamte weitere Programmierung nur anhand eines Spielers genauer erkl├Ąren, da beim zweiten Spieler nur leichte Modifikationen notwendig sind und ansonsten die gleichen Kommandos benutzt werden. Ich werde zwei verschiedene Steuermethoden integrieren, eine relative und eine absolute. Das soll hei├čen, der Spieler kann seinen Punkt mit 4 Tasten in die entsprechende Richtung steuern und bei der absoluten Steuerung kann man den Pixel mit 2 Tasten steuern, hierbei dient eine Taste f├╝r eine Rechts- bzw. F├╝r eine Linkskurve. Die Tasten werden dabei mit dem "INKEY$" Kommando abgefragt. Um die Taste abzufragen wird jetzt die erste Variable eingef├╝hrt, nennen wir sie "A$", ihr wird nun "INKEY$ zugewiesen. Das "$" Zeichen dient hier zur Kennzeichnung einer Zeichenketten - Variablen. Die Variable hat nun den Wert der gedr├╝ckten Taste auf der Tastatur. Um die Position des Punktes zu bestimmen werden jetzt noch die Variablen "X" und "Y" eingef├╝hrt. Um die Fahrtrichtung des Punktes zu bestimmen werden noch die Variablen "M" und "N" eingef├╝hrt, als Startwert f├╝r "N" wird -1 genommen, damit sich der Punkt nach oben bewegt, es sind zwei Variablen notwendig um einmal die Bewegung in X - Richtung und einmal die Bewegung in Y - Richtung zu kontrollieren. Damit sich die Koordinate des Pixel ver├Ąndert addiert man "M" zu "X" und "N" zu "Y". Damit der Punkt letztendlich auch auf dem Bildschirm zu sehen ist nimmt man noch das Kommando "PSET (X, Y), 4" damit ein Pixel auf dem Bildschirm erscheint, die Zahl "4" gibt die Farbe des Pixel an, in diesem Fall rot. Damit das Programm nicht nach der ersten Ausf├╝hrung abbricht wird noch eine Schleife eingef├╝hrt um das Programm fortlaufen zu lassen, bis die Taste "Q" gedr├╝ckt wird. Das Kommando " ' " dient zum einbringen von Kommentaren. Das Programm sieht zur Zeit so aus:

SCREEN 12 ' Initialisierung des Grafik Bildschirms
M = -1 ' Startwert f├╝r M
DO UNTIL A$ = "Q" ' Einleitung der Schleife
' sie wird fortgef├╝hrt bis "Q" gedr├╝ckt wird
A$ = INKEY$ ' Abfrage der Tastatur
X = X + M ' den Pixel in X - Richtung verschieben
Y = Y + N ' den Pixel in Y - Richtung verschieben
PSET (X, Y), 4' den Pixel auf den Bildschirm setzten
LOOP ' Ende der Schleife

Um die Abfrage f├╝r die Steuerung jetzt noch richtig zu integrieren habe ich das "SELECT CASE" Kommando genommen, damit ist es m├Âglich durch einen gegebenen Fall aus einer Menge m├Âglicher Kommandofolgen die richtige auszusuchen.

SELECT CASE A$ ' Einleitung der Auswahl
' relative Steuerung
CASE "w" ' oben
IF N <> 1 THEN N = -1 : M = 0
CASE "a" ' links
IF M <> 1 THEN N = 0 : M = -1
CASE "d" ' rechts
IF M <> -1 THEN N = 0 : M = 1
CASE "s" ' unten
IF N <> -1 THEN N = 1 : M = 0
' absolute Steuerung
CASE "y"
SELECT CASE m
CASE 1 'rechts
m = 0
n = -1
CASE -1 'links
m = 0
n = 1
CASE 0
SELECT CASE n
CASE -1 'oben
m = -1
n = 0
CASE 1 'unten
m = 1
n = 0
END SELECT
END SELECT
END SELECT

Dieser Programm Teil hat zur Folge, dass sich je nach gedr├╝ckter Taste der Pixel sich in die entsprechende Richtung bewegt. Die IF-THEN Abfrage bei der relativen Steuerung ist zwar nicht zwingend notwendig, aber verhindert in diesem Fall, dass der Punkt sich in die exakt gegen├╝ber gesetzte Richtung bewegen kann. Das ist notwendig da er sonst auf der schon gezeichneten Linie fahren w├╝rde und dieses hatte ein Kollision mit derselben zur Folge. Dieses bringt uns nun zur Kollisionsabfrage, im Augenblick k├Ânnte der Punkt sich zwar auf dem Bildschirm bewegen und gesteuert werden, doch er k├Ânnte noch nicht mit den W├Ąnden bzw. Linien kollidieren. Damit das Programm es merkt, wenn der Punkt mit einer Wand bzw. Linie kollidiert benutzte ich das "POINT" Kommando es liefert die Farbe der angegebenen Koordinate. Also m├╝sste die Zeile f├╝r die Kollisionsabfrage in etwa so aussehen:

IF POINT(X, Y) = 4 THEN
{Ereignis Folge}
END IF

Das hei├čt wenn der Pixel auf einen roten Punkt einer Linie trifft wird eine Ereignis Folge ausgel├Âst, die ich aber erst sp├Ąter genau beschreiben werden. F├╝r Test Phase kann man das "BEEP" Kommando dort einbauen, welches bewirkt, dass der PC kurz piept, so kann man gut nachpr├╝fen ob keine Fehler vorhanden sind. Ein Fehler den man zum Beispiel h├Ątte machen k├Ânnen w├Ąre das verwenden einer falschen Farbe, so w├Ąre der Pixel niemals kollidiert. Wichtig ist zudem, dass man die Kollisionsabfrage vor dem setzten des Pixel durchf├╝hrt, da sonst der Pixel jedes Mal kollidieren w├╝rde da er ja selber rot ist. Ist die Kollisionsabfrage jedoch korrekt gesetzt so wird erst gepr├╝ft ob schon ein Pixel auf der Position X Y vorhanden ist und wenn nicht dann wird ein neuer Pixel gesetzt und sonst eine Ereignis Folge ausgel├Âst. Damit der Pixel nicht au├čerhalb des Bildschirmes gelangen kann muss das Spielfeld entsprechend mit Linien begrenzt werden, diese m├╝ssen auch rot sein, damit die Kollisionsabfrage diese erfassen kann oder ansonsten m├╝sste man die Kollisionsabfrage entsprechend erweitern, wie man es f├╝r den zweiten Spieler tun muss, wenn er eine andere Farbe haben soll.

In dem jetzigen Stadium ist das Programm f├Ąhig ein Punkt ├╝ber den Bildschirm zu steuern und die Kollision von Punkt und Wand zu registrieren.

Nun werden ich die Ereignis Folge f├╝r die Kollisionsabfrage genauer beschreiben. Wenn der Punkt Kollidiert soll es eine kleine Explosion geben, der Punkte stand soll entsprechend ver├Ąndert werden und das Spiel soll wieder zu seiner Ausgangs Position zur├╝ck kehren und eine neue Runde soll beginnen.

Um die Explosion zu realisieren werde ich ein Unterprogramm schreiben, das hei├čt man kann durch den Aufruf des Unterprogramms die Explosion auf den Bildschirm zeichnen ohne dass man die Kommandos f├╝r die Explosion jedes Mal neu schreiben muss, so wird der Quell - Code leichter verst├Ąndlich und das Programmieren ist angenehmer denn so braucht man nur noch eine Zeile um eine Explosion zu bewerkstelligen und ohne dieses Unterprogramm brauchte man acht Zeilen. Das Unterprogramm w├╝rde dann so aussehen:

SUB Explo (EX AS INTEGER, EY AS INTEGER)
FOR R = 1 TO 40 STEP 1
CIRCLE (EX, EY), R, 2
CIRCLE (EX, EY), R/2, 10
NEXT R
FOR R = 0 TO 40 STEP 1
CIRCLE (EX, EY), R, 0
NEXT R
END SUB

Und ein Aufruf des Unterprogrammes so:

CALL Explo (X, Y)

Die oberste Zeile definiert den Namen des Unterprogrammes und welche Variablen bei einem Aufruf ├╝bergeben werden. In diesem Beispiel Aufruf sind es die Variablen X und Y, die die Koordinaten der Explosion angeben ihr Wert wird an die Variablen des Unterprogrammes EX und EY ├╝bergeben. Das Unterprogramm ist angesehen von diesen zwei Variablen v├Âllig unabh├Ąngig vom Rest des Programmes.

Die zweite Zeile von SUB Exlpo ( ) leitet eine FOR - Schleife ein, dass hei├č eine Variable, hier "R" wird von fortlaufend ver├Ąndert. In diesem Fall wird sie von 1 nach 40 ge├Ąndert und das mit einer Schrittweite (STEP) von 1, das hei├čt R nimmt die Werte 1, 2, 3, ..., 39, 40 an. Das "Circle" Kommando zeichnet einen Kreis mit Radius "R" und Farbe 2 (gr├╝n) bzw. Farbe 10 (hellgr├╝n). Beim zweiten "CIRCLE" ist der Radius R/2 damit die Mitte der Explosion heller ist als das ├äu├čere der selben und so einfach nur sch├Âner aussieht. Die zweite FOR - Schleife hat nur den Sinn die Gezeichnete Explosion wieder vom Bildschirm zu l├Âschen. Es wird zwar auch noch ein "CLS" (Clear Screen, Bildschirm l├Âschen) durchgef├╝hrt doch mit der zweiten FOR - Schleife wird ein sch├Ânere Effekt erzielt.

Damit w├Ąre CALL Exlpo (X, Y) das erste Kommando der Ereignis Folge bei einer Kollision, nun muss noch der Punkte stand des Gegners erh├Âht werden dazu werden die Variablen "P1" und "P2" benutzt, eine jeweils f├╝r den dazugeh├Ârigen Spieler. Nun m├╝ssen noch alle anderen Variablen ("X", "Y", "M", ...) wieder auf ihren Ursprungs Wert gesetzt werden. Dazu werden am Anfang des Programmes Konstanten definiert wie zum Beispiel "StartX", "StartY", usw. und die entsprechenden Variablen dann gleich dieser Konstanten gesetzt. Konstanten werden hier deshalb anstatt von Zahlen benutzt da man so ihre Werte sp├Ąter leichte ├Ąndern kann und so der Quell - Code leichter verst├Ąndlich wird.

Zwei weiter Unterprogramme werden jetzt noch ben├Âtigt eines um die Punktzahl auf dem Bildschirm anzuzeigen und eines um den Screen neu aufzubauen (Rechteck zum begrenzen des Spielfeldes zeichnen). Das erste Unterprogramm w├╝rde dann so aussehen:

SUB ShowScore (P1 AS INTEGER, P2 AS INTEGER)
LOCATE 1, 1: PRINT "PUNKTE ->",
PRINT "Player 1:"; P2,
PRINT "Player 2:"; P1
END SUB

Das Kommando "PRINT" schreibt den in Anf├╝hrungszeichen stehenden Text, ausgehend von der aktuellen Cursor Position, auf den Bildschirm. Mit dem "LOCATE" Kommando wird der Cursor auf die Entsprechende stelle gesetzt, in diesem Fall die linke - obere Ecke. Das Semikolon bewirkt das der Nachfolgende Text oder die Variable direkt an die letzte Textausgabe angeschlossen werden, ohne einen Zeilenumbruch wie er normalerweise entstehen w├╝rde. Das Komma bewirkt das selbe nur l├Ąsst es einen gr├Â├čeren Abstand. Das zweite Unterprogramm besteht praktisch nur aus f├╝nf Zeilen:

SUB SetScr
CLS
LINE (minX, minY)-(maxX, minY), 2
LINE (minX, minY)-(maxX, minY), 2
LINE (minX, minY)-(maxX, minY), 1
LINE (minX, minY)-(maxX, minY), 1
END SUB

Mit dem Kommando "LINE" kann man eine Linie von der einen angegebenen Koordinate zur anderen ziehen, die letzte Zahl gibt hier wieder die Farben an. Die Koordinaten sind hier wieder Konstante die am Anfang des Programmes Definiert werden, um sie einfacher ver├Ąndern zu k├Ânnen. Dass die Linien f├╝r den Rand verschiedene Farben habe hat keinen technischen Grund sondern ist einfach der Optik wegen.

Damit w├Ąre das Programm in etwa fertig, es m├╝sste nur noch die Steuerung und alles andere f├╝r den zweiten Spieler programmiert und noch einige ├änderungen bez├╝glich der Farbe vorgenommen werden.

Nachdem dieses geschehen ist das Programm betriebsbereit, aber noch nicht zwangsl├Ąufig Fehlerfrei. Deshalb ist es im Augenblick nur eine Beta Version, das hei├čt das Programm ist zwar fertig, aber kann noch Fehler haben und wird deshalb noch getestet. Die Alpha Phase habe ich in diesem Fall ├╝bersprungen, da sie praktisch w├Ąhrend des Programmieren ablief.

W├Ąhrend der Beta Phase stellten sich zwei wesentlich Fehler heraus, erstens waren die Spieler zwar in verschiedenen Farben, aber es war nicht immer genau klar wer nun eigentlich gewonnen hatte und zweitens war das Unterprogramm falsch im Quell - Text integriert, das bedeutete, dass bei jedem Programm Durchlauf die Punktzahl auf den Bildschirm geschrieben wurde. Der zweite Fehler war leicht zu beheben, der Aufruf f├╝r das Unterprogramm musste nur so plaziert werden, dass er nur am Ende einer Runde aufgerufen wird, da so nur die Punktzahl auf den Bildschirm geschrieben wird wenn sie sich ver├Ąndert, das hat zwar keinen richtigen Vorteil, macht das Spiel aber deutlich schneller und l├Ąsst es so auch auf langsameren PC lauf f├Ąhig und l├Ąsst dem Programmierer mehr Ressourcen frei f├╝r eventuelle Erweiterungen. Das erste Problem war von etwas anderer Natur, hier konnte man zwar den Gewinner der jeweiligen Runde an der Punktzahl ablesen, aber das erwies sich als unpraktikabel und so entschlo├č ich mich einfach die Farben f├╝r die Explosion abh├Ąngig zu machen vom Spieler der die Runde verloren hat. Au├čerdem entschied ich mich noch daf├╝r die Angabe der Punktzahlen den Farben der Spieler anzupassen. In der Praxis erwiesen sich diese ├änderungen als sehr n├╝tzlich und hilfreich.

Ein weiterer "Fehler" der sich in der weiteren Testphase heraus stellte war der, dass wenn sich die beiden Spieler aufeinander zu bewegen und einer dabei von oben bzw. unten und der andere von links bzw. rechts kommt und sie sich zum exakt gleichen Zeitpunkt treffen, sie durcheinander durch fahren und die Kollisionsabfrage scheitert. Dieses liegt daran, dass die beiden Punkte erst gezeichnet werden nachdem die Kollisionsabfrage und die Bewegung statt gefunden haben, da sie sich so beide auf dem gleichen Punkt befinden k├Ânnen, aber die Kollisionsabfrage nicht anspricht da die Pixel noch nicht gesetzt sind. Der Fehler lie├če sich zwar mit einem Koordinaten Vergleich oder einer umordnung der Programmaufrufe beheben, aber ich entschlo├č mich diesen "Fehler" bestehen zu lassen, da er nur sehr selten Auftritt, zu keiner unfairen Beeinflussung des Spieles f├╝hrt und mehr zur Erheiterung der Spieler beitr├Ągt, als dass er Schaden anrichtet.

Den kompletten Quell-Code zu diesem Q-BASIC Spiel gibt es hier.

Hi-Res
DECLARE SUB ShowScore (p1 AS INTEGER, p2 AS INTEGER)
DECLARE SUB Explo (ex AS INTEGER, ey AS INTEGER, Player AS INTEGER)
DECLARE SUB SetScr ()
DECLARE SUB Pause ()
COMMON x AS INTEGER
COMMON y AS INTEGER
COMMON x1 AS INTEGER
COMMON y1 AS INTEGER
COMMON m AS INTEGER
COMMON n AS INTEGER
COMMON m1 AS INTEGER
COMMON n1 AS INTEGER
COMMON SHARED a AS STRING
COMMON r AS INTEGER
COMMON p AS INTEGER
COMMON p1 AS INTEGER
COMMON Time AS SINGLE
CONST g = 20
CONST maxX = 639 - g
CONST maxY = 479 - g
CONST minX = 0 + g
CONST minY = 16 + g
CONST Farbe1 = 2
CONST Farbe2 = 1
CONST StartX = 300
CONST StartY = 240
CONST StartX1 = 340
CONST StartY1 = 240
CONST StartM = 0
CONST StartM1 = 0
CONST StartN = 1
CONST StartN1 = -1
CONST StartTime = 300
SCREEN 12
SetScr
CALL ShowScore(p, p1)
Time = StartTime
x = StartX
y = StartY
x1 = StartX1
y1 = StartY1
n = StartN
n1 = StartN1
Pause
DO UNTIL a$ = "q"
a$ = INKEY$
FOR za = 1 TO Time: NEXT za
Time = Time - .01
x = x + m
y = y + n
x1 = x1 + m1
y1 = y1 + n1
IF POINT(x, y) = Farbe2 OR POINT(x, y) = Farbe1 THEN
p = p + 1
CALL Explo(x, y, 1)
x = StartX
y = StartY
x1 = StartX1
y1 = StartY1
m = StartM
n = StartN
m1 = StartM1
n1 = StartN1
Time = StartTime
Pause
CLS
SetScr
CALL ShowScore(p, p1)
END IF
IF POINT(x1, y1) = Farbe2 OR POINT(x1, y1) = Farbe1 THEN
p1 = p1 + 1
CALL Explo(x1, y1, 2)
Pause
SetScr
CALL ShowScore(p, p1)
x = StartX
y = StartY
x1 = StartX1
y1 = StartY1
m = StartM
n = StartN
m1 = StartM1
n1 = StartN1
Time = StartTime
END IF
PSET (x, y), Farbe1
PSET (x1, y1), Farbe2
SELECT CASE a$
'Player 1
CASE "w"'(CHR$(0) + "H")' oben
IF n <> 1 THEN n = -1: m = 0
CASE "s"'(CHR$(0) + "P") 'unten
IF n <> -1 THEN n = 1: m = 0
CASE "d"'(CHR$(0) + "M") 'rechts
IF m <> -1 THEN n = 0: m = 1
CASE "a"'(CHR$(0) + "K") 'links
IF m <> 1 THEN n = 0: m = -1
CASE ("y")
SELECT CASE m
CASE 1 'rechts
m = 0
n = -1
CASE -1 'links
m = 0
n = 1
CASE 0
SELECT CASE n 'oben
CASE -1
m = -1
n = 0
CASE 1 'unten
m = 1
n = 0
END SELECT
END SELECT
CASE ("x")
SELECT CASE m
CASE 1 'rechts
m = 0
n = 1
CASE -1 'links
m = 0
n = -1
CASE 0
SELECT CASE n 'oben
CASE -1
m = 1
n = 0
CASE 1 'unten
m = -1
n = 0
END SELECT
END SELECT
'Player 2
CASE ("8") 'oben
IF n1 <> 1 THEN n1 = -1: m1 = 0
CASE ("5") 'unten
IF n1 <> -1 THEN n1 = 1: m1 = 0
CASE ("6") 'rechts
IF m1 <> -1 THEN n1 = 0: m1 = 1
CASE ("4")'links
IF m1 <> 1 THEN n1 = 0: m1 = -1
CASE ("1")
SELECT CASE m1
CASE 1 'rechts
m1 = 0
n1 = -1
CASE -1 'links
m1 = 0
n1 = 1
CASE 0
SELECT CASE n1 'oben
CASE -1
m1 = -1
n1 = 0
CASE 1 'unten
m1 = 1
n1 = 0
END SELECT
END SELECT
CASE ("2")
SELECT CASE m1
CASE 1 'rechts
m1 = 0
n1 = 1
CASE -1 'links
m1 = 0
n1 = -1
CASE 0
SELECT CASE n1 'oben
CASE -1
m1 = 1
n1 = 0
CASE 1 'unten
m1 = -1
n1 = 0
END SELECT
END SELECT

CASE ("c")
p = 0: p1 = 0:
Pause
SetScr
CALL ShowScore(p, p1)
x = StartX
y = StartY
x1 = StartX1
y1 = StartY1
m = StartM
n = StartN
m1 = StartM1
n1 = StartN1
Time = StartTime
END SELECT
LOOP
SUB Explo (ex AS INTEGER, ey AS INTEGER, Player AS INTEGER)
SELECT CASE Player
CASE 1
FOR r = 1 TO 40 STEP 1
CIRCLE (ex, ey), r, 2
CIRCLE (ex, ey), r / 2, 10
FOR za = 1 TO 10: NEXT za
NEXT r
CASE 2
FOR r = 1 TO 40 STEP 1
CIRCLE (ex, ey), r, 1
CIRCLE (ex, ey), r / 2, 9
FOR za = 1 TO 10: NEXT za
NEXT r
END SELECT
FOR r = 0 TO 40 STEP 1
CIRCLE (ex, ey), r, 0
FOR za = 1 TO 100: NEXT za
NEXT r
END SUB
SUB Pause
DO UNTIL (a$ = CHR$(13) OR a$ = "q" OR a$ = " ")
a$ = INKEY$
LOOP
END SUB
SUB SetScr
CLS
LINE (minX, minY)-(maxX, minY), 2
LINE (maxX, minY)-(maxX, maxY), 2
LINE (minX, minY)-(minX, maxY), 1
LINE (minX, maxY)-(maxX, maxY), 1
END SUB
SUB ShowScore (p1 AS INTEGER, p2 AS INTEGER)
COLOR 7: LOCATE 1, 1: PRINT "Punkte ->",
COLOR Farbe1: PRINT "Player 1:"; p2,
COLOR Farbe2: PRINT " Player 2:"; p1
END SUB

4679 Worte in "deutsch"  als "hilfreich"  bewertet