Showing posts with label game programming. Show all posts
Showing posts with label game programming. Show all posts

Saturday, March 27, 2010

Game In A Day - "Free Fall"

A theme I've done twice now is "Game In A Day" in which I sit down and create a brand new game from scratch in no more than 24 calendar hours. This post will outline the first such "Game In A Day" experience which took place a little over a month or 2 ago...

I'm huge into music. I play guitar, and I can't accomplish much of anything without my favorite tunes on. As I've mentioned in another post, I've always wanted to create a game based entirely around music. I coupled this desire with my desire to make a brand new game from scratch in less than 1 day. The goal: Create a game that is inspired and based around a single song, and do it all in 1 day.

The Tools
Due to the time constraints and past success with the language/library, I chose to use Python along with the PyGame API for this project. PyGame is really just a front-end for SDL with some added goodies. I use SDL extensively from C++, so PyGame feels very comfortable to me.

The Song
As for the song, that was a harder decision. I loaded up about 5 band's worth of material, turned my monitor off, turned my lights off, and paced around for about an hour trying to find something that screamed, "Game!" to me.

After a while, I decided on Dethklok - Comet Song. It is very fast paced and evokes a sense of urgency and thrill, 2 emotions perfect for a game.

You can check the song out here:
http://www.youtube.com/watch?v=kRQ47oEbA6s

The Game Design
Using the flow of the song as my guide, I started to picture an environment in which I was under constant pressure to evade and/or maneuver. The more I listened to the song, the theme of being in space (as is the theme for the song) started to appeal to me. I decided to design the game around this idea in the following ways:
  • The character will be falling through space
  • There will be objects coming at it with varying rates of speed that it must avoid
  • The character will only have 2 controls: move left, move right
  • The goal will be to stay alive as long as you can, earning points the longer you're alive
Pretty simple, but definitely has the potential for some fun, and it fits the song perfectly.


The Game Implementation

Parallax
Right off the bat I knew I wanted to create some sort of parallax effect. I had never implemented it before, and creating a game in 1 day really isn't that difficult, so I wanted to add some level of challenge to it, as well as gain some experience doing something cool like parallax.

