Hello there! Welcome to Programming Shenanigans! This is a blog documenting the trials and tribulations of two novice programmers as we try to navigate the weird and wondrous world of game coding.

Pages

Tuesday, May 18, 2010

Game Logic of Tetris

So when you think of a way to implement Tetris, obviously using an array pops out at you right? Siva seems to think my use of arrays in this game is blasphemous. The basis of my game logic coding started at designing a class to encapsulate the object the player manipulates. I extended the Sprite class previous created and added a bunch of fields to store various data needed to keep track of a single block in the grid. The main game world would be an array of these objects. All the handling of the seven tetriminos would be on a block by block basis, rather than manipulating a 4 block object all at once. In retrospect, the way I designed this is vastly inefficient and contained an enormous amount of hard coding. But for a game like Tetris, I really still can’t think of a better way.

Once the game state entered the activegame, the first thing the game would do, is instantiate the playing field. This consisted of rendering the HUD that contained simply a window for the game world array, a fancy little title and a window to display what the next block would be, standard Tetris stuff. It would than create an element in every position in the rectangular array. The reason for this was twofold. First, when I was designing this system, I thought, though it may not be much, perhaps it might be more effective to pre-create all the blocks at the beginning of the game and never have to worry about creating and destroying objects throughout the code, it might even improve game performance during play, since that piece of CPU allocation never had to be dealt with again for the lifetime of the game. Though that seemed like a valid train of thought, I retroactively came to the realization that memory is a much more precious resource than CPU; objects should only be in existence when required.
But what’s done is done, that is how the system is. So the way I differentiated between my various blocks was through the use of an int identifier. A field inside the block class would keep track of the color code of the block. Each color co-responded to a different tetrimino. This color code would also be kept inside a global variable, in the form of Currentcode and Nextcode. The second variable contains a randomly generated number that displays an image showing the players what the next block would be. Once it’s time for the next piece to drop, the Currentcode is set equal to the Nextcode, and a new number is generated for the NextCode.

The game itself runs even without user input. The active block is always falling down. What the user can control however, is whether or not the block moves sideways at all, as well as the ability to speed up the rate that the block can fall. For the blocks fall speed, I had a counter that read the GameTime and would only allow the block update method to run once every second. User input would change the time the amount of time in between each update cycle, in milliseconds.

The way the lateral movement was implemented was to check for one of the left or arrow keys to be pressed. One key press would allow the block to shift one column over. In retrospect, I should have implemented the lateral movement the same way I did the vertical movement. Where keeping the side arrow keys depressed continuously would allow the game to call a lateral update method periodically.

The rotation of the blocks is a completely hard coded feature. For a specific block, in a specific orientation, where would each of the 4 blocks go in the next rotation. For laziness sake, only clockwise turns were implemented. If I were to redesign this, I would have used a database of this information that would have been called by various turn methods, rather have hard coding nested If statements.

One problem I encountered was that when I tried to replace the contents of one block with the contents of another, the objects would be passed by reference. As of the writing of this post, I’m still unsure as to how to fix this. The hack that I had to put in was to individually update the fields of the blocks.

I hope this provides a good introduction of the thought process I went through when making this game. I apologize for the lack of detail, seeing as I only thought to write this all up after the fact. For my next project, documentation is a priority.

Sunday, May 16, 2010

Tetris - ROTATIONS

So, the hardest thing about tetris, and by hard i mean tasking... Brute force checks. The game is simple enough that it doesn't require an abstract rotation routine, having brute force checks for each block is efficient enough (BUT NOT VERY FUN TO CODE :( !!! )

What i did was, to make a routine for each block that calculates where each of the 4 squares (all tetris blocks are made of 4 squares) would rotate to. I.E. what to add to x,y values. As you can probably guess, the worst case scenario has 3/4 blocks moving with 4 orientations for each block! Lots of horrendous brute forcing. The worst part was all the checking, in bounds and not over other blocks, that had to be done as well.

