Aufgabenstellung

Chips Challenge

 

Im Sommersemester 2009 soll ein Klon des Spiels "Chip`s Challenge" erstellt werden. Das Originalspiel und eine kurze Anleitung, wie es zu benutzen ist, findet Ihr bei Takegame, weitere Informationen zur Historie des Spiels und weiterführende Links gibt es bei Wikipedia.

 

 

Kurzer Überblick:

Chip - der "Held" des Spiels - muß sich von Level zu Level durcharbeiten und dabei in jedem Level eine vorgegebene Zahl von Computerchips einsammeln, um das Zielfeld betreten zu können. Dabei gibt es diverse Gefahren wie Feuer- oder Wasserfelder und eine Menge verschiedener Monster, die Chip verfolgen und bei Berührung töten. Eisfelder, auf denen Chip ausrutscht, Laufbänder, die ihn automatisch in eine bestimmte Richtung bewegen, Teleporter und Fallen machen ihm dabei das Leben schwer. Hat er alle Level gelöst, darf er dem sagenumwobenen "Bit Buster Club" seiner Freundin Melinda beitreten :-)

Im Spiel kommen diverse verschiedene Feldtypen und Monster vor, die jeweils durch ein oder mehrere Bild(er) dargestellt werden. Die Monster können sich z.B. alle in zwei oder vier Richtungen bewegen und haben für diese Richtungen auch jeweils ein eigenes Bild und einen eigenen Konstantenwert im Aufzählungstyp, damit die interne Arbeit mit den Typen einfacher wird (s.u.). Sämtliche Feldtypen sind auf einer separaten Seite beschrieben. Die Bilder werden Euch ebenfalls zur Verfügung gestellt.

Konkret sollt Ihr das Spiel nahezu 1:1 nachbilden, allerdings gelten folgende Einschränkungen bzw. Abänderungen und Festlegungen:

  • benutzt bitte die mitgelieferten Bilder in der Originalgröße von 32x32 Pixeln, das weitere Aussehen des Formulars ist Euch freigestellt
  • vor dem Spiel soll der Benutzer 5 Level wählen können, die nacheinander zu lösen sind. Wurde das 1. Level gelöst, beginnt das 2., wurde dieses gelöst das 3. usw. Möchte der Benutzer ein oder mehrere Level überspringen, muß er (wie im Originalspiel) das entsprechende Paßwort kennen
  • mindestens diese 5 Level sind von Euch bei der Abgabe auch mitzuliefern! Dabei sollen möglichst jedes Feld und Monster mindestens in einem Level auftauchen
  • damit Ihr Euch voll auf das Spiel konzentrieren könnt, stelle ich Euch einen Leveleditor zur Verfügung. Die Bedienung sollte größtenteils intuitiv möglich sein, wenn man das Originalspiel kennt, ansonsten werft bitte einen Blick in die Online-Hilfe
  • damit Ihr die erstellten Leveldateien mit Eurem Spiel wieder korrekt einlesen könnt, müßt Ihr die unten im Abschnitt "Hilfe" gegebenen Typen benutzen!
  • alle Sorten von Eis- und Laufbandfeldern (Ice, IceRedirect* und ForceFloor*) sowie das Froschmonster (Frog*) müssen für den Pflichtteil NICHT umgesetzt werden (s. Zusatzteil)

Alles andere soll sich so weitestgehend am Originalspiel anlehnen, insbesondere die Anzeigegröße von 9x9 Feldern, die Steuerung, die Übersicht der eingesammelten Schuhe und Schlüssel und natürlich das Verhalten der Felder und Monster. Spielt am besten mindestens die ersten 15 Level des Originalspiels einmal durch, um ein Gefühl für das Spiel zu bekommen. Solltet Ihr dann zu bestimmten Feldern oder Monstern noch Fragen haben, dann stellt diese bitte per Mail an mich oder in der Newsgroup ptl.pascal oder schaut Euch die von mir jeweils genannten Beispiel-Level noch einmal an. Wenn Ihr im Originalspiel Strg+D drückt, könnt Ihr danach übrigens mit Strg+N und Strg+P durch alle Level springen, ohne daß Ihr die Paßwörter kennen müßt :-)

 

