[C#/XNA] Een (game) console bouwen..

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • kaesve
  • Registratie: Maart 2009
  • Laatst online: 16-05 03:04
Mensen van het SEA,

laat ik beginnen met een korte algemene inleiding. ik ben voor mijzelf bezig met het bouwen van een simpele game-engine. Ik ben een (alleen vandaag nog ;D) 17-jarig 18-jarig joch die zich graag bezig houdt met programmeren en van alles wat daar bij hoort. Hoewel ik in mijn eindexamenjaar VWO zit en dus eigenlijk elk vrij uurtje zou moeten besteden aan het voorbereiden van mijn examens, lijk ik toch steeds weer tijd over te hebben in dit projectje te stoppen. De bedoeling van het projectje is vooral om mijzelf beter te leren programmeren, maar het zou natuurlijk leuk zijn als er een bruikbaar resultaat uit zou komen rollen. enfin, tot zover de inleiding.

Voor het projectje, dat ik overigens Origamic gedoopt heb, maak ik gebruik van C# in combinatie met XNA, omdat ik hier al enige ervaringen mee had. Bovendien ben ik begonnen met deze sample van gamestate-management wat weer een grofweg een implementatie is van wat er in dit artikel beschreven staat.
Omdat ik uit eerdere ervaringen, waar ik ook dit voorbeeld gebruikte om mee te beginnen, weet dat het belangrijk is om goed te kunnen debuggen wilde ik een game-console bouwen. Hiermee moet ik makkelijk bepaalde settings at run-time en 'in-game' kunnen veranderen en andere settings en logs kunnen bekijken. Voor de gamers onder ons: het moet ongeveer zo werken zoals de console die valve altijd in haar games verwerkt.

Ik ben ondertussen zo ver dat ik een struct Message heb, die een tekstje en een enum messageType bevat. Deze messages worden bijgehouden in een stack in de klasse MessageTracer, die deze bovendien gefilterd op type terug kan geven. Dit kan ik ondertussen ook op het scherm tonen mbv de klasse ConsoleScreen. Wat er dus nog moet komen is een manier om met text-input settings op te roepen en opdrachten uit te voeren. Ik heb zelf wel een idee over hoe ik dit ongeveer zou willen oplossen, maar ik zou graag weten of hier nettere/betere/efficiëntere manieren voor zijn.

Mijn idee voor een console was alsvolgt:
Ik maak een delegate Commando aan, die een array aan strings accepteert (dus (params string[] args])). Daarna maak ik een Dictionairy<string, Commando> aan waarin ik de verschillende oprdachten opsla. Bij input van het ConsoleScreen wordt er gekeken of het eerste woord bestaat in eerdergenoemde Dictionairy. Zoja, dan wordt de bijbehorende Commando uitgevoerd, met alles wat na het eerste woord in de input kwam als parameter. Als het Commando echter niet bestaat, wordt er gekeken of er een setting is met die naam (deze staan ook opgeslagen in een Dictionairy).

Het enige probleem waar ik zelf tegenaan loop bij deze implementatie is de plaatsing van alle Commando-functies.. Volgens mij passen deze noch in mijn MessageTracer, noch in mijn ConsoleScreen (aangezien deze alleen de input en output afhandelt). Dit is niet echt een groot probleem, waar ik nog wel zelf uit kom.. Maar ik ben er nog steeds niet zeker van dat deze implementatie het mooist mogelijk is.

Een andere vraag die hiermee te maken heeft is: hoe trace ik het netst Exceptions? doe ik dit in het catch-blok, of zou de Exception dit zelf moeten doen?

Ik wil trouwens vaker vragen mbt mijn projectje hier plaatsen. Het gaat bijna altijd over ontwerp-problemen en misschien soms logica-problemen.. Is het mogelijk om daarbij op dit topic voort te borduren? of moet ik gewoon voor elk probleem een nieuw topic openen?

[ Voor 0% gewijzigd door kaesve op 27-02-2010 19:54 . Reden: even mijn leeftijd veranderd :D ]


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 08:01

Creepy

Tactical Espionage Splatterer

Ik heb je titel iets verbouwd omdat ik in eerst instantie dacht dat je een gameconsole wilde maken (een stuk hardware :P )

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • kaesve
  • Registratie: Maart 2009
  • Laatst online: 16-05 03:04
ondanks dat het mijn verjaardag is vandaag heb ik toch nog even de tijd genomen om hieraan te zitten. Is het niet mogelijk om alle functies die je uit moet kunnen voeren vanuit de CLI in een apparte klasse te zetten, om dan met class-reflection te kijken of de commandline-input overeenkomt met een functie uit die klasse? of wordt dit als vies gezien?

Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
kaesve schreef op zaterdag 27 februari 2010 @ 20:28:
ondanks dat het mijn verjaardag is vandaag heb ik toch nog even de tijd genomen om hieraan te zitten. Is het niet mogelijk om alle functies die je uit moet kunnen voeren vanuit de CLI in een apparte klasse te zetten, om dan met class-reflection te kijken of de commandline-input overeenkomt met een functie uit die klasse? of wordt dit als vies gezien?
Dit wordt vaak als 'vies' gezien vanuit een OOP perspectief, ja. Maar je bent dichtbij, je fipo zit al goed in elkaar. Je maakt een interface Command, met een functie doDinges(params) die het commando afhandelt. Elke functie die je uit kunt voeren vanuit de CLI implementeer je dmv een class die de Command interface implementeert. Console input die niet gelijk herkend wordt, wordt naar een SettingsCommand verstuurd, een Command implementatie die settings kan veranderen.

