Tuesday, February 21, 2012

Making of an Arcade Frontend - Part 3

Last part of this series I talked about how I started coding up the arcade frontend based on translating the features I wanted into tasks the program has to do. One thing I want to do when starting any project is work on tasks that provide the most benefit for the least effort. The strategy I used in the previous part was to pick a task that was needed for a lot of features to work (finding information on games to launch.) The final result is a nice skeleton which I can build the launcher around.

Today I'm going to talk about a second method of getting a lot of visible bang for your programming buck. That is by finishing tasks for the most visible features in the program. In short, make the user interface before other stuff. The first method (finding common tasks and doing them first) is roughly the same as bottom up development for those into jargon. This method of building programs is normally known as top-down development.

If you don't get the names try to imagine a program being like a cake. Top-down means starting with the icing and decorations while bottom-up means starting with... well... with the bottom. Both methods have their gotchas. building from the bottom up tends to mean you have something unappetizing until you're all done your work. But, building from the top down means you have a hollow shell made of icing and fondant. It looks complete and appetizing but its missing everything that makes it a cake.

With that in mind I prefer to do both at once. This way of doing things doesn't translate very well into my cake analogy. The closest idea is to build a cake one slice at a time. What you get is kinda tasty, but obviously incomplete. You end up with something that can be released very quickly that gradually improves until you're done.

Anyway; enough about cake. Let's talk about the arcade frontend... I'm going to create a graphical menu to pick out a game to start. I drew inspiration mainly from the rotating song menu in Dance Dance Revolution. Playable games will show in a semicircle with the selected game in the middle at a larger size than the others. selecting a new game rotates the menu and you can rotate forever in either direction.


To get the right look requires a bit of math. placing the titles vertically is simple... sort of. Dividing the screen's height by the number of visible items will give you the amount of space each item can take. If you take that number and halve it you get the distance to the center of each space that can be used.

Now, I'm guessing a few people are asking why I need the center of the space where each item goes at all since PyGame draws images positioned at their top left. The reason is that the center of each item will stay the same no matter how large or small the item gets. It's very easy to calculate the top left of the image by subtracting half of the image's size from its center. It's not so easy to calculate the top left of the image relative to the top left of the  The image below shows this better than words can.
Another thing to note is that I'm using an odd number of games in the visible part of the menu. This way there's one "middle" game which is the selected game and an even number of other games around it. Having an even number of games would result in the selected game being off center which looks ugly.

Placing the titles horizontally requires a bit more math knowhow but not much. If you remember your trig class you might recall that the sine function looks like a smooth set of waves like this.


Source: http://images.yourdictionary.com/sine-curve

In programming the sine function usually uses a unit called radians. Radians are how mathheads measure angles. You can do some cool tricks with them once you get it. The important part is that half a circle (180 degrees) is equal to Pi (3.14159...) radians. The cool part is that sine between 0 and Pi radians looks exactly like half a circle. In fact the value of sine at any angle matches how far you are from the center of a circle vertically at that angle.

With that all that needs to be done is to multiply the item number by Pi then divide it by the number of items that are to be visible plus two, put that number into a sine function, then multiply the result by the radius of the circle. Why plus two? In order to support spinning between games an extra game is to appear offscreen and slide onto the screen when changing selection. If we don't take these two items into account games coming onscreen from the top or bottom will wobble to the left or right.

Here's the result of all that math

Not too bad eh?

Next entry I'll be showing some code and talking about how to handle transitions between titles. I'll also show you the code that this entry produced as well.