Friday, 30 September 2011

Not that easy to create a "flight control" type game as first thought

I was reading this article by Mike Nachbaur which was quite amazing. From short video below you can see the car running on the track.

Demo Video:


This reminds me of the Starter Kit - Line Drawing Game and thought I can just extend the idea a bit and create some sort of prototype quickly. As looks like the only difference is: Mike's demo has the race track hard coded. All I have to do is merge it with some "touch" code, right?

Wrong! May be it's just I am not up to that level yet, as after a few tests, it's definitely not as easy as I first thought!

At first, spent some time studying "bezier curve" as Mike's code used lots of those curves to draw the race track. Later realise it's not required as can achieve same result using straight lines.

Also did some research and found a few other resources on the net, specially this article which talks about setting up the path in touchesBegan and touchesMoved.

With the following code, I was able to freely draw some line and make the car follow the path (Note: car image from Mike's project). Sounds like a good start?

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    if (touch) {
        thePath = CGPathCreateMutable();
        CGPoint tapPoint = [touch locationInView:self.view];
        CGPathMoveToPoint(thePath, NULL, tapPoint.x, tapPoint.y);
    }
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    if (touch) {
        CGPoint tapPoint = [touch locationInView:self.view];
        CGPathAddLineToPoint(thePath, NULL, tapPoint.x, tapPoint.y);   
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    
    CAShapeLayer *centerline = [CAShapeLayer layer];
centerline.path = thePath;
centerline.strokeColor = [UIColor whiteColor].CGColor;
centerline.fillColor = [UIColor clearColor].CGColor;
centerline.lineWidth = 2.0;
centerline.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:6], [NSNumber numberWithInt:2], nil];
[self.view.layer addSublayer:centerline];
    
    CALayer *car = [CALayer layer];
car.bounds = CGRectMake(0, 0, 44.0, 20.0);
car.position = CGPointMake(0, 0);
car.contents = (id)([UIImage imageNamed:@"carmodel.png"].CGImage);
[self.view.layer addSublayer:car];
    
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
anim.path = thePath;
anim.rotationMode = kCAAnimationRotateAuto;
anim.repeatCount = 1;
anim.duration = 5;
    anim.removedOnCompletion = YES;
    anim.calculationMode = kCAAnimationPaced; // For constant velocity animation along the path
    
[car addAnimation:anim forKey:@"race"];
    
    CGPathRelease(thePath);
    thePath=nil;
}

Demo of my test project:


However after that I found quite a few problems. For example: using CAKeyframeAnimation you can only specify a "duration" for it to finish running through the whole path. As the path length changes all the time, it's impossible to control that. So if the user draws a longer path, it will run in faster speed...

Also found that when the image is moving as part of CAKeyframeAnimation, you can't "touch" or "move" it any more until the animation ends!

So, based on what I found so far, it's not that easy at all!

[Update 13/May/2014]
Please see line drawing tutorial on Ray Wenderich site for more details about how to create a line drawing game using Sprite Kit.

Thursday, 29 September 2011

Have a look at this "iOS Game Revenue Survey" result

Thanks to Owen Goss for organising this "iOS Game Revenue Survey" and the result is available here, I think everyone should have a look as the result is quite interesting.

Wednesday, 28 September 2011

Is having a constant/similar style important?

While still working on my next project, I started spending some time analysing some of the popular games available at the moment. One of the topic I am looking at, is the constant/similar style of game design.

As you might be aware, the games from Nimblebit has always been quite popular. I love the "Tiny Tower", "Textropolis" and "Sky Burger", while my kids are big fans of "Pocket Frogs".

However, if you compare between the games from Nimblebit, the style seems to be quite different between most of them. Which leads me to think probably some of development work were outsourced?

While I am a big fan of games from another company called Donut Games. Their games are always very smooth in the flow, very user-friendly, easy to play/follow, and comes with very nice graphic/music/icon design. As shown below, even all the icons of their games follows constant/similar style and shows a number at the bottom.

I guess having a constant/similar style doesn't necessary have any direct relationship with whether your games will be popular or not. Plus there's nothing wrong outsourcing your game development to external companies. As long as it's a big hit, who cares?

For beginners like me, it's all these learning experiences that slowly build up the confidence and skills required to handle different kind of scenarios and designs.

It certainly helps to always stop for a while, look back at what you have been doing, do some analysis of all those popular apps and borrow some ideas from them. Then, adjust the direction a bit, and then hopefully create a much better app then previously planned!