The idea behind parallax is that you create the illusion of movement by layering background images on top of each other, giving each a different speed (and some layers don't move at all) to give the illusion of distance and speed in relation to the character.

I spent probably more time designing and tweaking the parallax than I did on anything else in the project. I wanted to fake the character's fall through space by creating the parallax in such a way that the character would only ever move left or right, but the outer space background(s) would move from the bottom of the screen to the top of the screen, thus creating a falling effect.

My final design was as follows:
  • For each background image traveling at a particular speed, there needs to be another background image traveling at that same speed. The image can be different, but the speed must be the same. The images are the exact size of the screen coordinates.This second image will be offset from the first one by a distance of the height of the image (SCREEN_HEIGHT). The reason for this is so that as both images move towards the top, there will never be a gap in backgrounds before the second half of the pair appears on the screen.
  • Apply 1 or more static background images to create points of reference for the character
  • Have 2 pairs of moving layers: a fast pair and a slow pair. In my implementation, each pair had their own image, but the image was the same within the pair. The images were just basic star maps I made in The Gimp using various colors and sizes of dots placed randomly around the image.
  • Once an image has moved from the bottom of the screen to the top of the screen and then completely off the screen, reset its position to its original starting position (either y = SCREEN_HEIGHT or y = SCREEN_HEIGHT * 2)
That's basically it. It took a lot of tweaking to get it to that level, but in the end it's pretty simple, but does the job nicely for this project. Horizontal parallax is a bit more involved, but not too far of a reach from what I've done here.

Asteroids
Since we're in space, I figured what better obstacle than asteroids and space debris? I browsed Google Images for something I could work with and then doctored it up in The Gimp. I essentially cut my own shape out of an image of a real asteroid and then colorized the image with a nice bright color. I ended up with 4 different colors if I recall correctly and they actually look really nice.

Next, I had to decide where the asteroids would be "attacking" from. I toyed with the idea of having them come from every direction, but felt this would make it too difficult. Then I thought about maybe just up from the bottom and down from the top, but in practice, it took away from the parallax effect and it was no longer believable that the character was falling. I settled on just having the asteroids appear at a random X-value at the bottom of the screen and head upwards toward the player and I'm very happy with the result of this.

I also had to determine how many asteroids I wanted to generate on each update of the game loop. I just went simple and kept track of the number of updates and used the modulus function to only generate an asteroid every 5 updates and it works surprisingly well.

The Character
Next, I needed a fun character to play the main role in the game. I ended up deciding on a cute little leaf. It fit the theme of falling, and I thought there was some neat stuff I could do with a leaf in the game. When I threw the leaf in initially, I knew I had a problem: Only allowing left and right movement wasn't selling the parallax at all.

I essentially had a static image that would just move in a straight line from one side of the screen to the other. So, what could I do? Hey, it's a leaf, how do leaves fall? They sway back and forth, right? So, my leaf should do the same! I used the same modulus trick to tackle this one, and every 5 updates I would rotate the leaf image by 90 degrees. This gave it a nice floating, flipping effect as you see leaves demonstrate when they fall. Once again, modulus saved the day!

Scoring
For scoring, I toyed with the idea of adding objects that you wanted to collide with (power-ups, bonuses, etc...) and the player would get points from those. I tossed this idea because with the random nature of how asteroids were being created, it would have proved difficult for the player to obtain these power-ups. I decided to just award points to the player for staying alive. I got lucky and picked some value multipliers at random and they ended up working out and I stuck with them:
  • The player has 3 lives
  • 1 point is added to the player's score on every game loop update
  • 100 points are deducted for colliding with an asteroid
  • On your 3rd collision, no points are deducted, thus allowing you to finish with the amount of points you've obtained since your last death.
The idea here is to facilitate high scores to keep the player excited and interested in beating their high score. With the scoring and lives, I had to go and implement a simple HUD (heads-up display). It's pretty basic and renders the number of lives (complete with mini images of the leaf) and the current score in the upper-left hand corner of the screen, and the high score in the upper-right hand corner of the screen.

Extras
After some play-throughs, I realized how fun and addicting the game was. It lacked one key thing though: score persistence. I found myself wanting to beat my high score, but only to find that I couldn't keep track of it! I whipped up a save and load mechanism to keep the player's score on disk. I also added the ability to play again once you died instead of having to restart the game.

Conclusion
This project was a total success. I finished the entire thing start to finish in under 10 man hours, and that counts dallying around with images! I'm very pleased with the outcome in terms of the goal I set out to achieve, and honestly didn't expect the game to turn out to be as fun as it is!

Screenshots

Tuesday, July 28, 2009

Designing A Hockey Power-Play System: Part 3

I finally found some time to sit down and revisit this problem. I made the decision a few days ago that I would wake up and devote my entire day to solving this problem once and for all, and I did just that. I realized that I had been going about the problem in the wrong fashion, which is why I never seemed to be able to come up with a solid solution.

If you haven't read the other 2 posts on this topic (or if you haven't read them recently), I suggest you do that now in order to get a good grasp on the evolution of this design.

Part 1
http://zachelko-gamedev.blogspot.com/2008/07/designing-hockey-power-play-system.html

Part 2
http://zachelko-gamedev.blogspot.com/2008/07/designing-hockey-power-play-system-part.html

To summarize though, my initial thoughts were to design some sort of power-play "system" which would encapsulate all of the tricky details of managing complex penalty situations. At first thought, this seems logical. In software engineering we commonly encapsulate complex things into easy to use interfaces. However, something about this particular problem just wasn't meshing with this approach. You see, the most complicated part of a power-play situation (or set of power-play situations) isn't managing the players who commit the penalties (taking them off the ice, the length of the penalty, placing them back on the ice, etc...). Instead, the complex part is informing the user of the situation via the HUD (heads up display). The behind the scenes work is simple because you simply set a timer for each player who commits a penalty, draw him in the penalty box for that duration, and when it expires you place him back on the ice. With the HUD, you have to verbalize to the user the exact situation that is currently in effect (5 on 4, 5 on 3, 4 on 4, or 4 on 3), and the duration that situation will last. To do this requires knowledge of all other currently running penalties. When you start to think of all of the permutations, you'll get a headache.

