I've recently been doing a lot of working involving audio on the iPhone and iPad. I thought it would be cool to make a multi-touch software keyboard. Making an on-screen keyboard has two main challenges: Laying out the images of the piano keys correctly and handling multiple touches accurately.
Laying out the keyboard:
There are two ways to lay out a keyboard: programatically and manually. To lay out the keyboard manually, you would create a new view in interface builder; then add the images of the keys to the view setting their positions manually. This is easy, but it lacks flexibility. If you want to add more keys, you would need to do it manually. If you wanted to change the scale of the keyboard, again, you would have to do it manually. After some consideration, I decided to lay the keyboard out programatically. To do this, you just need to loop over the number of white keys in the keyboard. For each loop, you create a new white key image and increase it's x-position by the necessary amount. After that you add the balck keys - the position of the black key is a bit more complex to work out and will depend on the dimensions of the images you're using for the keys:
CoreAudio is really badly document. On my blog I've been trying to get some good documentation out there to help aspiring audio developers. In this blog entry I'll show you how to set up an N-Band graphic equalizer using CoreAudio.
I'm not going to go into setting up an AUGraph here. For that look at my other tutorials. In this page I'm just going to explain how to use the NBandEqualizer module.
First do the standard setup for your module i.e. create the module, add it to the graph, set up connections to other nodes and then start the graph.
Shape Workshop 2.0 is taking shape rapidly and very soon I'll need testers to help with the beta testing. If you're interested please send an email to: firstname.lastname@example.org with the email subject "Shape Workshop Testing". Then, when the time comes I'll send you details of where to download the new version of Shape Workshop. As well as getting first access to the new version which is hugely improved, all active testers will discounts on the final version when it's released.
I thought it would interesting to write about some of the traps developers frequently fall into. Hopefully, reading these articles you'll be able to avoid these development pitfalls.
In software development there is always a tradeoff between flexibility and complexity. When you're designing a component to be flexible you need to think about all the possible cases where you might want to use the component in the future. Rather than just writing a date you would create a date object. It's clear that this kind of abstraction will lead to more lines of code. It's also clear that, if well written, this new date object will be re-usable in other projects. As the date object develops it will become more flexible incorporating new date formats until it becomes a 1,000MB juggernaut like the Drupal date module.
I'm not saying that flexibility and re-usability are bad. In this article I'm going to highlight the importance of keeping things in perspective.
Lets look at real world example. Lets say that I'm buying a car which I'm going to use to drive to the shops and back. A small cheap car could do this for $10,000. But wait! Since I'm buying a car, and since I'm spending $10,000, I should probably think of other scenarios where I might use the car. What if I have a family - then I'd need a family sized car. And, what if I decide I want to go touring in South America. Then I'd need a 4x4 with air conditioning. Ok, while I'm buying a 4x4 I might as well buy one with a winch and snorkel for fording rivers and seven extra tyres in case I get stranded in the desert… This is obviously ridiculous in real life so why do developers do something similar in software?
I need a text box… Well I should really think about the future. The text box is going to be part of a form and I don't want to have to type out the text box every time! I'll create a Form and TextBox will be a sub element. I'll have a weighting for the text box which determines it's position in the form. The name of the text box will be mapped to the database field. I'll create builder method to create the form from an XML document which I can create in my form builder application… Which I'll write! That way I won't have to do any coding to create my forms.
I know this is a bit over the top but it really does happen. For some reason, lots of developers have a kind of phobia for writing boilerplate code. They prefer to write a thousand line form manager class than spend half an hour writing out a form manually.
I spent some time working for a technology company. Their main product was a piece of software written in an ancient programming language from the 70s. The code editor for this language was a green on black terminal screen and was originally designed to accept code from punch cards!
I started working on Shape Workshop because I needed a good 2D level design tool for my iPhone levels. I searched the internet but I couldn't find what I was looking for. There were tools to create tile maps and some complex "generic level design" tools which purported to do everything. But nothing was an exact fit. I wanted to create free-form physics driven levels. The levels in Angry birds demonstrate what I mean. They are composed of arrangements of 2D objects which respond to physics.
In my search, I looked at a number of commercial solutions namely Physics Editor and Game Level Helper. Physics Editor a great tool but it's limited. It only lets you trace sprites - something which, in itself, isn't very difficult. After you've traced your sprites you to tessellate them (pretty fiddly) arrange them in your game manually. To me, that sounds like a lot of effort. Also, it only accepts sprites which isn't much good if you want to create a path based like the levels in Bike Ride. Overall, program is well written, pretty intuitive and does what it says it does. However, for me it's a bit limited.
I downloaded Game Level Helper but I didn't get on with it. For a start, it crashed the first time I tried to create a new project. Despite the flashy website, whole thing just felt sluggish and buggy. With these disappointments I started building Shape Workshop. In the new year I got to a point where the program was working and most of the basic functionality was complete. At this point however, I had other commitments so I tested the software and released the beta version. I hoped that it might be useful to someone and I also wanted to get some feedback. Generally, the feedback I got was good however people wanted more export options, undo redo, shortcuts and a more intuitive canvas i.e. drag to rotate. These were things I was always planning to implement but just hadn't had time.
There are lots of great games in the app store which don't sell. I've read numerous forum posts from unhappy developers who are only making several dollars a week from their games. Granted, some of these games are pretty poor quality but I've also seen games which taken a lot of work to put together and still don't sell. None the less, these developers move on to the next game hoping that this time their game will be the next angry birds. So where do they go wrong? Why do some games sell millions of copies while others languish in the App Store?
The Viral Effect
It's important to tackle the viral effect first because it can confuse the issue. Sometimes, games can become very popular, very quickly, for no apparent reason. Bubble ball is a good example of this. It's not the best game in the world, but it was downloaded millions of times! There could be a number of reasons for this:
I think most developers dream about their game going viral. A bit like winning the lottery, they'll wake up one morning and see 50,000 downloads overnight. Occasionally it happens, but it's very rare. The father of one of my friends used to play the lottery. Every week he'd have his tickets ready watching the TV, sure his numbers would come up. One week, I told him that he might as well choose the numbers: 1, 2, 3, 4, 5, 6 as they had exactly the same probably of appearing as any other numbers. He told me not to be stupid! It was nearly impossible for those numbers to come up! I said that they had just as much probability as any other set of random numbers. Eventually, after several hours working it out with his pen and paper, he came round to believing me. Even with this proof of the tiny probability of winning, he kept on playing.
Don't fall into this trap! Some Apps go viral but it's very rare. There should be more to your strategy than just hoping really hard that it happens to you.
I saw a presentation on TED about a boy who had created a fusion reactor at the age of 14. He wasn't a particularly good speaker and he wasn't even the first person to create a fusion reactor in their garage. He was about the 10th person to do it.
Why was he on TED? Because he was 14. It's much more remarkable when a child makes a fusion reactor than when a 40 year old scientist does it.
In the past I never used to buy commercial code. I always had the attitude that "If they worked it out then I should be able to work it out". I come across a lot of other developers with the same attitude. They're building their first iPhone game and they want to do it all from scratch - physics, animation, sound... Even if they manage to build their own game engine, they inevitably end up wasting countless hours on game engine design and end up with a sub par game engine at the end.
Recently, my attitude's been changing. When I write a game, I want to spend my time doing game design rather than worrying about collisions or OpenGL. When I have a new problem, I start by looking for existing libraries which could reduce my software development time. A month ago, I started selling source code on this site. Initially, I spent two days setting up a free shopping cart system. I spent about 8 hours setting up the cart which is worth about $320 of my time. It seemed to work fine and I started making sales. However, after installing some routine updates I got an email from a customer saying the shopping cart wasn't working. Now, the shopping cart I was using was very, very powerful and flexible; and that inevitably means that it was extremely complicated. It was composed of about 15 individual modules with a flexible system of rules to determine which actions were taken at every cart state. For some reason, the licenses weren't being issued. In the past, I'd have probably spent a week debugging the PHP code and eventually solving the issue. At least until the next dodgy update!
But wait a minute. I'm not a shopping cart developer. I'm a mobile game developer. I don't want to spend 40 hours trying to debug my shopping cart. I did a search and found a premium module which handled file purchases. It cost $50 which included technical support. I bought the module, installed it in 20 minutes and was ready to go. For me, this was the right option. I made that money back very quickly from the sales on the site and didn't waste my time working on something which didn't add value.
In fact, I probably made a strategic mistake. I spent 8 hours setting up the original cart which translates to around $320 of my time. Since the premium cart only costs $50 I should have gone with that solution from the start.