Freiwilliger Zusatzteil

Zusätzlich zu diesen Pflichtbestandteilen gibt es einen optionalen Zusatzteil, der von Euch zum Bestehen der Aufgabe NICHT zwingend bearbeitet werden muß. Ohne diesen ist allerdings im besten Fall eine 2.0 als Note möglich.

Für den Zusatzteil sollen nun auch die im Pflichtteil ausgelassenen Feld- und Monstertypen umgesetzt werden, also konkret Ice, IceRedirect*, ForceFloor* und Frog*. Der Spieler, alle Monster und Blöcke müssen sich auf den Eis- und Laufbandfeldern korrekt verhalten und der Frosch muß wie im Originalspiel jeweils den kürzesten Weg zum Spieler suchen und diesen entlanghüpfen - wenn er nicht durch Wände o.ä. versperrt wird.
Denkt bitte daran, in der Dokumentation unter "Problemanalyse und -realisation" und "Realisationsanalyse" darzulegen, wie Ihr diese Felder und den Frosch umgesetzt habt!

Hilfe

1)
Eine Leveldatei ist eine Textdatei (keine typisierte und keine ini-Datei) und hat den folgenden Aufbau:

<Levelname>
<Breite>,<Höhe>,<Zeit>,<Chips>,<Paßwort>
<Hilfetext>
(<2- oder 4buchstabiges Kürzel>,)*
<Verbindung>
<Verbindung>
<Verbindung>
...

Der Hilfetext kann leer sein, in dem Fall wird einfach eine Leerzeile eingefügt. Hat das Kürzel genau zwei Buchstaben, dann handelt es sich um einen der Feldtypen. Ist es vier Zeichen lang, dann geben die ersten beiden den Feldtyp und die zweiten beiden das Monster an, das sich auf diesem Feld befindet (der Spieler gilt hier auch als Monster). Ein FO wäre also ein leeres Floor-Feld, ein FOPL ist ein Floor-Feld, auf dem der Spieler steht. Mit "Verbindung" sind z.B. Teleporter oder rote Knöpfe gemeint, die eine Klonmaschine bedienen. Eine Verbindung hat immer das folgende Format:

<Verbindung> := <2buchstabiges Verbindugskürzel><Startkoordinaten>,<Zielkoordinaten 1>,
<Zielkoordinaten 2>,<Zielkoordinaten 3>,<Zielkoordinaten 4>

Alle Koordinaten bestehen dabei aus einem x- und einem y-Anteil, getrennt durch einen "/". Nur Teleporter können mehr als ein Zielkoordinatenpaar haben, bei Knöpfen ist z.B. immer nur das erste Paar gesetzt. Nicht gesetzte Koordinaten werden als "-1/-1" angegeben.
Schlüssel werden direkt hinter dem zweibuchstabigen Feldtyp jeweils mit ihrer Anzahl und einem / dazwischen in der Reihenfolge blau, grün, rot, gelb angegeben. Ein leeres Floor-Feld mit 3 blauen Schlüsseln darauf würde in der Datei also als "FO3/0/0/0" auftauchen.
Eine komplette Datei mit 9x9 Feldern könnte z.B. wie folgt aussehen:

Beispiellevel
9,9,100,0,ABCD
Die Schwimmflosse könnte helfen...
WL,WL,WL,WL,WL,WL,WL,WL,WL,WL,FOFG,WT,WT,FO,FO,FO,BE,WL,WL,WT,FO,FO,FO,FO,FO,FO,WL,WL,WT,CY,
FO,FO,HE,FO,FOBX,WL,WL,FO,FO,FO,FOPL,FO,FO,FO,WL,WL,FO,FL,FO,FO,FO,FO,WT,WL,WL,CP,CP,CP,FO,
FO,FO,WT,WL,WL,CP,CP,CP,FO,WT,WT,TA,WL,WL,WL,WL,WL,WL,WL,WL,WL,WL,
CY2/3,2/4
BE7/1,2/3
 

Benutzt bitte folgende Typen, um die vom Editor erstellten Leveldateien einzulesen und zu verarbeiten.

Aufzählungstyp für die Monster und den Spieler:

