home *** CD-ROM | disk | FTP | other *** search
- PROGRAM objekte;
- {
- OBJEKT.PAS Objekt-Demonstrationsprogramm.
-
- Dieses Programm zeigt grafisch die Benutzung der objekt-orientierten
- Erweiterung von QuickPascal. Auf dem Bildschirm sehen Sie Bitabbil-
- dungen, die den Jogger und ein oder mehrere Hunde repräsentieren.
- Jedes Mal, wenn der Jogger mit einem Hund zusammentrifft, wird er
- gebissen; nachdem der Jogger mehrmals gebissen wird, gibt er auf.
- Sie können das Programm durch Betätigen der ESC-Taste beenden.
-
- OBJEKT.PAS deklariert zwei Objekttypen: Hase und Fuchs
- (eine Unterklasse von Hase).
- Der Jogger ist Hase und der Hund ist Fuchs.
- Verbunden mit dem Objekt Hase sind verschiedene Routinen (Methoden),
- die initialisieren, bewegen, zeichnen, und löschen; Geschwindigkeit
- setzen und die Richtung ändern; und Zusammenstöße registrieren.
- Diese Methoden treffen auf Jogger und Hunde zu. Zusätzlich haben
- die Fuchs-Objekte die Möglichkeit, die Richtung zu wechseln, wenn
- der Jogger an ihnen vorbeiläuft. Dies wird Jagd genannt.
-
- }
-
- {$M+} { Aktiviert Methodenprüfung. }
-
- USES
- MSGraph, Crt;
-
- CONST
- escape = Chr( 27 );
- ende_zaehler = 10;
- max_hund = 10;
- max_schritte = 300;
-
- { ============== Bitabbildungen für Farbe ======================= }
- { Mann läuft rückwärts }
- mann_r : ARRAY[1..376] OF Byte = (
- 21,0,31,0,0,0,0,1,224,0,1,224,0,1,224,0,0,0,0,3,
- 240,0,3,240,0,3,240,0,3,224,0,3,240,0,3,240,0,3,
- 240,0,7,224,0,6,240,0,6,240,0,7,240,0,7,224,0,7,
- 240,0,7,240,0,7,240,0,3,224,0,3,240,0,3,240,0,3,
- 240,0,3,224,0,3,224,0,3,224,0,3,224,0,1,224,0,1,
- 224,0,1,224,0,1,224,0,1,224,0,1,0,0,1,0,0,1,224,
- 0,1,224,0,0,224,0,0,224,0,1,224,0,7,240,0,4,112,
- 0,4,112,0,7,240,0,207,248,0,204,56,0,204,56,0,207,
- 248,0,223,252,0,216,28,0,216,28,0,223,252,0,255,
- 238,0,248,14,0,248,14,0,255,238,0,119,231,0,112,
- 7,0,112,7,0,119,231,0,39,238,0,32,14,0,32,14,0,
- 39,238,0,7,252,0,0,28,0,0,28,0,7,252,0,3,232,0,
- 0,8,0,0,8,0,3,232,0,0,0,0,0,0,0,3,224,0,3,224,0,
- 0,0,0,0,0,0,3,240,0,3,240,0,0,0,0,0,0,0,7,248,0,
- 7,248,0,0,0,0,0,0,0,15,252,0,15,252,0,30,30,0,30,
- 30,0,30,30,0,30,30,0,60,15,0,60,15,0,60,15,0,60,
- 15,0,56,7,128,56,7,128,56,7,128,56,7,128,28,3,128,
- 28,3,192,28,3,192,28,3,128,14,1,0,14,1,224,14,1,
- 224,14,1,0,6,0,0,7,3,192,7,3,192,6,0,0,0,0,0,31,
- 7,128,31,7,128,0,0,0,0,0,0,63,0,0,63,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0);
-
- { Mann läuft vorwärts }
- mann_v : ARRAY[1..376] OF Byte = (
- 21,0,31,0,0,0,0,0,120,0,0,120,0,0,120,0,0,0,0,0,
- 252,0,0,252,0,0,252,0,0,124,0,0,252,0,0,252,0,0,
- 252,0,0,126,0,0,246,0,0,246,0,0,254,0,0,126,0,0,
- 254,0,0,254,0,0,254,0,0,124,0,0,252,0,0,252,0,0,
- 252,0,0,124,0,0,124,0,0,124,0,0,124,0,0,120,0,0,
- 120,0,0,120,0,0,120,0,0,120,0,0,120,0,0,120,0,0,
- 120,0,0,120,0,0,0,0,0,0,0,0,120,0,0,248,0,0,152,
- 0,0,152,0,0,248,0,1,252,16,1,156,16,1,156,16,1,
- 252,16,3,254,48,3,142,48,3,142,48,3,254,48,7,127,
- 112,7,7,112,7,7,112,7,127,112,14,127,224,14,3,224,
- 14,3,224,14,127,224,7,127,192,7,1,192,7,1,192,7,
- 127,192,3,254,128,3,128,128,3,128,128,3,254,128,
- 1,124,0,1,0,0,1,0,0,1,124,0,0,0,0,0,0,0,0,124,0,
- 0,124,0,0,0,0,0,0,0,0,252,0,0,252,0,0,0,0,0,0,0,
- 1,254,0,1,254,0,0,0,0,0,0,0,3,255,0,3,255,0,7,135,
- 128,7,135,128,7,135,128,7,135,128,15,3,192,15,3,
- 192,15,3,192,15,3,192,30,1,192,30,1,192,30,1,192,
- 30,1,192,28,3,128,60,3,128,60,3,128,28,3,128,8,
- 7,0,120,7,0,120,7,0,8,7,0,0,6,0,60,14,0,60,14,0,
- 0,6,0,0,0,0,30,15,128,30,15,128,0,0,0,0,0,0,0,15,
- 192,0,15,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
-
- { Hund läuft rückwärts }
- hund_r : ARRAY[1..256] OF Byte = (
- 21,0,21,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,128,
- 0,1,128,0,0,0,0,0,0,0,0,192,0,0,192,0,0,0,0,0,0,
- 0,0,192,0,0,192,0,0,0,0,0,0,24,0,192,24,0,192,0,
- 0,0,0,0,0,24,0,192,24,0,192,0,0,0,0,0,0,28,0,192,
- 28,0,192,0,0,0,0,0,0,46,1,192,62,1,192,16,0,0,0,
- 0,0,255,255,192,255,255,192,0,0,0,0,0,0,255,255,
- 128,255,255,128,0,0,0,160,0,0,191,255,128,191,255,
- 128,0,0,0,64,0,0,95,255,128,95,255,128,0,0,0,0,
- 0,0,255,255,192,255,255,192,0,0,0,0,0,0,15,129,
- 224,15,129,224,0,0,0,0,0,0,13,193,240,13,193,240,
- 0,0,0,0,0,0,12,225,176,12,225,176,0,0,0,0,0,0,12,
- 113,160,12,113,160,0,0,0,0,0,0,12,225,160,12,225,
- 160,0,0,0,0,0,0,28,3,128,28,3,128,0,0,0,0,0,0,28,
- 3,128,28,3,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
-
- { Hund läuft vorwärts }
- hund_v : ARRAY[1..256] OF Byte = (
- 21,0,21,0,0,0,0,8,0,0,8,0,0,0,0,0,0,0,0,24,0,0,
- 24,0,0,0,0,0,0,0,0,48,0,0,48,0,0,0,0,0,0,0,0,48,
- 0,0,48,0,0,0,0,0,0,0,0,48,1,128,48,1,128,0,0,0,
- 0,0,0,48,1,128,48,1,128,0,0,0,0,0,0,48,3,128,48,
- 3,128,0,0,0,0,0,0,56,7,64,56,7,192,0,0,128,0,0,
- 0,63,255,240,63,255,240,0,0,0,0,0,0,31,255,240,
- 31,255,240,0,0,0,0,0,80,31,255,208,31,255,208,0,
- 0,0,0,0,32,31,255,160,31,255,160,0,0,0,0,0,0,63,
- 255,240,63,255,240,0,0,0,0,0,0,120,31,0,120,31,
- 0,0,0,0,0,0,0,248,59,0,248,59,0,0,0,0,0,0,0,216,
- 115,0,216,115,0,0,0,0,0,0,0,88,227,0,88,227,0,0,
- 0,0,0,0,0,88,115,0,88,115,0,0,0,0,0,0,0,28,3,128,
- 28,3,128,0,0,0,0,0,0,28,3,128,28,3,128,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0);
-
- { ============== Bitabbildungen für Monochrom =================== }
-
- { Mann läuft rückwärts }
- mann_r_m : ARRAY[1..37] OF Byte = (
- 21,0,11,0,0,112,0,0,248,0,0,112,0,195,255,0,102,
- 112,192,28,112,48,0,248,192,3,142,0,6,3,128,14,
- 3,0,0,0,0);
-
- { Mann läuft vorwärts }
- mann_v_m : ARRAY[1..37] OF Byte = (
- 21,0,11,0,0,224,0,1,240,0,0,224,0,15,252,48,48,
- 230,96,192,227,128,49,240,0,7,28,0,28,6,0,12,7,
- 0,0,0,0);
-
- { Hund läuft rückwärts }
- hund_r_m : ARRAY[1..37] OF Byte = (
- 21,0,11,0,4,0,32,252,0,48,236,0,48,252,0,48,31,
- 255,240,255,255,240,31,255,224,25,134,96,25,134,
- 96,59,142,224,0,0,0);
-
- { Hund läuft vorwärts }
- hund_v_m : ARRAY[1..37] OF Byte = (
- 21,0,11,0,64,2,0,192,3,240,192,3,112,192,3,240,
- 255,255,128,255,255,240,127,255,128,102,25,128,
- 102,25,128,119,29,192,0,0,0);
-
- TYPE
-
- Hase = object
- { Beispieldaten }
- bilder : ARRAY[1..2] OF POINTER;
- igroesse : Word; { Größe jeds Bitbildes }
- x, y : Word; { Position: ulhc }
- xe, ye : Word; { Ausdehnung }
- vx, vy : Integer; { Schnelligkeit }
- { Methoden }
- PROCEDURE initialisieren( groesse, xe, ye : Word );
- PROCEDURE bild_setzen( b1, b2 : POINTER );
- PROCEDURE geschw_setzen( vx, vy : Integer );
- PROCEDURE umdrehen;
- PROCEDURE zeichnen;
- PROCEDURE bewegen( x, y : Word );
- PROCEDURE loeschen_obj;
- PROCEDURE steigern( xl, yt, xr, yb : Word );
- FUNCTION kollidiert( s : Hase ) : Boolean;
- PROCEDURE beenden;
- END; { Hase }
-
- Fuchs = object( Hase )
- PROCEDURE Jagd( x, y : Word );
- END;
-
- VAR
- hunde : ARRAY[1..max_hund] OF Fuchs;
- mann : Hase;
- wl, wr, { Maximum an Pixel - links, rechts }
- wt, wb : Word; { Maximum an Pixel - oben, unten }
- rFarbe : Word; { Randfarbe }
- verzoegern : Word;
-
- { ======================= Hase.initialisieren ======================
- Diese Prozedur initialisiert die Werte für die Hase-Objekte.
- }
-
- PROCEDURE Hase.initialisieren( groesse, xe, ye : Word );
- BEGIN
- self.igroesse := groesse;
- self.xe := xe;
- self.ye := ye;
- self.vx := 0;
- self.vy := 0;
- END;
-
- { ======================= Hase.bild_setzen ========================
- Diese Prozedur initialisiert die Bildpuffer für die Hase-Objekte
- mit deren Bitabbildungen.
- }
- PROCEDURE Hase.bild_setzen( b1, b2 : POINTER );
- BEGIN
- self.bilder[1] := b1;
- self.bilder[2] := b2;
- END;
-
- { ======================= Hase.geschw_setzen ======================
- Diese Prozedur zeichnet die Geschwindigkeit der Hase-Objekte auf.
- }
- PROCEDURE Hase.geschw_setzen( vx, vy : Integer );
- BEGIN
- self.vx := vx;
- self.vy := vy;
- END;
-
- { ======================= Hase.umdrehen ===========================
- Diese Prozedur wird aufgerufen, wenn ein Hase-Objekt die Richtung
- wechseln muß. Der Jogger wechselt die Richtung nur, wenn er den
- Bildschirmrand erreicht. Die Hunde wechseln die Richtung, um den
- Jogger zu verfolgen.
- }
- PROCEDURE Hase.umdrehen;
- BEGIN
- self.loeschen_obj;
- self.vx := -self.vx;
- self.zeichnen;
- END;
-
- { ======================= Hase.bewegen ==========================
- Diese Prozedur bestimmt die Position des Hase-Objekts.
- }
-
- PROCEDURE Hase.bewegen( x, y : Word );
- BEGIN
- self.x := x;
- self.y := y;
- END;
-
- { ======================= Hase.zeichnen ===========================
- Diese Prozedur zeichnet ein Hase-Objekt auf dem Bildschirm an der
- aktuellen Position.
- }
-
- PROCEDURE Hase.zeichnen;
- VAR
- wi : Word;
- BEGIN
- { Hase geht vorwärts, wenn der X-Vektor positiv ist,
- sonst geht er rückwärts.
- }
- IF (self.vx > 0) THEN wi := 1 ELSE wi := 2;
- _PutImage( self.x, self.y, self.bilder[wi]^, _Gxor );
- END;
-
- { ======================= Hase.loeschen_obj ==========================
- Diese Prozedur loescht das Hase-Objekt und wird aufgerufen, wenn die
- Position auf den neusten Stand gebracht wird. Da zeichnen _Gxor,
- loeschen_obj benutzt, wird einfach der gleiche Hase an der aktuellen
- Position gezeichnet.
- }
-
- PROCEDURE Hase.loeschen_obj;
- BEGIN
- self.zeichnen;
- END;
-
- { ======================= Hase.steigern ===========================
- Diese Prozedur löschet den vorher gezeichneten Hasen, setzt eine
- neue Position und zeichnet den nächsten Hasen.
- }
-
- PROCEDURE Hase.steigern( xl, yt, xr, yb : Word );
- BEGIN
- self.loeschen_obj;
- Inc( self.x, self.vx );
- Inc( self.y, self.vy );
-
- { Richtung wechseln, falls nicht mehr genug Platz für einen anderen
- Hasen auf dem Bildschirm ist, der die gleiche Richtung benutzt.
- }
- IF ( self.x < xl) OR (self.x > (xr - self.xe)) THEN
- BEGIN
- self.vx := -self.vx;
- Inc( self.x, self.vx );
- END;
- IF (self.y < yt) OR (self.y > (yb - self.ye)) THEN
- BEGIN
- self.vy := -self.vy;
- Inc( self.y, self.vy );
- END;
- self.zeichnen;
- END;
-
- { ======================= Hase.kollidiert ==========================
- Diese Prozedur überprüft, ob zwei Hasen kollidierten.
- }
-
- FUNCTION Hase.kollidiert( s : Hase ) : Boolean;
- VAR
- x1, y1, x2, y2 : Word;
- { ======================= erweitern ==========================
- Diese Prozedur ergibt Wahr, falls Teile der Hasen überlappen.
- }
-
- FUNCTION erweitern( x, y : Word ) : Boolean;
- BEGIN
- erweitern := (x >= self.x) AND (x < (self.x + self.xe)) AND
- (y >= self.y) AND (y < (self.y + self.ye));
- END;
-
- BEGIN { Hase.kollidiert }
- x1 := s.x;
- y1 := s.y;
- x2 := s.x + s.xe - 1;
- y2 := s.y + s.ye - 1;
- kollidiert := erweitern( x1, y1 ) OR erweitern( x1, y2 ) OR
- erweitern( x2, y1 ) OR erweitern( x2, y2 );
- END;
-
- { ======================= Hase.beenden ==========================
- Diese Prozedur macht beim Programmende Speicher frei.
- }
-
- PROCEDURE Hase.beenden;
- BEGIN
- FreeMem( self.bilder[1], self.igroesse );
- FreeMem( self.bilder[2], self.igroesse );
- self.igroesse := 0;
- END;
-
- { ======================= Fuchs.Jagd ==========================
- Diese Prozedur wird für Fuchs-Objekte (Hunde) aufgerufen.
- Es korrigiert die Richtung, wenn ein Jogger vorbeiläuft.
- }
-
- PROCEDURE Fuchs.Jagd( x, y : Word );
- VAR
- nvx, nvy : Integer;
- BEGIN
- IF (x > self.x) THEN
- nvx := Abs( self.vx )
- ELSE
- nvx := -Abs( self.vx );
- IF (y > self.y) THEN
- nvy := Abs( self.vy )
- ELSE
- nvy := -Abs( self.vy );
- IF (nvx <> self.vx) THEN self.umdrehen;
- self.vx := nvx;
- self.vy := nvy;
- END;
-
- { ======================= geschwindgk ==========================
- Diese Funktion ergibt eine Geschwindigkeit in der bestimmten
- Grenze.
- }
-
- FUNCTION geschwindgk( min, max : Integer ) : Integer;
- VAR
- grenze, num : Word;
- BEGIN
- grenze := Abs( max - min );
- geschwindgk := max - Random( grenze );
- END;
-
- { ======================= initialisieren ==========================
- Diese Prozedur initialisieret Variablen und Grafikmodus ujnd
- zeichnet die ersten Objekte.
- }
-
- PROCEDURE initialisieren;
- VAR
- vidmodus : Integer;
- vidzeilen : Integer;
- vc : _VideoConfig;
- n : Word;
-
- BEGIN
-
- { initialisiert Zufallszahlengenerator. }
- Randomize;
-
- { Richtet Videoinformation ein }
- DirectVideo := False;
- vidmodus := _MaxResMode;
- vidzeilen := _SetVideoMode( vidmodus );
- _GetVideoConfig( vc );
- IF (vc.Mode = _EResNoColor) THEN
- BEGIN
- vidzeilen := _SetVideoMode( _DefaultMode );
- Writeln( 'Programm benötigt hochauflösenden Monochrom- oder '+
- 'CGA-Adapter' );
- Halt( 1 );
- END
- ELSE IF (vc.Mode = _EResColor) AND (vc.Memory = 64) THEN
- BEGIN { Setzt richtigen Modus für 64K EGA. }
- vidmodus := _HRes16Color;
- vidzeilen := _SetVideoMode( _HRes16Color );
- _GetVideoConfig( vc );
- END;
-
- { Setzt maximale Anzahl der Pixel für links, rechts, oben, unten
- und die Rundfarbe.
- }
- wl := 0;
- wr := vc.NumXPixels - 1;
- wt := vc.NumYPixels DIV vidzeilen + 1;
- wb := vc.NumYPixels - 1;
- rFarbe := vc.NumColors - 1;
-
- { Setzt Zeitverzögerung. }
- IF (vc.NumColors = 16) THEN verzoegern := 0
- ELSE verzoegern := 50;
-
- { Erstellt Bilder. }
- New( mann );
- IF (vc.NumColors = 16) THEN { Farb-Bitabbildungen benutzen }
- BEGIN
- mann.initialisieren( SizeOf( mann_v ), 20, 30 );
- mann.bild_setzen( @mann_v, @mann_r );
- END
- ELSE { Monochrom-Bitabbildungen benutzen }
- BEGIN
- mann.initialisieren( SizeOf( mann_v_m ), 20, 10 );
- mann.bild_setzen( @mann_v_m, @mann_r_m );
- END;
- mann.geschw_setzen( geschwindgk( -20, 20 ), geschwindgk( -10, 10 ) );
- mann.bewegen( Random( wr - 21 ) + 1,
- Random( ( wb - wt -30 ) - 1 ) + wt );
-
- { erstellt Hunde. }
- FOR n := 1 TO max_hund DO
- BEGIN
- New( hunde[n] );
- IF (vc.NumColors = 16) THEN { Farb-Bitabbildungen benutzen }
- BEGIN
- hunde[n].initialisieren( SizeOf( hund_v ), 30, 20 );
- hunde[n].bild_setzen( @hund_v, @hund_r );
- END
- ELSE { Monochrom-Bitabbildungen benutzen }
- BEGIN
- hunde[n].initialisieren( SizeOf( hund_v_m ), 20, 10 );
- hunde[n].bild_setzen( @hund_v_m, @hund_r_m );
- END;
- hunde[n].geschw_setzen( 3, 1 );
- END;
- END; { Prozedur initialisieren }
-
- { ======================= beenden ==========================
- Diese Prozedur setzt den Videomodus zurück.
- }
-
- PROCEDURE beenden;
- VAR
- vidzeilen : Integer;
- BEGIN
- vidzeilen := _SetVideoMode( _DefaultMode );
- END;
-
- { ======================= spiel ==========================
- Diese Prozedur macht die Hauptarbeit des Programms.
- }
-
- PROCEDURE spiel;
- VAR
- anzHunde : Word;
- n : Word;
- anzBiss : Word;
- anzSchritt : Word;
-
- BEGIN
- FOR anzHunde := 1 TO max_hund DO
- BEGIN
- { Spielbereich erstellen. }
- _ClearScreen( _GClearScreen );
- _SetColor( rFarbe );
- _Rectangle( _GBorder, wl, wt, wr, wb );
-
- { Anfangsposition zeichnen }
- mann.zeichnen;
- FOR n := 1 TO anzHunde DO
- BEGIN
- { Zufalls-Anfangsposition für Hunde auswählen. }
- hunde[n].bewegen( Random( wr - 31 ) + 1,
- Random( (wb - wt - 20) - 1) + wt );
- hunde[n].zeichnen;
- END;
-
- anzBiss := 0;
- FOR anzSchritt := max_schritte DOWNTO 0 DO
- BEGIN
- { Will Benutzer aufhören? }
- IF KeyPressed THEN
- IF (ReadKey = escape) THEN
- BEGIN
- GotoXY( 1, 1 );
- Write( 'Jogger gibt auf!' );
- Delay( 2000 );
- Exit;
- END; { beide IF-Anweisungen }
-
- { hunde.steigern - Jogger wird immer gebissen, wenn
- er mit einem Hund kollidiert.
- }
- FOR n := 1 TO anzHunde DO
- BEGIN
- IF mann.kollidiert( hunde[n] ) THEN
- BEGIN
- Inc( anzBiss );
- IF (anzBiss > ende_zaehler) THEN
- BEGIN
- GotoXY( 1, 1 );
- Write( 'Jogger entscheidet, einen anderen Sport zu wählen.' );
- Delay( 2000 );
- Exit;
- END;
- GotoXY( 1, 1 );
- Writeln( 'Autsch! Hund beißt Jogger.' );
- Delay( 500 );
- GotoXY( 1, 1 );
- Writeln( ' ' );
- END; { falls kollidiert }
- hunde[n].steigern( wl, wt, wr, wb );
- hunde[n].Jagd( mann.x, mann.y );
- END; { for n := 1 to anzHunde }
-
- { Jogger steigern. }
- mann.steigern( wl, wt, wr, wb );
- Delay( verzoegern );
- END; { for anzSchritt ... }
-
- { Jogger überlebt eine Runde. }
- GotoXY( 1, 1 );
- Write( 'Jogger überlebt ', anzHunde * 2,' Kilometer.' );
- Delay( 2000 );
- GotoXY( 1, 1 );
- Writeln( ' ' );
- END; { for anzHunde ... }
-
- { Jogger hat die "Schlacht" mit den Hunden überlebt. }
- GotoXY( 1, 1 );
- Writeln( 'Jogger erreicht Siegerland (weit nördlich des'+
- ' Allgäus)!');
- Delay( 2000 );
- GotoXY( 1, 1 );
- Writeln( ' ' );
- END;
-
- { =========================== Hauptprogramm =========================== }
-
- BEGIN
- initialisieren;
- spiel;
- beenden;
- END.
-
-
-
-