Next "For Fun" Project
For those that follow my crazy forays into stuff that I think is just plain cool, I have begun yet another project. No crazy hacking in the sidebar. No more new webcam stuff (yet). No screen scraping with Outlook calendar appointment setting. I'm off into web land starting an Ajax based RPG similar to a game called Kingdom of Loathing.
It's a turn based RPG whose maps are hex tiles. I'm doing some crazy dynamic image generation and its all stream based so as not to fill up the server hard disk (and to keep memory in check, the stream is closed rather being saved off somewhere like the Session object).
I've opted to go for a pipeline based architecture consisting right now of 2 pipelines. The logic pipeline which will react and update the game variables based on user input and the rendering pipeline which I'm working on now. Since the game has so many different parts (the user avatar, monsters, cities, treasures, inventory, etc...) I wanted to break it down thus leading me to the pipeline. Just to show how easy it is to get something into the dynamic image that is generated by the map, I'll show some really early pre-pre-pre-alpha code here. Here's the main game controller object demonstrating the creation of the rendering pipeline. There are 2 pipeline objects: the map renderer which simply draws the hex grid and then a test object which simply draws a rectangle as a proof of concept. Now that the architecture is in place, it's extremely easy to inject new renderers into the rendering pipeline.
private void LoadGameRenderPipeline()
{
IPipelineObject mapRenderer = new MapRenderPipelineObject();
IPipelineObject testDecorator = new MapDecoratorTest();
renderPipeline.Add(mapRenderer);
renderPipeline.Add(testDecorator);
}
Once the logic pipeline finishes, I can then enumerate through all the rendering pipeline objects and tell them to execute in order. I also use something I'm calling a PipelineContext in order for the pipeline objects to share information rather than having each individual object do something stupid like hitting the database, reading from storage, or stuffing everything in the Session object.
Just for fun, here's the Execute method for the MapDecoratorTest object (in the image below, it's the object that drew that red rectangle on top of the map that the MapRenderPipelineObject created). Oh, and disregard the nasty naming convention. It's prototype code :-)
public void Execute(PipelineContext pipelineContext)
{
MemoryStream ms = pipelineContext["MapImageStream"] as MemoryStream;
Bitmap bm = Bitmap.FromStream(ms) as Bitmap;
Graphics g = Graphics.FromImage(bm);
g.FillRectangle(new SolidBrush(Color.Red), 0, 0, 200, 300);
bm.Save(ms, ImageFormat.Png);
}