So, how did I alter the design to negate these issues? Simple: I solved the problem procedurally. Instead of using an object-oriented "system" approach to nicely encapsulate away all of the nastiness, I simply broke the problem set down into very simple functions. It took some detailed doodling on paper to get things right, but if you can't make an algorithm work on paper, you'll never get it working in code.

Here is the algorithm I came up with:

  1. Maintain a list of times that represent penalties that are currently being served. Tick each of the times in the list once every second (elapse time)
  2. When a penalty occurs, remove this player from the ice and add his time to the list of penalty minutes.
  3. Count the players on the ice for each team (should be a simple call to a size() function on the container they are held in for each team)
  4. Set the situation timer (5 on 4, 5 on 3, etc...) equal to the smallest remaining time in the penalty times list. We use this time because as soon as a penalty expires, the situation will change, so we choose the time that expires soonest.
  5. When a penalty expires, place the player back on the ice and repeat the process of counting players and setting the situation timer.
If the situation is 5 on 5, no display needs to be shown. Also, whichever team has the advantage, the situation label will appear under their label on the screen. For example, if the Penguins have a 5 on 4 power-play advantage, under the team label "Penguins" on the screen, the text "5 on 4" would be displayed. If it is an even strength situation (but not full strength), the display can be shown in the middle of the 2 labels. This all depends on your interface and isn't really important as far as the algorithm is concerned, but it does have to be accounted for.

The problem seems so much simpler once it is broken down into 3 or 4 very basic functions. At first I felt it odd and maybe even "hacky" to count the players in this fashion in order to display the situation, but then I realized that the serving of the penalties and the HUD are two totally different issues, so trying to put them into one solution was pointless and just led to more problems. I also believe this solution is very fast and light-weight. Consider the fact that you are adding the penalty times to a container of some sort. If you always insert them at the back, and tick each one every second, you can guarantee that the penalty which will expire soonest will always be in the first position. No searching, no sorting. Just grab the first element and you can set the situation timer. And as I mentioned before, chances are the players on each team are in some sort of container themselves, so "counting" the number of players simply means calling a size() function on that container which should be as fast of an operation as possible being that it is a standard library function (not to mention there are < 20 players on a hockey team... =p ).

Hopefully this has been helpful to someone out there. I'm putting the finishing touches on the code, so I'll post some screenshots of the demo in action once I complete it.

Monday, July 21, 2008

Intrigue of Game Design

I was thinking about this the other day, so I wanted to get it down here. What makes game design / programming different from all other types of software development? Sure, it tends to be more difficult due to the melding of many forms of technologies, different programming/scripting languages, advanced math, physics, the list goes on. But I'm getting at something else entirely.

The thing that intrigues me about game programming is simply this: As the developer, you have the ability to write some code, that when finished, can be able to provide endless fun and entertainment. The whole idea of writing something once, putting it on a disc or into an EXE and sending it out, only to be able to play that game and "create fun" each and every time you play it in new ways is really astounding. The game that really got me thinking about this was of course Grand Theft Auto. Therein lies a game in which all the work has been done, disc printed, shipped, sold. From there, anyone who plays this game can create their own fun, their own experience, and can do so for an unlimited number of years. All of this can be separate from what the makers of the game "intended" you to do, or it can include those elements as well.

Another way to think of this is that someone can create something, and from that something, they can turn it into anything they want. Think about a car. The car maker produces this vehicle to get its customers from place to place safely. The customer can then take that car and choose to do anything they want with it. They can race it, enter it into demolition derbies, enter it in car shows, use it to transport materials, etc... It's a limited example in comparison to Grand Theft Auto, but the same motif of creating a system of some sort, and then being able to jump into that system and envelop yourself in it, creating fun and experiences as you go.

Clearly, not every game is cut out for this type of adaptation, but I believe elements of this are possible in nearly every game. Keep this in mind as you design your game. Ask yourself, "Can the players of my game use elements inside the game to create their own fun/experiences that I didn't explicitly program into the game?"

-Z