Initially, we had the idea of having a BlockKeeper (4x4 class of squares) that would fit al the blocks within it resulting in a common usable rotation between them all. However, deciding it would be better to have individual blocks, we scrapped that idea. Horrid.... Must have stuck to that plan. GENERALIZATION IS GOOD!


Need too make more general methods to override for later use!

Thursday, May 13, 2010

It's all about that score

So in my last post, I discussed getting a Menu Image to display on the screen. At this point, we must add some functionality to the program. First, consider the situation the game is in. When you take in user input to either start viewing the high score or being paying the game, you no longer care about anything that happens in the main menu, you only care about the things that occur in the option that the user chose. So in this way, we should keep all 3 of these states separate. In the past, I had always used simply an INT variable to keep track of the state, performance wise, it’s a good idea, however for maintenance and code legibility, I decided to create an ENUM to encapsulate the 3 states that I wanted my game to be in. The first state would be the main menu, second would be the game, and third would be the hi-score window.

One major advantage in using these states is the way the Update method is called. There is only one update method that constantly runs, but using states, we can put all 3 modes into one method, and then divide the method into 3 independent sections that run only when an the variable tracking the state passes each of the respective modes.

Moving to another state

Within the update method provided, each of the three modes will have a method that is called only when the mode is active. The method for the hi-score mode is the one I chose to start making first, for the obvious reason that it is infinitely simpler than the game mode. For storing a high score, I decided to record the high score in arrays containing the name and score.

As far as printing it on the screen goes, that was a more difficult task. In beginner programming classes, you were heavily dependent on Conesole.WriteLine(“”) to give output. In XNA, no such method exists. There is a similar function, albeit one that is far more complicated. You call it from SpriteBatch.DrawString();. To be able to use the Draw String method, you must first create a font object and load a font into it. It is done much the same way as one would load an image into a Texture2D object. Now that we have a hi-score in the game, we must find a way to track the high score even when the game is off. I did this the only way I knew how, by storing data in a CSV(Comma Separated Values) file. The high score update method would check for the existence of a CSV file that stores the current hi scores. If no such file exists, it would then proceed to create one and initialize all values as something standard. Reading and Writing external files is done using the StreamReader and StreamWriter classes.

And finally for the high score state, you have one last method that checks for the ESC button being pressed. When it detects this, it changes the mode variable back to main menu. And thus, the high score mode won’t run on the next cycle.

Wednesday, May 12, 2010

Let’s get the balls rolling with Tetris

Or perhaps let’s get the blocks falling. For my first attempt at an application of the skills I learned on the website I mentioned in my last post, I decided to go with a classic, Tetris. There are two reasons I chose Tetris. First, I’ve been playing Tetris for years, I feel that I have a firm grasp on the gameplay mechanic. Second, the premise of the game is simple, falling blocks that line up to clear lines. I felt that coding this would be much easier than something more recent. Tetris comes from an era where game hardware was really limited. My coding limitations sort of match that?

Despite what I just said about Tetris being really easy to program, that is a misconception that I quickly dismissed, in abstract terms, it’s easy to understand, but when you break it down into code, there are so many steps to consider in even the simplest step of the game. It’s scary to think about how bad a game like Pac-Man might be, where there is AI involved.

Regardless, I felt that diving headlong into coding the gameplay would be redundant. Seeing as this whole project is a way to push my programming experience, I felt that I should really try to reproduce Tetris in its entirety, not just the gameplay of it.

When taking on a project of this magnitude, there should always be a fair amount of planning before the first line of code is written. I only realize this in hindsight. Though my professors always stress the importance of this, It never really sinks in until you experience it all for yourself, more on that in a later post.

Like the noob that I am, I just jumped right in and created a game project in Visual Studio without much planning, hoping to wing it as I go, I had a rough idea of what I wanted to do as I went along. The first thing I wanted to do, was to display an opening screen onto a window. To allow this to happen, I recreated much of the Sprite class that was covered in those tutorials I mentioned in the second post. For those of you who haven’t read that tutorial, I will run over the key concepts of that topic.

