After Shark Ghost Eater, I wanted to try my hand at some other types of games to learn more about game programming and the XNA library. I’ve still a long way to go, but it still impresses me how easy it is to do things now compared to a decade ago.
Anyway, after fiddling around with some other stuff like custom sprite fonts and working on a fancy text displayer (example) I decided I’d like to try to make a simple Zelda-like game. Here’s what I got running in about forty minutes:
A couple things of interest:
A lot of XNA games that go for the pixel-y look tend to still have aliasing issues, which kills the look. That, or different pixels are done at different scales (like sprites might be 2x the pixel size while backgrounds are 3x the pixel size), which just looks “off”. So I looked into how to do this properly and it turns out to be relatively easy. It involves changing the RenderTarget when doing a SpriteBatch.Begin(), and then afterward resetting the target and using the PointClamp filter to zoom the entire thing up to the window size.
Basically, this means I can do consistent, authentic-looking pixel art without batting an eye. What happens is that technically the game is drawn on a tiny little sprite about the size of a NES screenshot, and then zoomed up to fill the screen each frame. The result is that already the art looks a lot better than Shark Ghost Eater without even trying!
Also, for this Zelda clone I’ve decided I want to make it look NES-like, so I’ll only use the 50 or so colors an NES can produce. Luckily there are palette files available just for that purpose. I also plan to do all the graphics with sizes that are multiples of 8, since that’s how NES graphics are done. I’m hoping it’ll make for an authentic feel as time goes on.
Shark Ghost Eater didn’t have any animation at all. I was hoping XNA had some sort of animation class or something, maybe it does, but tutorials I read all just recommended putting all the frames of animation in a single texture and then just showing certain sections of that texture. A very simple approach, so I got it running pretty quickly. Right now, this is how the main character works – there are four frames, one for each direction you face.
I wanted to have an enemy to bash around, so I drew up yet another ghost! Thanks to the above pixel stuff, it already looks better than my previous art 😛 Thanks to my practice with object oriented programming and state machine stuff with all my web programming over the past few years, getting the enemy class up and running took only about five minutes.
Using the state machine design and the way object oriented stuff works, it made implementing a bunch of stuff really easy, like making the enemy scoot back after being hit and having it blink on and off before it dies completely. Doing that the old-fashioned way would’ve sucked and would’ve taken me forever. But this new approach is so natural and liberating, it’s like the code flows from my fingers!
Implementing the sword required some thinking – I had to do another set of animations, basically I drew the sword in four different directions. The trouble came with trying to position it properly for each case.
Then the real hard part came with the hit detection. The hit detection in Shark Ghost Eater was laughable, so this time I wanted to do better, since I used to do hit detection stuff all the time years and years ago. Luckily, it looks like XNA has a IsHit() member function in the Rectangle class. I used that very quickly and horribly but it works reasonably well without any tweaking at all!
Dinner was in ten minutes, so I was in a rush by this point. I decided to add some sound effects very quickly. Making sound effects sucks, but luckily I stumbled upon this amazing program that generates a lot of randomized sound effects that you can save! So I used some of those, which XNA makes very easy.
While I was at it, I looked into how to add some stereo sound to it – so right now one or two of the sound effects will pan more to the left or right speaker depending on where the sound takes place.
By now it was time to call it a night, so I stopped here. All in all, I got a lot done in a short amount of time. It’s hard to find any spare time for this sort of thing, but programming’s always been very relaxing for me, so I hope to keep at it.