TMonster = (None, BeeDown, BeeLeft, BeeRight, BeeUp, Blob, Bomb,
            BouncerBlueHorizontalLeft, BouncerBlueHorizontalRight,
            BouncerBlueVerticalDown, BouncerBlueVerticalUp, BouncerPinkDown,
            BouncerPinkLeft, BouncerPinkRight, BouncerPinkUp, BugDown,
            BugLeft, BugRight, BugUp, FrogDown, FrogLeft, FrogRight, FrogUp,
            PhantomDown, PhantomLeft, PhantomRight, PhantomUp, PlayerDown,
            PlayerLeft, PlayerRight, PlayerUp, PlayerWaterDown,
            PlayerWaterLeft, PlayerWaterRight, PlayerWaterUp, PyroDown,
            PyroLeft, PyroRight, PyroUp, TankDown, TankLeft,
            TankRight, TankUp);

 

Aufzählungstyp für die Felder:

 
TFieldType = (Block, ButtonBlue, ButtonBrown, ButtonGreen, ButtonRed, Chip,
              ChipSocket, CloneMachineBee, CloneMachineBlock,
              CloneMachineBouncerBlue, CloneMachineBouncerPink,
              CloneMachineBug, CloneMachineFrog, CloneMachinePyro,
              CloneMachineTankLeft, CloneMachineTankRight, DeathFire,
              DeathWater, Dirt, Fire, Floor, FloorSeparatorDown,
              FloorSeparatorDownRight, FloorSeparatorRight, ForceFloorDown,
              ForceFloorLeft, ForceFloorRandom, ForceFloorRight, ForceFloorUp,
              Gravel, Help, Ice, IceRedirectDownLeft, IceRedirectDownRight,
              IceRedirectUpLeft, IceRedirectUpRight, LockBlue, LockGreen,
              LockRed, LockYellow, Target, Teleport, Thief, Trap,
              Wall, WallAppear, WallBlueFloor, WallBlueWall, WallInvisible,
              WallToggleClosed, WallToggleOpened, Water, FireBoot, Flipper,
              Skates, SuctionBoot);

 

Konstantenarray mit allen zweibuchstabigen Kürzeln. Zuerst die Monster, dann die Felder, jeweils in der Reihenfolge der Aufzählungstypen:

 
CCode : array[0..97] of string[2] =
        //Erst die Monster
        ('BD', 'BL', 'BR', 'BU', 'BB', 'BX', 'BH', 'BZ', 'BV', 'BA', 'BP',
         'BC', 'BY', 'BQ', 'BN', 'BF', 'BI', 'BG', 'FG', 'FF', 'FT', 'FP',
         'PD', 'PF', 'PR', 'PU', 'PL', '--', '--', '--', 'PW', '--', '--',
         '--', 'PO', 'PY', 'PG', 'PP', 'TD', 'TL', 'TR', 'TU',
         //Ab hier dann die Felder
         'BK', 'BO', 'BW', 'BT', 'BE', 'CP', 'CS', 'CE', 'CB', 'CO', 'CI',
         'CU', 'CF', 'CY', 'CL', 'CR', 'DF', 'DW', 'DI', 'FI', 'FO', 'FS',
         'FD', 'FR', 'FW', 'FE', 'FM', 'FH', 'FU', 'GR', 'HE', 'IC', 'ID',
         'IW', 'IL', 'IR', 'LB', 'LG', 'LR', 'LY', 'TA', 'TE', 'TH', 'TP',
         'WL', 'WA', 'WF', 'WW', 'WI', 'WC', 'WO', 'WT', 'FB', 'FL', 'SK',
         'SB');

 

Aufzählungstyp für die Verbindungen:

 
TConnectionType = (CE, CB, CO, CI, CU, CF, CY, CL, CR, //CloneMachines
                   BO, BW, BE, //Buttons in blau, braun und rot
                   TE); //Teleporter