Sprite Class
An object of the Sprite class will have various variables and methods available to it to allow it to be able to display a 2-D image onto the game window. This will be a super general object that really has no function to it. The sprite class will be widely inherited to allow for Sprite objects that are really far more beefed up and are really the core of what I used to build my game. Though, in the future when the games get more complicated, it may not be wise to inherit the Sprite class to create your gameplay objects, it might be more prudent to create Sprite objects inside your more prominent classes.

To see the specifics of this class – take a look at the Source Code I will upload.
At this point in my programming, I did not know how to print Text to the screen, So I simply printed an image with pre-rendered Text on it.
I’m going to split the discussion of the Tetris project down into smaller posts, So that you guys don’t have to deal with giant walls of text.

Getting started with XNA

When I first started thinking about advancing my programming ability a few weeks ago, I really had nowhere to start. Reading the C# textbook for hours on end really felt like a battle of attrition, in comes the words, and out goes the knowledge, nothing stuck. Programming just isn’t something you can learn by reading someone else’s work. Of course there are the moments where you can gain valuable insight by seeing a snippet of somebody else’s code, but more often than not, the only real way to learn programming is to open up an IDE(Integrated Development Environment) and start coding away.

So there I was, filled with ambition and completely clueless. My first train of thought was “hmm okay, making games, let’s forget about gameplay for now, and start basic, draw a dot on the screen, and control it with arrow keys.” Of course that was a far cry from anything I had previously done in class. No matter how advanced my coursework got, it was always still just console applications. Feeling overwhelmed, I decided I would consult a friend of mine who was more experienced than I in this field. His interest in this was enough that rather than just giving me advice on this, he is now my partner for all future developments, all documented in this blog.

Though more experienced than I, working on something of this nature was still outside his field of expertise. When in doubt, hit the Google button. It’s a philosophy I follow almost religiously. After spending maybe 5 minutes on Google, I found the website that would allow me to get a foothold on game programming, http://www.xnadevelopment.com/. This blog has excellent tutorials starting from complete scratch and advancing all the way to what I considered at the time advanced programming techniques such as RTS style unit selection and a primitive manner of 2-D collision detection.

While running through these tutorials, you really feel as though you accomplished something. From only programming applications that run in the console, to seeing your little wizard guy shooting fireballs, is an amazing moment. The XNA framework takes care of a great amount of grunt work required to make a game. So the transition isn’t as bad as many would think.

Beginning of the Shenanigans

Why hello thar,

For the first official post of this blog, let me tell you a little about myself and my partner. My name is Xin, We are soon to be 2nd year Electrical/Computer students at University of Waterloo. I am a complete novice at programming, my only exposure to the field is really the one course that I took after entering university. The code I post and the points of view i put up will reflect that. My thought process will be that of somebody figuring everything out for the first time, any beginners reading this will feel right at home with the level of content that I post. For those more advanced, who knows, maybe I'll be able to give a fresh perspective on a tired subject. Feel free to comment and criticize my work.

The language that you will be seeing all our code in will be C#, as that's what we use in school. In the future, we might switch over to C++, but that's distant in the future, mostly owing to the fact that we will be using Visual Studio to do all our work in. We will be using the XNA framework to code all our games for the foreseeable future. XNA only has full support for C# so we wont be leaving C# until we're good enough to code without depending on the XNA framework.

[Siva] Hey Hey!

Hey guys, i'd like to start off with a little background knowledge about myself.

Currently, i am a 1st year computer engineering student at Waterloo University.
I recently finished my co-op at IBM Canda, and am now back to the toils of classes.

So, what do i know?
I've got a working knowledge in developing in C#, C++, Java.
Some scripting knowledge of Perl.
OS: Windows (2000, XP, 7) Linux (Ubuntu 9.x, SLES 10), MAC (OS X)
Virtualization Experience (I must post a note about my Win7 wd seamless ubuntu desktop!)

Current project: XNA

This gaming designs have really perked my interests. We (Xin and I), have a working model for Tetris. However, plenty of sparks going on in the factory.

You know what would be really cool? Porting SC2 map editor into XNA, and seeing what random fun we can do!

That's that, hope to keep you all updated frequently, and release a TON of projects.

Cheers,
Siva

Followers