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!
I was recently contacted by Allan Hoffman (the "tech jobs expert" for Monster.com) about some quick thoughts and tips I had on how to have a successful technical blog (which alone is a shock to me as I wouldn't even start to think of my blog as "successful", but to each his own I suppose :)). I thought I would reprint my response here (with permission, of course). I hope you enjoy :).
Obviously, these are just my opinions so you can take them with a grain of salt if you wish (at your own peril, I might add :P). Feel free to add your own as well. I know many of other more capable bloggers have already talked about this, so I'm merely sharing my own experiences as a blog reader myself.
--------
What are the ingredients for a good technical blog? In my opinion, the recipe is pretty simple: accurate technical information + personality + reliability (at least semi-frequent posts) = good technical blog. I have certainly suffered from time to time on the reliability aspect. And I believe that at certain points in the history of my blog, infrequent posting has actually caused me to lose readers. Personality is an aspect that I still am feeling my way through. At times I feel I become too personal and lack the amount of technical information that people desire. At other times, I had tried to be so technical that my personality had stopped showing through. It's definitely a balancing act.
Here are some quick tips that I could think of:
Tip A / B. Have Something To Say / Be Unique. It seems like nearly everyone has a blog these days. Even in the technical world there seems to be an over-abundance of blogs that exist now. There is an incredible amount of noise that exists that people have to sort through in order to get to the juicy stuff. Let's face it, you want to have one of the blogs that gets noticed. You don't want to simply be adding to the noise. In this vein, make sure that you have something to say. A quick way to get a reader to hit the "unsubscribe" button is to write many "check out this link" posts. And whatever you do, don't simply post to apologize for not posting. With how much noise that exists out there in the "blogosphere", if you're not adding signal, you're out of my aggregator.
Another way to add signal? Be unique. Even if you're not always technical, there is a good reason that blogs like http://www.neopoleon.com are becoming extremely popular (dare I say, near cult-like). If you are unique, you give your readers the opportunity to look past some of your shortcomings (and face it, we all have them). Not only that, but maybe you'll make people laugh in the process (which is always a good thing in my book).
Tip C. Blog About Something You Enjoy. You have to enjoy what you are blogging about, it's as simple as that. If you don't, it will feel forced and your readers will notice. If you would like people to enjoy reading your blog, you should enjoy writing it! When reading blogs I believe people don't want to feel like they are reading a text book. Which leads to Tip D.
Tip D. Let Your Personality Show. One of the major advantages of blogs is that they can be a uniquely personal communication medium. When reading your blog, let people know who you are. I've noticed recently that the majority of blogs in my RSS aggregator are from people who let their personality show. I enjoy the fact that while reading a person's blog I get the unique opportunity of getting to know them a little bit. So, remember to be yourself while blogging.
I haven't done any coding recently as I've been getting ready for the gig I just had tonight in Seattle. I'm now checked in to the (crappy) hotel (the room is about as big as my left thigh). Luckily, they have wireless, so I'm able to at least give this update.
I realized yesterday that to take this game where I want to take it, I really need to upgrade to Managed DirectX to leverage the hardware acceleration (especially once I get into implementing my particle engine/system). So, as soon as I get back, I will be upgrading the game from GDI+ to Managed DirectX. Luckily, this conversion shouldn't take too long as I simply need to add a new Direct3dGraphicsService class and change my application to use that.
Actually, that's not entirely true. I also need to change some of my game logic. This is because GDI+ expects the origin to be in the upper left corner, while the way I will be setting up my camera in MDX will expect the origin to be in the _lower_ left corner. That should be pretty easy to fix though.
Perhaps if I really start using MDX, it will allow Andy to start giving some blogging love to it :) (don't forget Andy that George is also using Managed DirectX for the contest).
Anyways, back to reading the AI book I picked up the other day.
You may not get another Spaceballs update until Monday or Tuesday night. Sorry :).
Well, I didn't think I was going to be able to make much progress on the game until next week (since I'm going to be gone all weekend), but I was able to get in some coding time tonight that I wasn't expecting. And you know what? I'm glad I did :).
My tracer bullet is completely finished now (take that George, :P) :).
Tonight I wrapped up the High Score system and made it persistent using simple XML serialization to the game's own folder under the Application Data directory. The High Score screen is displaying the results and the Recap screen will congratulate you if you have achieved a new high score.
So, all the major "required" features are done and checked off the check list. That means that what is left is making it look good, adding more enemies, tuning game play mechanics, etc. This is one feeling that I love about implementing tracer bullets: once you finish the tracer bullet, you realize that a large portion of your system is fully operational and ready to be added onto.
So, now I'm on to simply making it fun. Not bad for Day 14. I still have roughly 28 days to finish the game (giving me some wiggle room, just in case). I'm fairly confident I will have quite a fully-featured game by that time considering that I have twice as long left than I've already spent on it.
Yee haw :).
Perhaps I will take some time next to do some performance profiling and getting my framerate back up since it has dipped to under 100 fps. Although, on second though, I won't worry about that until it dips under 60 fps since it won't be noticeable 'til then anyways.
Soooooo, I guess I'm on to adding some new enemies, weapons, power-ups, and the like. Sweet! Here's where the real fun begins :).
Well, since Sir Georgio decided to give me some crap about losing focus, I figured I would post about what I've been doing.
The MVC work is all finished, cleaned up, refactored, and ready to drop a bunch of new types of enemies into the game. Before I did that though, I decided to clean up the graphics a bit.
One of the first tasks was to implement a "playing field" that play would take place on. Before, play was just the whole screen which wasn't very conducive for HUD-like UI (like Score, Lives, etc.). The playing field is now implemented and operational.
I still think it is important for me to hook up the High Score system before plugging in new enemies. Once the high score system is fully implemented (shouldn't take that long), my tracer bullet will actually be entirely complete and functional. Then I can move on to beautify-ing the application and adding some more gameplay elements.
Here's a new screenshot of how it looks now. Still not stellar, but a definite improvement over my last post (and yes, I made the Sprites myself (although any artists out there can probably tell that fact already)).
|