Tenminste, zoiets zou ik doen / lijkt mij logisch. Stop ze in een /commands map, eventueel in een submap daarvan (/utilcommands, /cheatcommands, /leethaxcommands).

mbt exceptions, wat bedoel je precies met 'tracen'?

Acties:
  • 0 Henk 'm!

  • kaesve
  • Registratie: Maart 2009
  • Laatst online: 16-05 03:04
en hoe houd je dan bij welke commands je hebt? in C# heb je het principe van delegates: functies die je in een variabele opslaat. volgens mij kan je het een beetje (niet helemaal) vergelijken met een pointer naar een functie in C (niet dat ik C spreek.. mijn kennis op dat gebied is flink gelimiteerd :P). Deze delegates kan ik dan netjes in een Dictionairy opslaan met een string als key (dit is een hashMap in java, denk ik?). Dat kan ik natuurlijk ook doen met aparte classes die dezelfde interface implementeren, maar is dat dan echt beter?

over het exceptions tracen:
een belangrijke functie van mijn console is het weergeven van messages. Verschillende events kunnen een instance van mijn Message-struct sturen naar de MessageTracer-klasse, die deze messages beheert, filtert, sorteert, weg kan schrijven en door kan geven. Exceptions zouden als het even kan altijd een Message moeten sturen naar de MessageTracer, die dan kan bepalen of het belangrijk genoeg is om te bewaren.. (exceptions zullen dat meestal wel zijn..)
Maar hoe implementeer ik dat? is het net om de Exception-klasse dit zelf te laten doen? of doe ik dit steeds in de catch-clausule?

in ieder geval erg bedankt voor je behulpzame antwoord. ik ben eigenlijk vrij nieuw in het hele programmeren en ik vind dit nog vrij lastig..

Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
en hoe houd je dan bij welke commands je hebt?
Gewoon in een Map<String, Command>, of zie ik dat nu verkeerd? Met een loopje kun je simpelweg uit laten printen welke Commands er geregistreerd staan / beschikbaar zijn. Met een functie getDescription() in je Command interface kun je evt. nog documentatie terug laten sturen. Een Command HelpCommand met een param 'commandname' zou dan de Command uit de Map kunnen halen die voldoet aan de commandnaam en de getDescription teruggeven. ofzo.

En wat betreft je exceptions: Eigenlijk is een Exception altijd kritisch, daar het een probleem in je code is. Die kun je ruwweg in twee categorieën opdelen: Exceptions die op te vangen zijn (bijvoorbeeld FileNotFoundExceptions, indien die in C# bestaan, en het een bestand betreft die niet kritisch is), en Exceptions die niet op te vangen zijn, die je hele systeem laten ontploffen.

Maar je zou in de logging-laag deze niveaus aan kunnen geven. In een typische Java applicatie (waar ik het meeste mee werk) ziet een catch-blok er typischerwijs zo uit:

Java:
1
2
3
4
5
try {
   doeIets();
} catch (EenSoortException e) {
    LOG.log(Level.SEVERE, e.getMessage(), e);
}


In de Log aanroep kun je een niveau aangeven (severe, warning, info, etc). De Logger (of, het component van je systeem dat de logberichten in de console of een logbericht weergeeft) kun je vervolgens configureren om alleen berichten van het niveau SEVERE weer te geven, of INFO (en hoger), of gewoon ALL.

Volgens mij is zoiets wat je zoekt. Ik ben niet bekend verder met logging frameworks voor C#, maar daar zou je wat onderzoek naar kunnen doen.

Acties:
  • 0 Henk 'm!

  • kaesve
  • Registratie: Maart 2009
  • Laatst online: 16-05 03:04
top!
ik had gister inderdaad al even geprobeerd een implementatie te schrijven op basis van een interface. dat werkte, maar uiteindelijk is die interface een abstract class geworden, om zo de gemene deler van elke command maar 1x te implementeren (denk aan een auto-completion functie die standaard alleen de commando-naam terug geeft).
dat je vooral met java werkt had ik ergens al begrepen :+ dat is eigenlijk de eerste echte programmeer-taal die ik heb geleerd dus dat spreek ik ook wel aardig (ondanks verschrikkelijke ervaringen bij het leren).. niet dat C# zo verschrikkelijk anders is, en zeker niet bij het afhandelen van exceptions. mijn vraag was vooral: als je toch altijd wilt dat alle exceptions worden gelogged, waarom laat je dat de exception niet zelf doen? maar nu ik erover na denk heb je daar natuurlijk niet altijd controle over.

oké, dan heb ik nog één vraag, betreffende het ordenen van de commandos. ik weet dat in java er een limiet van één public class per file is, waardoor je dus in deze situatie verplicht zou worden om het in meerdere class-files op te delen. In c# is die limiet er echter níet. is het dan nog steeds best-practise om elke class in een aparte file te stoppen, of kan ik hier ook een file CheatCommands.cs maken en daar alle commando-classes in dumpen die met cheats te maken hebben?

Acties:
  • 0 Henk 'm!

Verwijderd

Dat moet je zelf weten. Ik zelf houd wel alles in een apart bestand, ook als het een interface is met 1 definitie.
Je hebt wat meer files, maar je kunt natuurlijk met directories en namespaces spelen, waardoor het mijns inziens overzichtelijker is.
Pagina: 1