![]() | ![]() |
|
Main
About:
Resources: |
C# and XNA ResourcesIf you are programmer, then you will find this page to be a useful collection of resources for programming in C# and XNA. If you find any additional resources that you feel should be included on this page, please contact the programming TAs. Learning C#While professional game programming is often done in C++, we are using the XNA game engine for class and thus must program in C#. Fortunately, you will find that C# is very similar to Java, and thus it is a lot easier to program in coming from a Java background. You will find the following resources helpful in getting started.
Beyond this, you should always feel free to pester the programming TAs with questions about C#. Learning XNAOnce you have mastered C#, XNA is pretty easy. XNA is just an additional set of API that extend the .NET framework. Because it is rapidly becoming a standard platform for teaching game design, there are an awful lot of resources out there.
XNA on your Home MachineOften people want to design games on their home machines instead of having to do them in the lab. In turns out that it is very easy to get XNA up and running provided that you have a copy of Visual Studio. You will either need a copy of Visual Studio 2008 (which is what we use in the CSUG lab), or Visual C# Express. We recommend that you use Visual Studio 2008, as projects created in these two versions of Visual Studio are not compatible with one another, and standardizing on Visual Studio 2008 will save you a lot of grief. While Visual C# Express is freely available, Cornell has a program by which you can get a copy of Visual Studio 2008 through MicroSoft Developer Network Academic Alliance (MSDNAA). You should have been given information about obtaining software from the MSDNAA when you received your CSUG account. Once you have Visual Studio 2008 installed, you should go to the XNA Creators Club for the instructions on how to install XNA on your machine. Libraries for XNAOne of the advantages of using a platform like XNA is that there is a large enough developer community that there are lots of libraries out there to help you do cool and unique things with it. The advantage of this is that you can leverage these libraries to solve your technical, game engine problems, and hence focus more on making your game fun. In this section, we present several libraries that you may find useful. Over the course of the semester, we will add more as we discover them. Physics EnginesOne of the most difficult parts of a modern game is the physics engine. Even more than graphics, this is one of the advantages of having a 2D game, since 2D physics is simpler than 3D physics. It also means that there are likely to be a lot of free physics libraries out there (unlike the 3D engines, which want some serious money). The preferred library for this class will be Box2D X, a port of the famous Box2D physics engine; we will eventually have a lab covering its use. However, there are several other alternatives to choose from. Each has its advantages and disadvantages.
Programming for the Wiimote in XNAThe Nintendo Wii is one of the more interesting game consoles to come out in a long time. A lot of the excitement has centered around the "Wiimote", a motion sensitive controller that uses acceleration and infrared sensors to determine its spatial position. This allows for highly innovative games, though designers are still struggling with how make games that effectively leverage the controller. While XNA does not allow you to design games for the Wii, there are XNA libraries that allow you to use the Wiimote with a PC (even if you do not have an actual Wii). There are several resources available online to get you started with this.
Designing a game for a Wii is definitely one way to satisfy the "innovative" requirement for this class. However, in order for it to count as innovative, you have to use the unique features of the Wiimote. If you are using the Wiimote in a way that could be easily be emulated by a D-pad style controller, this is not particularly interesting. Important Programming TipsPerformance is very important in game programming, and you will often find yourself optimizing your code. However, there is always a balance between performance and readability. The following tips should help make easy to maintain code while avoiding some of the more basic performance pitfalls. AssertsAsserts are a nice way to make sure that your program is behaving the way that you expect it to. Whenever you assume that something is true, you should call the method Debug.Assert() to make sure that it really is true. For example, suppose you assume that the player's health is greater than 0. Then you should add the line
Other good things to assert are 'target != self' and 'level != null'. Note that the assert has a text message which it displays if the assert is not actually true. Look at the documentation for Debug.Assert() for more information. If you're not familiar with the concept of asserts, this might sound like unnecessary extra work. However, getting in the habit of using assert is one of the biggest timesavers possible. It basically corners bugs before they can even happen. As soon something you assert fails to be true, you'll be told when and where. On the other hand, if the assert hadn't been there, (unless you get lucky) your game will keep running, some completely unrelated code will screw up, and you will have no idea why. Note that asserts do not even get compiled in optimized Release builds, so your game will not run any faster if you don't use them. CachingThe primary performance problem is often doing unnecessary computation in the Update() or Draw() method. These two methods are the ones that are called every animation frame, so the less computation you do here, the faster your game is going to go. The most common pitfall is to perform computation that never changes between animation frames. For example, suppose a space ship has size size, and every frame, you want to draw a target sqrt(2)*size away from the space ship (thus the target scales with the size of the ship). Computing this number is expensive every frame; the sqrt function is not cheap. It is much better to make an additional field targetPos and set it equal to sqrt(2)*size in the initialization method, which is not called every frame. In this case, you are caching the computation in a variable, so that you do not have to keep doing it every frame. A note about doubles and floatsNo matter what you might hear, doubles are slower than floats even on current (circa 2008) systems, and they take up twice as much memory. You should use floats instead of double in your game, except where extremely high precision is absolutely necessary (which, in this course, is basically never). When you type a decimal number in your code like 0.5, that automatically means it's a double. You should instead type these values like 0.5f (append an f to the number), to tell the compiler it's a float and not a double. In general, you should also always use functions that require floats instead of doubles if at all possible. Unfortunately, the Math functions in C# all use doubles, and there does not appear to be any float versions of these functions. Therefore, you should be very careful how you use these functions, as type casting between a float and a double can be very expensive. You should cache these computations whenever possible. Another feature that you will find with floats is that you may be tempted to compare two floats with the "==" comparison. This is fine and valid if you know they can be exactly the same, but in many cases all you really want know is whether the floats are within a certain range of tolerance within each other. In order words, you often want to test
instead of
If you are relying on super-high precision for your game to work (e.g. you absolute have to use '=='), you are doing something wrong anyway that high precision will not be enough to fix in all cases. Magic NumbersA "magic number" is any numeric value in your program that has some semantic meaning, such as the window size, or the player starting health. Magic numbers are very confusing and often hard to debug. And they appear a lot in graphics programming. Whenever you find yourself using a magic number, you should use a constant instead. For example, we used a magic number in our discussion about comparing floats. We should have written
where EPSILON is some constant that we defined telling us the amount of tolerance we have between floats. That is it for our tips right now. We may add more as the semester progresses. |