2)
Mehrere Bilder bekommt Ihr z.B. mit einer TImageList und einem TBitmap in das DrawGrid. Wie genau das geht, könnt Ihr Euch hier in einem kleinen Beispiel ansehen, das auch zeigt, wie man die Bilder auf die Größe einer Zelle skaliert (was aber eigentlich nicht erforderlich sein sollte).
Beachtet bei der Benutzung der TImageList, daß man die transparente Farbe eines Bildes nur direkt beim Hinzufügen in die ImageList setzen kann, danach geht dies nicht mehr! Da sich die Monster teilweise auch auf Wasser, Eis oder Feuer bewegen können, müßt Ihr sie mit transparentem Hintergrund in der Liste vorhalten, da sonst später die Darstellung nicht funktioniert!

3)
Für die zeitgesteuerten Veränderungen, also die Bewegungen der Monster, des Spielers und von Blöcken, braucht Ihr einen TTimer. Dort stellt Ihr in der Eigenschaft "Interval" ein, nach wie vielen Millisekunden jeweils die Ereignis-Routine onTimer aufgerufen werden soll. Alles, was zeitgesteuert sein soll, muß sich also in dieser Prozedur befinden oder in Methoden, die von ihr aufgerufen werden.
Deklariert Euch dann am besten eine unitglobale Variable vom Typ word, initialisiert mit 0, und zählt diese bei jedem Aufruf der onTimer um 1 hoch. Um dann verschieden lange Zeiträume benutzen zu können, braucht Ihr noch ein globVar mod x, wobei je nach dem Wert von x die Länge des Zeitraumes eine andere ist und x z.B. ausdrücken kann, wie schnell sich ein Monster bewegt.
Auch für den Timer gibt es ein kleines Beispielprogramm.

4)
Generell solltet Ihr damit anfangen, diese Aufgabenstellung mindestens 2 mal komplett zu lesen: das 1. Mal, damit überhaupt klar ist, woraus die Aufgabe besteht und das 2. Mal, um Euch schon erste Gedanken zu machen und Euch die einzelnen Anforderungen genauer einzuprägen.
Setzt Euch dann - VOR dem Schreiben der ersten Codezeile - hin und schreibt Eure Überlegungen zu den benötigten Datenstrukturen, Dateizugriffen und erforderlichen Formularen, Komponenten und Datenflüssen auf. Dies bildet später (fertig ausformuliert) die Doku-Kapitel "Problem- und Realisationsanalyse". Ihr spart Euch später viel (Korrektur-)Arbeit, wenn Ihr diesen Schritt hier sorgfältig durchdenkt!
Diese Überlegungen, Notizen und ggf. Skizzen sind ebenfalls mit abzugeben.
Ist das geschehen, fangt Ihr am besten damit an, ein Bild in einem DrawGrid anzuzeigen. Danach baut Ihr die eigentliche Datenstruktur (als Liste) auf, in welcher sich das Spielfeld befindet. Diese Datenstruktur wird dann im DrawGrid dargestellt (Änderungen z.B. durch Tastendrücke finden also NICHT direkt im DrawGrid statt, sondern auf der Datenstruktur, die dann im DrawGrid dargestellt wird. Nur so erhaltet Ihr eine saubere Trennung von Logik und Oberfläche!).
Anschließend ergänzt Ihr die Bewegung mit den Pfeiltasten, die dann die erwähnten Änderungen in der Liste vornimmt (in diesem Fall z.B. eine Spielfigur von einem Feld auf ein anderes bewegt). Danach folgt dann der Rest des Programms, also insbesondere das Verhalten aller Felder und Monster.
Falls Ihr auch den Zusatzteil erstellen wollt, macht dies erst, wenn der Rest des Spieles schon funktioniert. Gerade die Eis- und Laufbandfelder sind nicht einfach, wenn ein Monster oder der Spieler sie betritt. Hier könnt Ihr Euch also einigen Ärger sparen, wenn Ihr saubere Vorüberlegungen anstellt und Eure Erfahrungen vom Schreiben des Codes für die anderen Felder und Monster mit einfließen laßt!

 

Wie immer sind natürlich die generellen Richtlinien für die Seminaraufgabe Object-Pascal zu beachten.

Der letzte Abgabetermin für Chip´s Challenge ist der 10.07.2009. Der letzte Termin für die Abgabe inklusiv einmaliger Nachbesserung (siehe Richtlinien) ist der 12.06.2009.


Viel Erfolg bei der Bearbeitung!