Monday, 26 September 2011

How many lines of code required to play an Audio file?

While looking at codes required to play an audio file, I found huge differences between different books/resources.

In the book iOS 4 Programming Cookbook, it talks about:

1. Adding " <AVAudioPlayerDelegate" to the .h file of the ViewController
2. Create 2 methods:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
- (void) startPlayingAudio;

3. in viewDidUnload, you have to do the following:

    if (self.audioPlayer != nil) {
        if([self.audioPlayer isPlaying] == YES){
            [self.audioPlayer stop];
        }
        self.audioPlayer = nil;
    }


Wow,  that is quite a lot of work/code just to play an Audio file.

So far, the best I got are the following 2, which is quite similar:
1st one is from iOS Recipes: Tips and Tricks for Awesome iPhone and iPad Apps. The code is as below:

    NSURL *url = [NSURL fileURLWithPath:
                  [NSString stringWithFormat:@"%@/correct01.caf"
  [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc
                   initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
[audioPlayer play];


2nd one is from the the Core Animation Demo by Bob McCune I mentioned before:


    NSString *soundFilePath = [[NSBundle mainBundle]
                               pathForResource:@"correct01" ofType:@"caf"];
    NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
    AVAudioPlayer *audioPlayer =
    [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL
                                           error:nil];
    [fileURL release]; 
    audioPlayer.numberOfLoops = -1;
    [audioPlayer play];


Both are quite similar and much much shorter than the top example above plus many other examples I found on the net.

Let me know if you got better way!

Sunday, 25 September 2011

Wolfenstein 3D for iPhone Ver 1.0 working on Simulator

Yeah! I finally got "Wolfenstein 3D for iPhone" Ver 1.0 working on iPhone Simulator, and the sound works too, pretty cool!

Note: have to disable "GLimp_AppActivate( active );" and "GLimp_Shutdown();" in "opengl_main.c" to allow it to compile and run on Simulator. Read on the net that you only need those files when you are running/compiling it for the actual device.


Also read this article by Fabien Sanglard which provides some info about the code. But as I know nothing about Open GL yet, so it's still too advanced for my level. I can only work out that the NSTimer is in the EAGLView.m part, and have absolutely no idea about the rest :-( ...

And no, unfortunately I can't get the V2.1 version work yet as there's tones of image files missing...

Any way, this is sufficient to keep me occupied for a while and relax a bit before diving back to my unfinished Open Source Game #4... still got quite a lot of bugs to fix...

Stop killing open source!!

Noticed this game called "Bubble Explosion" almost identical to ABC123 - sequence in App Store. It was originally selling for $1.99, now reduced to free.

Alright, to be fair, this guy did change the background colour from green to blue, the front menu, and when the game starts, the background bubble image wasn't displayed.

Other than those mentioned above, everything is identical. Yes, even the font, the bubble image, the labels, the messages, everything...

I guess that's where all those copyright/legal licensing thing comes in. The web site of ABC123 probably hasn't been updated for a while. Info about sharing source code by author Jedidiah Laudenslayer in 2008 is available here but it no longer works). So can't really tell what info did the author put in there as I don't have a copy.

It's always quite encouraging to see so many developers sharing their knowledge and willing to help others on the net. However this kind of lazy, disgraced behaviour makes me sad.

Even though I haven't publish any app in the App Store yet, I would be really really mad if this happened to any of my published open sourced apps.

I think it's time to review my "Take your kids, family or love ones for a few hours of outdoor activities license". And probably only release source code of any published open source game after at least 6 months after published. Please let me know if you have any other idea...

[Update 11/04/2012] This issue has been on my mind for a while. After calmed down a bit, I think it's me who is the silly one - who didn't fully understand the meaning of Open Source at the beginning, then probably felt hurt as others published something before me using my code (I still haven't publish anything yet :-( ...), thus came up with all these negative stuffs.

But hey, that's Open Source! You suppose to feel proud that someone did copy your stuff as that would be some sort of "recognition"!

My apology if my negative feeling caused any confusion or hurt any one. Was thinking of deleting this/other post, but on second thought, decide to leave it as a reminder - to show what sort of dumb mistake I have made - released code as Open Source and then criticise others for copying it.... Silly me...

Friday, 23 September 2011

Originality doesn't matter - as long as yours is better!

I was reading this article "Does originality matter?" on "Roach Puppy Games". Chris compared the popular "Angry Bird" game with an earlier game called "Crush the Castle" and it's quite obvious which one should be the first to come up with the original idea. However we all know the huge difference between the result.

That inspired me a lot. As long as yours is better, who cares if you are the first one who comes up with the idea?

Then, how to make your application better?

I can think of one thing - the most important factor that makes Apple so different from any other companies - the user experience. You could have spent 90% of your time in your game design, but it's the front end 10% user experience that matters. Even if your game have much more complexity/feature/images than others, if it can't provide a smooth experience, it definitely won't stand out from the crowd!

Gideros studio - develop iPhone apps without Mac?

Saw ManiacDev mentioned about this new free "Lua Game Development Tool" called Gideros Studio.

Had a quick look and it looks quite interesting. One of the most important feature would be it allows you to develop iPhone/iPad apps completely on Windows platform - believe Apple won't be happy about that!

As you still have to learn this script language called "Lua", so it surely wouldn't be as easy for non-technical background people as GameSalad. Plus looks like it's still quite new and lacks lots of information (e.g. Tutorials, real apps submitted to App Store, ...etc), so might still have to wait a bit longer for it to build up market share...

Wednesday, 21 September 2011

Error "EXC_BAD_ACCESS" fixed by adding "retain" to NSString

Was working on my next project and for some unknown reason, during the main loop it will work perfectly on 1st round, but then always crashed with this strange "EXC_BAD_ACCESS" error which I never seen before. Sometimes it shows this screen full of assembly languages as shown below.

Sometimes it's like this:

Tried lots of different things, like restructuring the classes, moving methods up and down the hierarchy, add lots of NSLog and checking object allocation/deallocation, check for memory leak in Instruments...etc.

Search on the net (see this one for example) and learned that the error is more about trying to call method of a object that's already deleted, not the memory leak. Have to use "Enable NSZombie detection" as shown below to check.

And I got it straight away!

After a while finally worked out that I was incorrectly doing something like this;

recordOfComputersMove = [recordOfComputersMove stringByAppendingFormat:@"%@%i",kStringSeparater,curEmptySpot];


which should actually be like this, adding the "retain" at the back fixed the problem.

recordOfComputersMove = [[recordOfComputersMove stringByAppendingFormat:@"%@%i",kStringSeparater,curEmptySpot] retain];



while working on the issue, I also read a few articles talking about this thing called "Enable Guard Malloc" (see here and here), and it took me a while to find out how to do it in XCode 4 (see here) as shown below inside "Edit Scheme".

However I think I don't understand how to use it "properly" yet as after it's been enabled, all I can see is this message as shown below, saying "stack log" been created in this file. But when I tried to open that file, it's in some sort of special format which I can't find a proper reader/editor to interpret it into a readable way.

Well, I guess most important thing for me is to identify the problem and work out a fix. That "Guard Malloc" way is definitely a bit too advanced for my level I guess...

Yeah, feels good to learn new things every day!

Monday, 19 September 2011

Use 'ima4' compression to reduce CAF file size during conversion

While playing with sound, the most frequently encountered problem will be file format conversion.

Apple has this Technical Q&A QA1534 which talks about how to create .CAF files from .AIF files using "afconvert" utility.

If you searched on the net you can also find lots of info about converting MP3/WAV to CAF files.

However I couldn't find much information about how to reduce the .CAF file size. I think you play around either the bit rate or the sample rate, however that would more or less impact the music/sound quality.

Later I found this discussion about OpenAL file formats in Apple Support Communities which talks about "IMA4" compression - which is something I never heard before.

I did a few simple experiments as below, converting same WAV file to CAF using different sample rate and "LEI16", "IMA4" data format:

afconvert -f caff -d LEI16@44100 -c 1 correct01.wav correct01_44100.caf
afconvert -f caff -d LEI16@128000 -c 1 correct01.wav correct01_128000.caf
afconvert -f caff -d 'ima4' -c 1 correct01.wav correct01_ima4.caf
afconvert -f caff -d 'ima4@44100' -c 1 correct01.wav correct01_ima4_44100.caf
afconvert -f caff -d 'ima4@128000' -c 1 correct01.wav correct01_ima4_128000.caf


The result file size is as below:


With same 44100 sample rate, using IMA4 compression reduced the file size from 313 KB to 86 KB, about 73% smaller! With the 12800 sample rate, the result is also similar. Don't know what's the default sample rate when using "-d 'ima4'",  without the parameter, the result file of 19KB is the smallest.

I guess for small, short sound effect files, should be ok with lower sample rate as it dramatically reduced the file size, but for looping or more important music, you might want to play around with the numbers a bit to get the best balance/result.

Hope you find this information helpful. And if you are aware of any better/other compression or whatever method to further reduce file size (hopefully without loosing too much sound quality?) please let me know!!

[Update 09/Feb/2014]
Thanks for the comment by a reader, I have corrected the mistake in the article.

You can get further info from this link from Ray Wenderlich as below:

Bit Rates

There’s an important piece of terminology related to audio encoding that we need to mention next: bit rates.
The bit rate is the number of bytes per second that an audio file takes up. Some encodings such as AAC or MP3 let you specify the number of bytes to compress the audio file to. When you lower the bytes per second, you lose quality as well.
You should choose a bit rate based on your particular sound file – try it out at different bit rates and see where the best match between file size and quality is. If your file is mostly speech, you can probably get away with a lower bit rate.
Here’s a table that gives an overview of the most common bit rates:
  • 32kbit/s: AM Radio quality
  • 48kbit/s: Common rate for long speech podcasts
  • 64kbit/s: Common rate for normal-length speech podcasts
  • 96kbit/s: FM Radio quality
  • 128kbit/s: Most common bit rate for MP3 music
  • 160kbit/s: Musicians or sensitive listeners prefer this from 128kbit/s
  • 192kbit/s: Digital radio broadcasting quality
  • 320kbit/s: Virtually indistinguishable from CDs
  • 500kbit/s-1,411kbit/s: Lossless audio encoding such as linear PCM

Sample Rates

There’s one final piece of terminology to cover before we move on: sample rates.
When converting an analog signal to digital format, the sample rate is how often the sound wave is sampled to make a digital signal.
Almost always, 44,100Hz is used because that is the same rate for CD audio.

Error "Undefined symbols for architecture i386: _OBJC_CLASS_$_AVAudioPlayer referenced from: objc-class-ref"

Was away on holiday last week. Of course I brought my MacBook Pro with me. Unfortunately there's no Internet access, which is extremely painful...

I was playing around with the Core Animation Demo by Bob McCune and created this very simple sound testing project.
But whenever I tried to compile the project, as below it kept showing this error:
Undefined symbols for architecture i386: _OBJC_CLASS_$_AVAudioPlayer referenced from: objc-class-ref
And without Internet Access I was stuck for the whole week, biting my finger nails, scratching my head, searched through every PDF I have but couldn't workout anything. I wonder was that something Apple put in to encourage developers to sign in to the developer program??

When I finally got Internet today I quickly searched the net and found quite a few people having same issue. I found this post from stackoverflow most relevant. So it's my fault, I didn't add the AVFoundation framework!! Simple as that, but without the Internet I would never be able to work that out for sure as I never seen that error before.

Next question then is how to do that in Xcode 4?

As shown below, click on "TARGETS" in the middle panel, then click on the "Build Phases", expand the "Link Binary With Libraries", then click the "+" sign.

After added the AVFoundation framework it works like a charm!

I love the feeling when I learned new things or fixed some annoying problems!

Wednesday, 7 September 2011

Yes! You can play Audio and Movies from iPhone Simulator!!

From this link on maniacdev.com I downloaded the Core Animation Demo by Bob McCune, and to my greatest delight I found that this demo project can play sound and video!! How Amazing!

I haven't work out how to do that yet, a quick look at the "resources" group in the project shows the Audio is in ".caf" format and the video is in ".m4v" format.

Will certainly spend more time to learn a bit more about that!

Tuesday, 6 September 2011

Instrument 4.1 (Build 4138)/ Xcode 4.1 (Build 4B110) still hung when profiling Project from Apple on OS X 10.7 Lion

I was thinking, may be it's my code - won't be too surprise if a project written by newbie like me causing problems isn't it?

Ok, so I then tried this "AlternateView" sample code from Apple, and guess what? It hung too!! Ha ha, that makes me feel much better...

Tried to search Internet and found this post on stack overflow.com about similar issue.

It also talks about starting up Instrument first, then switch back to Xcode to do profiling. I was able to get it working once, and then it stops responding again....

This is very painful, will wait for Apple to fix it then. Before that, will have to do all my profiling on the 10.6.7 box...

Monday, 5 September 2011

Problem with Instrument 4.1 (Build 4138)/ Xcode 4.1 (Build 4B110) running on Lion OS X 10.7?

I was testing my new "Memorise Me If You Can" game on my new 13" MacBook Pro running Lion OS X 10.7 using the Instrument/XCode 4.1. Noticed whenever I started Instrument it just hung and I wasn't able to stop or quit or pause it. Only way to stop is "Force Quite" which is quite annoying.

Wonder if any one experiencing same problem? I then run the same thing on another OS X 10.6.7 with Instrument/XCode 4.0, it works perfectly without any problem. I can stop or quite at any time.

I have posted 2 videos as below, 1st from 10.6.7 with Instrument/XCode 4.0, the 2nd one from 10.7 with Instrument 4.1 (Build 4138)/ Xcode 4.1 (Build 4B110).



3rd Open Source Game - Memorise Me If You Can!!

As mentioned in previous post, I finally got the whole game working, and tested/approved by my 10 years old "iPhone game testing" specialist.

I decided to call it "Memorise Me If You Can !!" The game is based on ABC123 and it's so simple that it shouldn't require any further explanation. I have posted this short demo video on YouTube:


I have added quite a few features to make it more interesting and easy to play, I think any one can at least easily reach level 10.

I learned from playing the popular game "Tiny Tower" that when the score gets updated, by moving it down and then back quickly, it catches player's attention due to the movement. I quite like it so I also added this feature to the game.

Some of the things different (extra!) from ABC123 as below:
  1. handles rotation (portrait upside down)
  2. shows count-down before each level
  3. count-down time increased every 2 levels to make the game challenging but still achievable
  4. change background image every level to make it more interesting
    1.     Note:       There's this last minute change to this part of code (the 2nd internal if loop) which now changes it to change background image every level. Originally it was only to change at "every 2 levels". Can easily change it back by enabling the internal if loop.
                  //change background colour every 2nd level if not 1st start
                  if ((curGameData.prevGameState != -1)) {
                      
                      //if (isCurrentTurnNumberNotChar) {
                          self.view.backgroundColor = [self getNextBackgroundColor:kDontUseDefaultBackGroundImage];
                      //}
                  }
    2. display current level
    3. added visual effect to shake/move score/life/level value
    4. use faded effect for all display message to maintain clean interface
    5. added simple info about how to play at the bottom of the screen during count-down
    6. didn't add menus at beginning of game
    7. like the previous ball bouncing game, keeps track of top score


    A few screen dumps as below:

    I can also think of quite a few extra stuffs for future enhancements:

    1. Might need some more refactoring, as I didn't spend lots of time in planning the object/file separations. Lots of the codes in the view controller might be able to be further separated to make it cleaner
    2. May be a more challenging "reverse order" every 5 levels to make it more interesting?
    3. May be a menu at the beginning with a simple tutorial/how to play?
    4. currently timer set to 1 sec, may be can make it smaller to make it more responsive. As now everything has to wait for 1 sec before the timer kicks in next check. But this might make the count-down part more complicate.
    5. MUSIC and SOUND EFFECT! This is still my weakest point as I am still using the simulator. Hopefully can start testing on real device soon.


    Code structure wise, it's quite simple, other than main and AppDelegate, there's:

    1. UIViewController => for View Controller 
    2. BubbleObj => UIView class for all the bubbles. Yes it's not in round shape but I still call it bubble, the image is from previous "glass button generator" project 
    3. GameData => to hold game related data 
    4. ScoreLifeObj => to hold score, life, level data 
    5. SharedUtilities => for utilities that shows the count down, shakes the label, shows messages that fade away in a few seconds time, ...etc 


    Game control logic wise, still follows the same game looping method learned from ball bouncing game. Using 2 int variable to keep track of current and previous game state, then calls different methods accordingly. Top score tracking is done using application preference.

    I have also tested the game in "Instruments" and found no memory leaks.

    Hope you find the game interesting, let you know if you found any bug or got any questions.

    Source code of the "Memorise Me If You Can" Game project

    Thursday, 1 September 2011

    Working on another game similar to "ABC123"

    There's this very old post on iPhoneDevSDK site in 2009 which "kwigbo" announced about publishing full source code for his "ABC123" cocos2d game. Unfortunately that link no long works and I wasn't able to find any source code on his site either.

    Based on the same idea, I am currently working on "my implementation" of a game similar to "ABC123". I haven't learn COCOS2D yet, so all in basic iPhone code.

    Already finished the logic, display and other stuffs. Only got a few things left like showing/keeping the score, showing how many "tries", ...etc. Hopefully can get it completed within the next few days.

    Will keep you posted.