Initial efforts to port my framework from JavaScript to TypeScript have now been completed on day two. Theoretically I could now proceed forward with the game prototyping portion, but I still want to clean things up a bit.
I fell into a bit of a Java mind trap during the initial port; TypeScript totally allows you to create just regular functions in a namespace, and export them (or not), which is not really what I expected. In the original version of the code I was implementing some of the static class methods by just having a regular function or variable, but in this initial porting push I switched that to using a more TypeScript static method.
That is to say, instead of something like this:
var autoEntityID = 0; var createDefaultID = function () { autoEntityID++; return "_ng_entity" + autoEntityID; }; // In a method somewhere if (this.properties.id == null) this.properties.id = createDefaultID ();
The typescript version looks more like this:
static autoEntityID : number = 0; private static createDefaultID () : string { Entity.autoEntityID++; return "_ng_entity" + Entity.autoEntityID; } // In a method somewhere if (this.properties.id == null) this.properties.id = Entity.createDefaultID ();
In this particular case, the code tends to look a little cleaner, which is all to the good, I guess.
Where this is more important is in the Stage class. In that class there is a lot of static methods and variables hidden in the closure that control things like what the current Scene is, what the next Scene should be on a switch, controllers for creating screenshots and so on. In this case it seems to really cruft the code up a fair bit with all of the Stage. prefixes on those values. So I want to go back over this area and clean this up a little bit now that I know I can still create a function outside of a class.
Another big thing is the idea of private versus public on instance member variables. Naturally in the JavaScript version everything was public, but that’s not very good OOP. Accordingly I have made everything private or protected as appropriate by default. This exposed a lot of places where code needs to get at the internals.
Probably the best way around this is to provide property accessor functions to provide read-only access or possibly to mask the internal values entirely. A problem I have with this method is that you can’t define an accessor function that has the same name as the actual instance value. I’m not a big proponent of “warting” up internal members (e.g. with an underscore prefix or suffix), which leaves naming conflicts.
Before I consider the port complete I want to revisit this area and come up with a good compromise. I’m thinking I want to go ahead and do that, even though I don’t like the visual looks of it, to ensure the safety of everything.
That’s a job for another day, though. Time to play a little Zelda!