Wednesday, May 13, 2009

Getting a Move On

I recently took my first foray into animation, and it wasn't nearly as scary as I expected. As it turns out, animation was based largely upon the work I did with sprite sizes in the last post. As a recap, since textures need to be sized by powers of two, I found I needed to pull out rectangles within the textures to create sprites of varying sizes. I also made three sprites out of one texture that included all three images.

Well, animation follows the same idea. For reference, take a look at this texture image:

(What you're not seeing is that this image has transparency in it, something else I recently figured out.)

So, this texture has six frames of animation in it for our swirly circle. To animate it I simply display a different rectangle within the texture on each pass of OnPaint. I made a SimpleAnimatedSprite class to handle these animations. It stores the number of rows and columns of sprites inside the texture, as well as the size of each frame (they all must be the same). Then it just iterates through each image and displays them in order.

This worked perfectly well, but it animated extremely fast so I added another property to my class, the length of time between frames in milliseconds. I made the OnPaint loop display the same frame until the correct amount of time has passed, then move to the next frame and calculate the time for the frame after that one. I was able to successfully control the speed of the spiral, and even make it controllable by the user.

There are a few limitations to this class. First off, all the frames have to be the exact same size, and the frames need to be arranged in the texture image such that the final row of frames is full (you couldn't have seven frames for example). I'll create a ComplexAnimationSprite class to overcome these limitations.

Sunday, May 10, 2009

Sprite Sizes

I set myself to displaying a nice logo screen before my game came up recently. I figured this would be a fairly straightforward process given the work I had done so far. Just setup a Scene object with one sprite in it and stick it in the center of the screen. Easy!

Well, nothing is ever easy, as soon as I slapped my logo on the screen the image was stretched! It look horrible! Since I was testing this in my monitor's native resolution I knew exactly how the image should look. I began the process of debugging and found that it was reading my logo in as a 1024x1024 image, when the actual image was something more like 600x600.

With a bit of Googling I undercovered that the textures I'm using as sprites need to be loaded in with square resolutions in powers of two (2x2, 4x4, 8x8, 16x16, 32x32, 64x64, 128x128, 256x256, 512x512, 1024x1024, etc). The two colored dot images I was using were 100x100 and 200x200, but as expected it turns out these were being loaded in as 128x128 and 256x256 respectively. I just hadn't noticed because it wasn't too drastic at that size.

Well, the solution to this is to load your sprites in as textures of the allowed size, and the grab out the pieces you need. Example:

sprite.Draw(spriteTexture, textureSize, new Vector3(0, 0, 0), new Vector3(xPos, yPos, 0), this.alphaColor);

The second parameter of the D3D Sprite.Draw method takes a Rectange object (textureSize) that specifies what portion of your texture you want to draw. I created a sprite subclass called BlitSprite (I *think* the term for this is blitting, thus the name) which is overloaded to take a rectangle instead of just using the entire texture square.

You can (and should!) also combine sprites into a single texture. Now I'm pulling three colored dots from one image file like this:



















Also, I added a parameter to my Sprite baseclass that allows me to pass in a black value to the image. So, against a black background that behaves like a fade. I used it to gently fade my logo in and out before the game starts up. Of course, the user can just hit any key to skip it :).

Thursday, May 7, 2009

A Real Engine

The farther I got into the project the more types of games I was coming up with that could use the framework that I am creating here. Everything I've done is pretty generic so far, but it was coupled with the game logic fairly tightly (or rather, where future game logic will go). If I wanted to make another game using the same structure I would have to re-engineer a lot of the code to reuse it.

So I recently spent some time breaking the code apart and creating a game engine that is separate from the game implementation. I took all the code dealing with graphics and devices and sprites and placed it all in a separate .DLL project that I could include into the main project. This was a fairly successful endeavor. The main game project doesn't even include references to the DirectX libraries anymore, just to the engine .DLL. The game project can just create Scene objects using the Scene base class from the engine and just worry about managing sprites and logic.

For what its worth, I called the engine the same as my design 'group', the FirstLight engine. Sounding important is all part of the fun, right?

Tuesday, May 5, 2009

A Logo!



















I figured I needed some sort of logo for my development. Something that looked really official. A banner I could fly above my little game, and any future games I create. I came up with the name FirstLight Studios and put together this logo today. I'm usually fairly critical of my own art work, but I'm pretty happy with how this turned out. I know, I know...'studios' is a little silly as it's really just me in my pajamas banging out code at my desk, but I thought it sounded fun.

So, now when my game starts up the logo of FirstLight Studios can gently fade in, all professional like.

Sunday, May 3, 2009

Making a Scene

With my sprite abstraction layer in place I needed some larger structure that could manage groups of sprites and the application logic associated with them. What I ended up with was something I called a 'scene'. A scene would be some discrete function of the game, like a main menu, a map screen or a battle screen. Each scene manages its own sprites by registering them with the GraphicsManager and has an UpdateScene method that gets called by the main form on each game loop right before the graphics are updated in the GraphicsManager. All of this is handled by another interface called IScene.

I created a class named SampleScene which loads a single sprite into memory, my favorite blue dot, and handles the logic to move this dot with the arrow keys. When the enter key is pressed the scene tells the main form that it should load the next scene (which in this case is the exact same scene. The first scene is torn down and the next scene is created and away we go. On the screen this means that the blue dot just moves back to the starting location, but under the hood a scene has been swapped out.

Along with all this I added a few nice things here and there. Sprites and Scenes can dispose of themselves now to get their resources out of memory. This is done behind the scenes when a scene is torn down before the incoming scene is initialized. I also built out some factory classes for sprite and scene creation. Both need access to resources like the GraphicsManager to intialize properly so I wrapped all that up in the factory pattern. Requesting a new sprite or scene flows nicely now.

Quite a productive weekend!

Saturday, May 2, 2009

Abstract Thinking

As I mentioned yesterday, I set out to create an abstraction layer around the early graphics work I did yesterday and ended up with something I'm quite happy with. I worked and reworked my classes several times before I came up with something that seemed straightforward and hid the implementation of the graphics rendering well enough. There's still a few things being passed around that I'd rather not pass around, but I'm not too worried about it.

I now have a class called GraphicsManager which houses the Direct3D device instance. It's job is to setup the instance and handle the rendering of each frame in the game loop. The GraphicsManager is created in the 'static void main' class (which I named Launch) along side the windows form and is immediately passed into the windows form so the form holds the reference to it. GraphicsManager has a method called PerformFrameRender which the form calls in it's overloaded OnPaint event. That was the form doesnt need to know a thing about rendering any graphics. It acts purely as a container and pump to drive the game loop. Later, the logic loop will be driven from here too.

With this framework in place I can create sprites on the screen very easy with code like this:

BasicSprite sprite1 = this.graphicsManager.CreateBasicSprite();
sprite1.LoadSprite(@"../../images/blue.tga", 100, 200);
this.graphicsManager.RegisterSprite(sprite1);


I am requesting a BasicSprite object from the GraphicsManager, loading it with an image file and a screen location, and then registering it with the GraphicsManager. (I went round and round about creating and registering in the same step or seperate steps, but figured this was more flexible when it cames to preloading a ton of image data before pushing it into the pipeline).

All sprites inherit from an ISprite interface I created. This way the rendering of the sprite is up to the implementation of the particular sprite class, but the GraphicsManager can just loop through all registered sprites and draw them. Right now I just have BasicSprite, a stationary image, but later I can make things like AnimatedSprite and MovingSprite with this framework.

Friday, May 1, 2009

Baby Steps

Today I decided to start writing some code. Not code that will ever make it into a finished product, but rather some simple DirectX tests to get something running and compiling. And this, ladies and gentlemen, is the product of my hard work....
















Ok, so it's not much. There's a blue dot in the upper lefthand corner of the screen.

My understanding was that one would use DirectDraw for 2D sprite rendering and Direct3D for, well, 3D rendering. As it turns out, DirectDraw is completely depricated in DirectX 9, and may have been for several versions now. What I found out was that I should use Direct3D to draw images on flat surfaces. Fortunately this requires no 3D work at all and Direct3D has classes to facilitate this.

This little application bascially requests a full screen from the hardware with a back buffer to draw to. It would seem I do not need to manually draw to the back buffer and flip it to the front like I would in DirectDraw, Direct3D seems to handle that aspect for me. After a full screen has been presented I setup a sprite using a .tga file I created in GIMP (a blue dot in this case). Finally I overloaded the OnPaint event of the (full screen) window and told it to draw my sprite there. The OnPaint event ends by calling this.Invalidate() which basically means that OnPaint will be called immediately again, thus running a very, very game loop. Each time the screen is obliterated and the sprite redraw. Again, there seems to be a back buffer here but I'm not managing it. All the better. Our little application also overloads the OnKeyUp event so that an escape keypress will end the application.

This simple code will form the foundation of the graphics abstration layer. I need to wrap some classes and such around this so that these nuts and bolts aren't something I need to worry about as I write the game presentation and logic. I think I'll work on that next.

Saturday, April 25, 2009

Tools of the Trade

So, just what am I going to be writing this game in? Most games are developed in C++ I think, and while I could struggle through reacquainting myself with it, the prospect of managing memory pointers and the like makes me not what to go there. Java certainly seems popular in the Open Source space, so how about that? My Java skills are acceptable, but I've no idea where to start creating anything like a game in it. I've done Java web portal type things, but never graphics and the like.

So what do I pick? For me, it's C#. I use the language extensively at work and I have a good handle on it. I feel comfortable there; it's practically a second language to English. Yes, yes C++, Java and C# have virtually identical syntax, but the environments are so different.

C# isn't really the first thing that comes to mind when you think of Open Source, or games for that matter. There are, however, plenty of great Open Source projects in C#, and I am not writing the next great 3D engine here. C# may have overhead, but not for a game of my scope. Having fun and being able to get started quickly are high on my list here, and C# fits the bill nicely there.

Being as one of the challenges here is using Open Source tools I have selected SharpDevelop as my C# IDE. The install was impressively smooth and simple after installing .NET 3.5 SP1 (which actually took far longer). It was quick to load and the interface is very familiar to anyone who knows Visual Studio. I felt comfortable in it immediately. Makes you wonder why Visual Studio takes an hour to install when this seems just as robust and installed in minutes. Just loading it up made me excited to dive in. I threw together a Hello World application and everything seemed in order.

Next, I needed something in which to exercise my meager art skills. As a web guy I've used Photoshop plenty at work, and I had heard the the GIMP was the Open Source equivelent. Once again installation was a breeze and the program loading quickly and painlessly. I goofed off in it a bit, found my favorite Photoshop functions and declared victory.

Seeing these amazing, robust tools created for free by development communities was somewhat inspiring as I set myself to making this game. People really DO this stuff for the love of doing it, to contributing something to the world, and not just to make a buck. I'm glad I'm in good company.

Wednesday, April 22, 2009

Lets get this started

So, welcome to Developing Light, an open source game development challenge I'm posing to myself. See, I've always been a gamer and development is my day job, so naturally I've always thought that making a game of some sort would be pretty interesting. I've kicked this idea around for a while now, but never really acted upon it. Lately I've had a little game idea that I just couldn't shake so I decided to finally give it a go.

Now, I don't claim to have all the skills required to build a game. I'm a competent enough developer in languages like Java and C#, but this has mainly been in the web development space. Game development is a different beast entirely, so I'll have to learn along the way. I tend to think I have VERY mild artistic tendencies, and certainly can't do sound or music at all. That will all be a challenge too. I'll cross those roads when I get to them. I figure I'll take it a day at a time. If I stare off and look at all the things I CANT do, I'll never start and thus never accomplish anything at all (this, by the way, applies to most anything in life).

As for the open source part...well, I'm certainly not going to spend any money on this. I figured it might be fun to see what all I can do with free tools exclusively. In turn, whatever it is I create in this process will be freely released.

Now, in addition to skills and resources another thing I lack here is time! I'm a father, I work a steady job and I'm a raid leader in my World of Warcraft guild to boot! This leaves precious little time to go around developing masterpieces. Just another part of the challenge. I don't intent to stay up nights working on this. This is a hobby, something I'll do for fun. It may take a long time, but I'd like to see it through.

You may ask, "Isn't it a bit vain to be blogging about this?" Well, maybe. I figured my process of discovery here might interest people. I'll post about what I'm working on and what I'm learning. I'll post code samples for the geeks who care, and maybe get ideas from comments, should people ever read this. :). Its also accountability. If I'm keeping a blog up to date it will keep me moving on the project, as long and drawn out as it may be.

So here we go. I don't know where we'll end up. Maybe there will be a fun game I can release in a year or so. Or maybe I'll fail. Either way, it will be fun!

Next time I'll talk about the tools I plan to use.