I was asked recently what excited me most about the various Vista technologies. While I took a valiant stab at limiting my answer down to a handful of them, the proper answer with the way I feel would have been "what _doesn't_ excite me about the various Vista technologies." Yes, I could get into the various aspects that excite me about Workflow Foundation, Presentation Foundation, and/or Communication Foundation. I will save that for a later blog post though. Save to say, I'm extremely stoked right now about doing some development with all the different Foundation technologies. I think I'm going to do some deep-diving into Workflow Foundation for a while though :).
So, after a hiatus for almost a year (has it really been that long?), I will be spending time again getting into the various Vista technologies that are coming our way. So stay tuned in the future for more Vista updates :).
I know I was shooting to get the lives system implemented last night, but I wasn't able to do so because I needed to fill out a bunch of paperwork and do some general catch up on some other tasks (non game-development related, that is). So tonight was my first opportunity to work on Spaceballs since Tuesday night.
I'm proud to say that not only did I get done what I was shooting for (multiple lives for the player as well as the "Get Ready, Set, Go!" countdown at the beginning), I also got done a lot more. I love the feeling of being very productive because the architecture and framework just enables you to be productive :). With the way I had implemented my state management (combined with existence of my new Task Manager), I was able to finish the GameOverState as well as add a death animation for when the player dies. I also added a bunch of prompts throughout play and stuff. What a great feeling!
Now with lives, respawning, death, death animation, game over, etc. all implemented, the functionality and flow of the gameplay is _literally_ feature complete now (must haves + nice to haves). Now I can move on to adding the new enemies, power ups, and such (read: all the fun stuff). I find myself getting more and more confident with each coding session (of getting something fun and complete done by the deadline, not of winning (especially with all the other fun games being done)).
I do have some cleanup left to do after tonight's coding session. This just involves creating a quick UI component that can be re-shared between the various GameStates I have for the Scoreboard area (Score + Lives + Prompt/Possible Message To User). That should take almost no time at all. Perhaps after that I will do a release of the binaries and source for all of you to download (maybe tomorrow night?). Regardless, sharing code and binaries is very easy for me since I have a script that automates the cleanup of the source code, generation of release notes, and creation of the zip files for me.
Once I'm able to do that, I'm hoping that starting tomorrow night and ending sometime Saturday, I can create and finish a HomingSpaceball (charges after the ship wherever you go) and a WanderingSpaceball (moves in random directions). If I'm able to get those done, I would like to extend the HomingSpaceball to break up into four smaller spaceballs when it is destroyed. That should add some more fun to the game.
Now, in the miraculous case that I'm able to get all that done this weekend, I will move on to adding a new weapon (which will require me to finally create a new Weapon class and change my firing mechanism around a bit (once again, shouldn't take that long)) that you will automatically upgrade to at 10k points. When that is finished, the next step will be adding bombs to the player's arsenal that will destroy all spaceballs that are in play when it is dropped. Holy cow, if I could get all that done (even by next Tuesday or Wednesday), I would _REALLY_ be cooking along toward my goal. Perhaps then I could start doing some play testing.
Until next time, that's how the cookie crumbles :).
OgreDotNet was recently pointed out to me by a friend and co-worker. I don't know have I missed it in the past, but I see it's there now which is the important part :). With the lack of mature, open-source 3d graphics engines for managed code out there right now*, I'm glad to see this come to fruition.
Since Ogre3d is already object-oriented, you can't tell from the code of OgreDotNet that it is simply a set of bindings down into the C++ libraries of Ogre3d :). Not only that, but it appears the forum is fairly active and alive (and that's the OgreDotNet forum I'm talking about (since the regular ol' Ogre forum is _very_ much alive)).
In the future (aka after I finish Spaceballs and perhaps another game or two), I will probably end up using this for my first 3d game I do (and possibly all the other 3d games I do after that). I really want to just break down and start playing around with it now, but I'm sure my competition in this contest would like for me to do exactly that. SOOOO, perhaps once Spaceballs is finished I can start playing around OgreDotNet.
Until then, make sure you check it out :).
http://www.ogre3d.org/wiki/index.php/OgreDotNet
* Axiom priorly being sucked up into RealmForge (I know the source forge project has started up again, but it _just_ started up again seriously, in my opinion), RealmForge now being "deprecated" of sorts, and the other options like Irrlicht.NET and Haddd not being as mature and supported as Ogre (again, just my opinion)
I didn't quite get around to implementing the lives functionality tonight. However, I did do some general cleanup and "paved the road" for me to easily drop in the code for respawning and multiple lives tomorrow.
One of the refactorings I did was to take what I was calling "States" before and change them to "Screens". Really, they were screens. As I needed to start adding states to the gameplay itself (like PlayingState, LostLifeState, etc.), I didn't want to go down the road of making a hierarchical state manager because I felt it would muddle up what was really being done under the hood. I felt that separating out Screens from States would lead to a much more clean implementation.
Rather than states being things like MenuState, PlayState, RecapState, and HighScoreState, those are now MenuScreen, PlayScreen, RecapScreen, and HighScoreScreen. In my mind, that makes it much more clear what they are actually doing. States are now concepts like ReadyToPlayState, PlayingState, LostLifeState, PowerUpState, GameOverState, etc. Once again, I am happy about this change as I am really liking the separation between "Screens" and "States" rather than hacking both concepts into one. The code is not only cleaner, but it will also be much more clear where the functionality I'm about to implement goes. For instance, the multiple lives functionality will simply be transitions from PlayingState to LostLifeState and back to PlayingState. If I add the "countdown" at the beginning of the game (think "Starting in 3... 2... 1.... GO!"), it will simply be starting with ReadyToPlayState and transitioning to PlayingState when appropriate. This will also help break out the code into more manageable chunks as well (which I always like).
On an aside, I think I use Source Control much more than I originally thought. It's only day 20, and I'm already up to revision 61 in SVN (61 commits). Better safe than sorry, I suppose :).
I still don't have any comments to make on Visual C# Express. I still haven't really noticed the difference all that much for my hobbyist development. Anyone out there that wants to get into C# development should _totally_ download Visual C# Express and use that. Besides, you can't beat the price of FREE :). The one thing that I can say is that, in my opinion, the Express products are better than the other free IDEs that are out there today. Usually, you get what you pay for (meaning free can suck tremendously), but not with the Express editions.
That's it for this update. For tomorrow night, I'm going to shoot for implementing multiple lives (a.k.a. LostLifeState) and hopefully get around to implementing the ReadyToPlayState as well to add the countdown to play time. Those shouldn't take too long (hence the reason I'm hoping I can get both of them done tomorrow night). Until then, I'll see you on the flip side :).
Not much functionality change tonight. Nope, tonight was mostly bug squashing night.
The first bug I squashed was around spawn point generation. Sometimes, a spawn point would be generated that would cause a Spaceball to be spawned within a wall. This was due to the spawn point generation algorithm not taking into account the size of the entity is was generating a spawn point for. That was an easy fix :).
The next bug I squashed was around the ball-reflection logic I had to bounce Spaceballs off of the walls when they hit. Unfortunately, it didn't take into account whether the code had already flipped the velocity vector based on a prior collision with the wall (i.e. a collision from the frame before (meaning, it is _still_ stuck in the same wall since not enough time has passed to clear the wall)). This was causing Spaceballs to become "caught" in a wall or to pass right through it. This was also an easy fix. I basically added logic to not only check for the collision, but to also check whether the Spaceball was still headed in the "wrong" direction before correcting its velocity.
The last thing I implemented was more around missing code. When implementing the game loop originally, I had forgot to add the ability for a game to be "paused". This meant that if the form lost focus (like navigating away to a different window), that the game would still run in the background. Oops :). That was also an easy fix, so it behaves properly.
Fixing the game pausing functionality exposed another bug, though (don't you love when that happens?). My EnemyEmitter class that was spawning new enemies on a frequent basis was checking a DateTime field from the last time it spawned to DateTime.Now to verify whether it needed to spawn a new enemy. This meant that the second a new enemy was spawned, I could make the window lose focus, wait several seconds, give the window focus again and a new enemy was spawned right away. Bad Jason! I should know not to check against *real world* elapsed time. I changed the code to record how much time had elapsed *in game* since the last spawn (by adding up the elapsed time through each "Update" call to the Emitter) and Poof! Bug fixed :). Once again, easy fix.
That's about it for tonight. Hopefully tomorrow night I can implement the lives system (i.e. giving you three lives rather than the game being over the first time you get hit). I was really hoping to do that tonight, but I guess it just wasn't in the cards :). Once I do that (which will include some refactoring to add "spawning" of ships themselves and fixing an annoying spawning issue I currently have), I will truly move on to implementing some of the various other Spaceballs I have in mind. Then the true fun begins (not that it hasn't been fun up to this point :)).
Well, I was able to squeeze in _some_ coding time last night and this morning. The update to Managed DirectX is all finished. It's kind of nice to see FPS should up from 90 fps to around 550 :).
All in all, it took about three hours to upgrade from GDI+ to Managed DirectX. Boy am I glad that I wrote the infrastructure the way I did. After a quick refactoring (making it so the IGraphicsService implementation rendered the Sprite rather than the Sprite itself), all I had to do was implement a new Direct3dGraphicsService and change the ServiceLocator to use an instance of that instead of the GdiGraphicsService it was using before. Viola! I'm now in Managed DirectX land. I love when to make a change like that, all you have to do is add another class rather than comprehensively changing your existing code.
Unfortunately, I'm still at the hotel in Seattle so I can't commit my changes to my Subversion repository yet (boy does that feel weird; I guess I'm used to committing often when I make small functional changes).
Now I believe I'm in a position to sustain for the long haul (as in, the system can grow to handle a particle engine and the like rather than having to find clever ways around the fact that GDI+ is not hardware accelerated).
So, what are the next steps?
1) Resolve a bug around Spaceball creation (sometimes the Spaceballs are created in the walls). This should be easy as it is simply limited the spawn area by the dimensions of the Spaceball being created.
2) Add "lives" to game. You will start out with three lives and the game will be over when you have no lives yet (currently, you only really have one life). I will probably re-implement my TaskMaster here to handle delayed spawning.
3) Create "invisible time" for two seconds when a new Spaceball is spawned. Currently, if a Spaceball just happens to spawn where you are: BLAMO! Game over. Just a little annoying, to say the least. I want to fix this.
Once those are done, I figure I will either "beautify" the Menu screen, or I will start adding in more enemies and gameplay mechanics (like Ship power-ups and such). Currently, I'm leaning towards adding some more gameplay mechanics as I would rather get those down and fleshed out before making the various screens look good (which I can always do at the end). Basically, I want to prevent myself from spending so much time make it look pretty that the gameplay suffers.
DirectX Rant #1 - The errors. They're horrible. If I accidentally try to Draw a Sprite before calling Begin(), please just tell me that "Begin must be called first" or something like that. Whoever thought that "<INSERT MAGIC NUMBER HERE> D3DERR_INVALIDCALL" is a useful error should be SHOT on sight.
Visual C# Express Thoughts - I agree with George, here. In this case, no news is good news. I work with Visual Studio at work and the fact is that I have hardly noticed that I'm _not_ working with it at home. The only difference for me is that I'm missing ReSharper, but that is _only_ because I've been too lazy to install it yet :). You gotta love a quality IDE that doesn't get in your way and has so much functionality to it!
|