OO Textbased Game
Text-gebaseerd spel mbv OO technieken
De prijs voor meest sexy titel gaan we niet winnen. Maar naar de aloude traditie van de klassieke tekst-gebaseerde adventure-games (zie hier ) zullen we een eenvoudig object georiënteerd framework maken dat ons toelaat snel onze eigen games te maken. De nadruk van dit artikel ligt daarbij niet tot het creëren van een perfecte imitatie, maar wel om aan te tonen dat met een beetje object georiënteerde inzichten we tot zeer propere, herbruikbare én onderhoudbare code kunnen komen.
We maken uiteraard het spel in een Console-applicatie.
Main
We willen de Main() methode van Program.cs zo leeg mogelijk laten. Daarom zullen we de meeste functionaliteit verpakken in een klasse GameManager. Het enige dat we dan nog hoeven te doen in onze main is een loop starten die steeds 3 zaken zal doen:
Huidige locatie beschrijven
Aan gebruiker tonen welke acties hij kan uitvoeren
Gewenste actie van gebruiker verwerken en uitvoeren
In code behelst dit:
static void Main(string[] args)
{
Console.WriteLine("Welkom bij AP Adventure. Een avontuur voor moedige en minder moedige studenten. Ben je er klaar voor?");
GameManager theGame= new GameManager();
//Start gameloop
while(!theGame.Exit)
{
//Beschrijf kamer
theGame.DescribeLocation();
//Toon acties
theGame.ToonActies();
//Lees actie uit
theGame.VerwerkActie();
}
}Een bool property Exit binnen het GameManager object zal ons toelaten om de loop te stoppen wanneer het spel wordt beëindigd.
GameObject
Doorheen de verschillende locaties zullen elementen te vinden zijn. We beschrijven deze als GameObjects:
Location
De gebruiker kan van locatie naar locatie gaan. Een locatie bestaat uit een aantal zaken:
Een beschrijving en titel
Een lijst van GameObjecten (items) die zich op deze locatie bevinden
Een lijst van Exits, namelijk de richtingen waar de gebruiker naar toe kan gaan die aansluiten op een andere locatie
Een eerste versie van onze locatie klasse is dan:
Merk op dat we gebruik maken van List<> ipv arrays.
Exit
Iedere exit in een locatie definieert minstens 2 zaken:
De richting waar deze uitgang zich bevindt (Noord, Oost,Zuid, West)
Een referentie naar het locatie-object waar deze uitgang toegang tot verschaft
We krijgen dus al:
Waarbij Directions een eigen gemaakt enum-type is:
Van locatie veranderen
Binnen de locatie klasse voegen we een methode toe die de GameManager kan gebruiken om te weten te komen naar welke locatie de gebruiker gaat. De methode aanvaardt een Direction (i.e. de richting waarin de gebruiker wenst te gaan) en zal een referentie naar het location-object teruggeven waarnaar de gebruiker zal bewegen. Indien de richting waarin hij wenst te bewegen niet geldig is dan tonen we dit op het scherm:
Wanneer dus een exit wordt gevonden in de Exits lijst die voldoet aan de meegegeven Direction dan geven we een referentie terug naar de bijhorende locatie (GoesToLocation). Wordt er geen exit gevonden en bereiken we dus het einde van de foreach lus dan verschijnt de tekst op het scherm en geven we een referentie terug naar de huidige locatie.
GameObjects als vereisten om exit te gebruiken
Stel nu dat we soms willen dat een bepaalde locatie pas bereikt kan worden indien de gebruiker reeds een bepaald GameObject in zijn bezit heeft. Hiervoor moeten we 2 zaken aanpassen:
We beschrijven in de
Exitklasse welk object(en) nodig zijn om deze exit te mogen gebruikenWe controleren of de speler het
GameObjectheeft wanneer deze naar een nieuwe locatie wil gaan mbv deGetLocationOnMove()methode.
De nieuwe, volledige Exit klasse wordt dan:
In deze ietwat knullige code tellen we dus of de speler alle GameObjecten in z’n inventory heeft (playerInventory) nodig om deze exit te gebruiken.
Deze methode TestPassCondition gebruiken we nu in de GetLocationOnMove()-methode in de Location klasse om te bepalen of de exit mag gebruikt worden. De methode wordt dan:
GameManager
Rest ons nu enkel nog de GameManager klasse te maken. Ruw gezien is deze als volgt:
Wat ogenblikkelijk opvalt zijn:
De 3 publieke methoden
DescribeLocation,VerwerkActieenToonActiesEen instantievariabelen
currentLocationdie een referentie bijhoudt naar de huidige locatie van de speler3 lijsten met daarin de objecten die de speler heeft (
playerInventory), alle objecten in het spel (Objects) en alle locaties in het spel (GameLocation)Een
InitGame()methode waarin we alle gameobjecten, exits en locaties zullen aanmaken bij aanvang van het spelEen bool
Exitzodat de externe gameloop weet wanneer het spel gedaan is
We zullen nu de afzonderlijke methoden invullen:
DescribeLocation()
VerwerkActie()
We laten de speler dus toe door n,o,w,z in te typen dat gecontroleerd wordt naar welke nieuwe locatie zal gegaan worden. We passen hierbij de currentLocation property van de GameManager aan naar de, al dan niet nieuwe, locatie.
ToonActies()
InitGame()
In deze methode definiëren nu de volledige spelinhoud. Wil je dus bijvoorbeeld dit spel uitbreiden met extra kamers en objecten, dan doe je dat in deze methode. Ter illustratie tonen we eerst hoe we 2 locaties aanmaken en deze aan elkaar hangen mbv de Exits (waarbij kamer één zich ten zuiden van kamer 2 bevindt)
Vergeet niet op het einde de 2 kamers toe te voegen aan de GameLocation lijst van de GameManager, alsook in te stellen wat de beginkamer is.
GameInit met GameObject als conditie om kamer in te kunnen
Stel dat we even later in een kamer een sleutel plaatsen die als conditie dient om een andere kamer te kunnen openen. We schrijven dan in de GameInit() methode:
Een volledige GameInit ter illustratie
We hebben nu de belangrijkste onderdelen geschreven. We tonen daarom een iets uitgebreider spel, demo zeg maar, waar in we alles gecombineerd in actie zien:
What’s missing? Veel!
Maar een eerste uitdaging zou kunnen zijn: hoe kunnen we de speler objecten van de grond laten oprapen en in de inventaris plaatsen? Dat raadsel laten we aan jou over over om op te lossen!
Last updated
Was this helpful?