Friday, 9 December 2011

New way to declare private methods

Normally I would put private methods in the header file. But noticed from "Learn Cocos2D 2nd Edition" book a different way been used.

The header file is quite simple:


#import "cocos2d.h"

@interface HelloWorld : CCLayer
{
}

// returns a Scene that contains the HelloWorld as the only child
+(id) scene;

@end


The private methods are however declared in the .m file as shown below with "(PrivateMethods)" added behind "@interface":


#import "HelloWorldScene.h"

// private methods are declared in this manner to avoid "may not respond to ..." compiler warnings
@interface HelloWorld (PrivateMethods)
-(void) onCallFunc;
-(void) onCallFuncN:(id)sender;
-(void) onCallFuncND:(id)sender data:(void*)data;
-(void) onCallFuncO:(id)object;
-(void) createLabelWithOffset:(int)offset;
@end

@implementation HelloWorld



This is completely new to me and indeed quite interesting!

Sunday, 4 December 2011

ARM CPUs of the iOS devices don't support division operations in hardware?

Read in the "Learn Cocos2D 2nd Edition" book Chapter 4 that "since the ARM CPUs of the iOS devices don't support division operations in hardware, multiplications are generally a bit faster."

So instead of divide by 2, you should use multiple by 0.5 - this is interesting...

uDevGames 2011 result published

In case you are not aware, the result of uDevGames 2011 is available here. Although most of the games are for Mac OS X, you should be able to learn something there, as most importantly - there's quite of few of them with both source code and binary available for download!

Tuesday, 22 November 2011

Check list for all future projects

I like to slowly build up some sort of template/check list which I can follow and gradually improve on every future projects to make sure I don't miss anything important and sort of maintain a standard for the quality of work.

Things I can think of at the moment listed as below, will keep updating this list:

1. Handle device rotation properly
2. Test for memory leak
3. Handle different devices correctly - including icon, launch image, size of sprite, screen resolution, ...etc
4. Save game state/data on different scenario
5. with sound/audio
6. proper menu/high score
7. help/tutorial
8. [future] Game center support if applicable
9. [future] test in real device, not just simulator

This is definitely not a simple task....

Things learned from "iLabyrinth"

Was reading the code of iLabyrinth game by UD7 Studios and learned quite a few things worth written down even though only looked at a few files:

1)The way they handle the loading of different sprite/map files according to different device/resolution:


2) The "isDeviceIPad()" is a macro defined as below for detecting if the device is an iPad, very handy.

static BOOL isDeviceIPad(){
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
    if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
        return YES;
    }
#endif
    return NO;
}

3) The "hightRes()" part (shouldn't it be "highRes()" :-) ?) also worth a look, probably to differentiate between devices like iPhone 4 which has higher resolution from previous devices.

+ (BOOL)hightRes {
    if( [[CCDirector sharedDirector] contentScaleFactor] > 1 ){
        return YES;
    }
    
    return isDeviceIPad();
}

4) In my older projects, I always use lots of "#define" to define different game states, later learned to use "typedef enum" to just list out all of them and saved a lot of typing. Noticed as below they also assign each item a value using bit shift operation, which means may be these items can also be used for calculation/operation if required, which is quite cool.

typedef enum {
WalkPathWalk = 0,
WalkPathToTop   = 1 << 1,
WalkPathToRight = 1 << 2,
WalkPathToBottom= 1 << 3,
WalkPathToLeft  = 1 << 4,
WalkPathEntrance= 1 << 5,
WalkPathExit = 1 << 6,
WalkPathNoPath = 1 << 7,
} WalkPath;


typedef enum {
    ZeroPathToBottom= 1 << 7,
    ZeroPathToLeft  = 1 << 8,
    ZeroPathToTop   = 1 << 9,
    ZeroPathToRight = 1 << 10
} ZeroPath;


5) The way it handles game state saving is also new to me. It's called in "applicationDidEnterBackground" (shown below), "applicationWillResignActive" and "applicationWillTerminate" inside the AppDelegate code.

- (void)applicationDidEnterBackground:(UIApplication *)application {
[[CCDirector sharedDirector] stopAnimation];
[[CCDirector sharedDirector] pause];

// Save GameState
[NSKeyedArchiver archiveRootObject:[iLabyrinth sharedInstance] toFile:[iLabyrinth stateFile]];
}

6) Also a bit unclear about the concept of "Scene" and "Layer" at the moment, specially about how they interact with each other.

At first look, the game seems to only have one file called "UDGameLayer" which indicates it's a "Layer". But when I looked further down the code, inside quite a few "Scene" files (e.g. "UDGameEndScene.h" shown below), it actually includes a layer too.... hmmm.... that's a bit confusing...


@interface UDGameEndScene : CCScene {

}

@end


@interface UDGameEndLayer : CCLayer {
CCSpriteBatchNode *_backgroundLayer;
}

@end

7)This multiple build targets thing - already seen it in the Cocos2D sample project, but still worth mentioning and hopefully can later work out how to do it myself.

---------------------------------------------------

There's also a few other things I am still not very clear with Cocos2D and still looking for answers and trying to work out how it's been handled in iLabyrinth...

a) the concept of "storing multiple Sprites inside one big image file and then load the required part accordingly", specially if there's animation involved for each sprite.

b) the best way to structure the code if there's a main character (with different weapons?) and multiple levels to play - probably with different enemies/targets to fight with in each level.

Still lots of things to learn :-( ....

Wednesday, 16 November 2011

Malware detected in iphonedevsdk.com forum by chrome 14.0.835.202

I got a chrome session with iphonedevsdk.com forum left overnight, and this morning when I look at it, Chrome says "Warning: Something is not right here!" and the content talks about malware. The chrome version is 14.0.835.202, wonder if the forum admin guys aware of this, probably some sort of injection attack?

Tuesday, 15 November 2011

5th Open Source Game (1st in Cocos2D) - Dice in Cup

Finally got 5th Open Source Game (1st in Cocos2D) "Dice in Cup" all done (or in other words - sick of working with it and wants to start another new one :-) ). The source link is at the end of this post.

As I mentioned before, I purposely picked this simple game idea to have a chance to get familiar with Cocos2D.

A high level flow of the game from code's point of view is as below:

1. Game first started, "init" calls "initialiseGameVariables" which set "GameState" to "kGameStateStarted"

2. "init" creates all cup/seeker objects, call "moveCupToRevealObject"

3. end of "moveCupToRevealObject" will call either "stateChange_startGame" or "stateChange_gameOverDisplay" depending on "GameState"

4. "stateChange_startGame" will reset all cups initial position, set "GameState" to "kGameStateMoveCups" then call "MoveCups"

5. "MoveCups" will move cups around, at the end of all cup move, calls "stateChange_CupMoveCompleted"

6. "stateChange_CupMoveCompleted" set "GameState" to "kGameStateUserActionStart"

7. after user clicked something, "observeValueForKeyPath" will set "GameState" to either "kGameStateIncorrectChoice" or "kGameStateCorrectChoice"

===== incorrect move

8. in "scheduleControl, if "GameState" is "kGameStateIncorrectChoice", it calls "moveCupToRevealObject", which same as #3 above at the end calls "stateChange_gameOverDisplay"

9. in "stateChange_gameOverDisplay", "Restart" been shown, wait for user click restart (calls "restartGame"

10. in restartGame", remove "Restart", then call "moveCupTorevealObject" and "initialiseGameVariables"

===== correct move

11. in "scheduleControl" if "GameState" is "kGameStateCorrectChoice", it updates score/level and then sets "GameState" to "kGameStateMoveOnToNextLevel"

12. also in "scheduleControl", it calls "updateDelayAndMoveNumber" and then sets "GameState" to "kGameStateStarted" - which then starts new level and repeats from #4 above

Did I confuse you? Hope not... I believe there should be other better/cleaner ways to handle the game logic, this is what I got so far. Welcomed to let me know if you got better ideas!

Also tested in iPad simulator, as below, might need to made some adjustment with the sprite size, other than that, it works perfectly.

A few other notes:
a. Same as previous game I used KVO to "observe" the correct/incorrect moves.
b. Tested rotation and Cocos2D handles that quite well, no extra code required.
c. Tested for memory leak in both Instrument 4.0 and 4.2, no leaking found.
d. Two places which I got stuck and spent most of the time is (1) the game state change which control the flow logic and (2) how to move the cups using the actions. As the CCSequence was mainly for running multiple actions on one Sprite, I end up creating 3 of them - one each! Let me know if you can think of better ideas!
e. As the main purpose of this exercise is just as a warm-up, to get familiar with Cocos2D, didn't try other stuffs like music/sound effect, menu, ...etc, will try to cover that in future projects.

Let me know if you found any problem with the code and hope you find this post interesting. Why not try one yourself and share it with everyone your better ideas!

Source for Dice in Cup V1.0

Strange error in Xcode 3.2.3 "texture_ undeclared"

While still working on the project, I copied the "Dice in Cup" project (with Cocos2D 1.0.1 and named "Cocos2dDiceInCup") from my MacBook Pro (which the project runs perfectly with Xcode 4.2/OS X 10.7.2) to a test VMWare box running Xcode 3.2.3 on OS X 10.6.4, strangely it won't compile at all. As shown below, keep complaining about "texture_ undeclared" error.

If I right click on "texture_" and select "Jump to Definition", as below you can clearly see "texture_" is properly defined in CCSprite.h", very strange...

I later copied the project to another box with Xcode 4.0/OS X 10.6.7 and it runs perfectly. May be Xcode 3.2.3 is just too old?

Also tried searching the net but can't anything relevant.

Sunday, 13 November 2011

Almost ready - 5th Open Source Game (1st in Cocos2D) "Dice in Cup"

Sort of "almost" finished my 5th Open Source Game (1st in Cocos2D), still working on code tidying at the moment - hopefully this won't break the code :-)...

Although I called it "Dice in Cup" - which is what I first intended to do - it now looks quite different. The "Dice" is now actually the "Seeker" image from Cocos2D, and the "Cup" is actually a ugly green rock image I created in Inkscape in 5 minutes.

It's a very simple game and everyone can easily understand it within seconds. Though it's quite slow and simple at the beginning, when you reached level 9 and above, the cups move really fast and it's quite difficult following it to work out which is the right one.

I purposely picked this game as my first Cocos2D game project and the result was quite good. I now have a better idea of how all the powerful "actions" works. Was stuck with the "Cup" moving logic and the game logic for a while. Although still not 100% clear on how some of the schedule and CCSprite class stuffs work yet, after this project I felt a bit more confident in dealing with it now.

Uploaded a short demo on YouTube as below.


Hopefully can finalise all the work in the next few days and will let you know when it's all completed!

Saturday, 12 November 2011

Strange behaviour when method in "@selector" missed a parameter

I was reading and trying some of the code from this article (Cocos2D iphone tutorial: Die, Grossini, Die! – Part I) about some basic Cocos2D stuffs. One of the things I have is to create a clickable "Restart" text as below:

-(void)stateChange_gameOverDisplay {
    
    CCLOG(@"inside stateChange_gameOverDisplay");
    
    [CCMenuItemFont setFontName:@"Marker Felt"];
    [CCMenuItemFont setFontSize:30];
    CCMenuItem *play_menu = [CCMenuItemFont itemFromString:@"Restart" target:self selector:@selector(restartGame:)];
    
    CCMenu *menu =[CCMenu menuWithItems:play_menu,nil];
    menu.anchorPoint=ccp(0,0);
    menu.position = ccp(280, 20);
    [self addChild:menu];
    
    CCLOG(@"end of stateChange_gameOverDisplay");
    
}

But when I run the code, there's nothing been displayed and it just keep looping and looping as below:

inside stateChange_gameOverDisplay
inside stateChange_gameOverDisplay
inside stateChange_gameOverDisplay
inside stateChange_gameOverDisplay
inside stateChange_gameOverDisplay
inside stateChange_gameOverDisplay
inside stateChange_gameOverDisplay

It took me a long time to work out it's because when I specify the selector, there's an extra ":" behind the method name.

@selector(restartGame:)


But I declared the method incorrectly as below:

-(void)restartGame {
    CCLOG(@"inside restartGame");
    //do something here
}


The correct way should be as below, with the "(id) sender" parameter

-(void)restartGame: (id) sender {
    CCLOG(@"inside restartGame");
    //do something here
}

I guess it's probably because the "@selector" thing can't find the correct method to call? But as there's no error or warning, it might be a bit difficult to relate the symptom to the root cause...

Back in June, I wrote in this post about crash caused by missing ":", I guess this one is also similar, but from different angle, somehow.

So one more tips for everyone if you get similar strange behaviour like this...

Tuesday, 8 November 2011

Cool! Face Detection in iOS5 works even with Johnny Deep's multiple eyes photo!

Was following this example from ManiacDev.com which as below quickly detects the eyes and mouth in a few seconds time and highlighted all of them.


I then quickly tried it with the Johnny Deep's multiple eyes photos and it sort of works too! Except the left side picked up the wrong one, not bad isn't it?

Monday, 31 October 2011

What's the benefit of having 2 names for the same variable?

I was following this tutorial called Cocos2d Sprite Tutorial, and noticed as below, the variables were first declared in the header file with an extra "_" underscore character at the front.

    CCSprite *_dragon;
    CCAction *_flyAction;
    CCAction *_moveAction;

But then at the @property declaration, the underscore character was removed.

@property (nonatomic, retain) CCSprite *dragon;
@property (nonatomic, retain) CCAction *flyAction;
@property (nonatomic, retain) CCAction *moveAction;

And then in the main ".m" file, both names were used as below with the "=" sign at the "@synthesize".

@synthesize dragon = _dragon;
@synthesize moveAction = _moveAction;
@synthesize flyAction = _flyAction;

And also inside the code both names were referenced as shown below:

        self.dragon = [CCSprite spriteWithSpriteFrame:frame1];
        _dragon.position = ccp( s.width/2-80, s.height/2);

But why? This is the not the first time I saw people doing that, but I don't understand the benefit at all, won't it be very confusing having 2 names for the same variable?

Saturday, 29 October 2011

Error "Sending 'ccColor4B' (aka 'struct_ccColor4B') to parameter of incompatible type 'CIColor *'"

While trying to compile some old Cocos2D projects, as attached, keep getting this error "Sending 'ccColor4B' (aka 'struct_ccColor4B') to parameter of incompatible type 'CIColor *'" in my Xcode 4.2

As below, the Cocos2D is version 0.99.01 according to "cocos2d.h". Looks like have to upgrade the Cocos2D in the project...

[UPDATE 16/01/2012]
I found the fix!

Instead of:


+ (id) layerWithColor:(ccColor4B)color
{
return [[[self alloc] initWithColor:color] autorelease];
}


The fix is to change it to as below, with the changed part highlighted and underlined.


+ (id) layerWithColor:(ccColor4B)color
{
return [[(CCColorLayer*)[self alloc] initWithColor:color] autorelease];
}


Note that this is for Cocos2D 0.99.x only, read on the net that it's renamed to "CCLayerColor" in later version.

Hope this helps!

Wednesday, 26 October 2011

Error "Illegal Configuration - Pattern colors on iOS versions prior to 3.0"

While looking at some old projects developed with Cocos2D from the net, found that the new Xcode 4.2 throws the following error: "Illegal Configuration - Pattern colors on iOS versions prior to 3.0" and refused to compile.


Checked the net and found this page from Mark Tomlinson's site which says "The error is due to incompatibilities with older nib/xib files prior to version 3.0". It also mentioned about the fix is to "change the **Deployment** type in the *Interface Builder Document* settings", however the image no longer exist so I got no idea what he is talking about.

It took me a while and I finally found it. You have to select the nib/xib file, then at the right hand side, as shown below, under "Document Versioning" there's this drop down called "Deployment" and the current selected option is "iOS 2.0", just change it to the current version "iOS 5.0" (or anything above 3.0) then it works.

Tuesday, 25 October 2011

Problem after upgraded iPad 2 to iOS 5 [fixed]

I have an iPad 2 with wifi only, and I always connect to my iPhone 3GS (iOS 4.3.5) through Bluetooth and then using the "personal hotspot" on iPhone, I can share the Internet connection and do lots of stuffs on the net with the much bigger screen.

However, after I upgraded my iPad 2 to iOS 5 yesterday, the Bluetooth connection still works, but it can't get any Internet connection any more!

This is really annoying. I guess can also upgrade my iPhone to iOS 5 to see if that would fix the problem, but there's first of all the risk that it still won't work, plus I will then loose a device for testing with iOS 4!!

What a pain, any one having similar issue?

[UPDATE] saw quite a few people experiencing similar issue with iPad after upgraded to iOS 5 - but mostly for connection through router, some of them got it fixed after router restarted. So I tried that too - I power off and then restart my iPhone. And guess what, it works! But why a restart is required is still a mystery to me...

Sunday, 23 October 2011

Top "In App Purchases" shown in App Store

You might already know this, while studying the 101-in-1 Games, I noticed theApp Store shows the top "In App Purchases" ranking too. It sort of provides you a rough idea about:
(a) whether the game provides In App Purchase
(b) what sort of In App Purchase options the creator provides
(c) which product/price range is the most popular one


Also have a quick look at another one of my favourite game Tiny Tower and it also shows similar ranking as well, but only 3 been displayed instead of 5.


This also proves you can indeed make money with free games too! And imagine those are your profits if it's your game... Got to work harder mate!

Where to get hundreds of game ideas for free

When you started learning to write games, one of the main problem will be about finding an idea for you new game project.

I found this new game 101-in-1 Games which is quite interesting.

When I first saw the game, to be honest I was a bit depressed - as if someone already provided a free application that includes 101 games, how much space will be left for us?

After tried the game for a while however, I felt a lot better. As each of the included games is only in a very simple form - which means each of them can still be further expanded to become a full game. Therefore we can use it as a good example/source for different types of game ideas!





Have a try and I think you will like it too - not just playing with it, but also learning from it!

Monday, 17 October 2011

Inspecting Apps (.ipa) files under Microsoft Windows

A friend told me that although the code for iPhone Apps are protected by encryption, other stuffs like music, images, ..etc can still easily accessed from any Microsoft Windows machine. I didn't quite believe it until I check it on a XP machine after synchronised with my iPhone.

No I didn't jailbreak or change anything on the phone - all I have to do is look at the "My Documents\My Music\iTunes\iTunes Media\Mobile Applications" folder and open each of the ".ipa" files using WinZIP or WinRAR. Tried to do the same thing on my Mac but it was blocked.

I quickly browse around, found that one of my favourite game Tiny Tower has a "floor.csv" file with 145 floors defined - I am currently on floor 107, would be interested to see what will happen when I reached the 145 floors limit?

Lots of image and music files are fully exposed. Saw lots of Apps use ".PVR" files instead of ".PNG" or ".JPG" files for images - I just learned that ".PVR" files can be loaded much faster than other formats.

Also saw lots of Apps still have the ".nib" files in there, wonder if all those ".nib" files won't be protected by encryption either?

However, out of all mentioned above, the most shocking thing I found is about an App called "OfficeJerk". As shown below, it seems to be partly written in ".lua" and both the code and the sprite are fully exposed.



Does the name "Lua" sound familiar to you? Yes, I mentioned it in this post when we were talking about this new software called Gideros Studio - all the apps developed in it has to be done in this "Lua" language.

I certainly hope they don't handle your app like whichever compiler/application "Office Jerk" author used to deploy theirs. As it's really un-secure...

So I guess everyone should have a look at what your app might look like before publishing it. Just look at "/Library/Developer/DerivedData/AppName/Products" then check either the debug or release branch and open it with "Show Package Contents" - hope you don't see what you don't expect to see..

Thursday, 13 October 2011

Can iOS5 Face Detection API detect this?

Seen quite a few blogs/news articles taking about the new iOS5 Face Detection API "CIFaceFeature" which has properties like "hasLeftEyePosition", "hasRightEyePosition", "hasMouthPosition", ...etc. Would be interested to see how it really works.

Also, just wondering, what would be the result if we run it against Johnny Deep's famous "multiple-eyes" image? :-)

[UPDATE 2011-11-08] Yes it works! See this post about the result when I use this photo to run the face detection example... Quite cool!

Instrument 4.1 (Build 4138) still hung in OS X 10.7.2 Lion - issue fixed in 4.2 (Build 4233)

Software update prompted me to upgrade today, so I upgraded my MacBook Pro to 10.7.2 straight away.


Although the new iCloud function looks interesting, the first thing I tried is actually the annoying Instrument 4.1 hung issue. Unfortunately still the same...

Wait, isn't iOS5 out now, what about Xcode update? I must have missed something.... Have a quick look at AppStore, and yes! Xcode 4.2 is available!

Can't tell you the result yet as I have to download the 1.8GB file first... Will let you know how it goes... fingers crossed...

[UPDATE] YES! It's fixed! I tried Instrument 4.2 (Build 4233) and the hung issue is gone!
However somehow it shows a small red bar when I run it with my Follow Me If You Can project... Will look into that later

Wednesday, 12 October 2011

4th Open Source Game - Follow Me If You Can

After a few weeks hard work, I am please to announce my 4th Open Source game - "Follow Me If You Can" - released in MIT license.

It's a very simple memory game: the computer moves some tiles around and you have to remember all the moves. As when it's your turn you have to repeat it. You get points for every correct move, extra bonus and life if all correct. You loose life for every incorrect move - but the correct move will be shown as hint.

Some screen dumps as below:


Features:
1. My first project to have background music and sound effect (applause for every level that's completed with no mistake)
2. Start up menu and game over menu
3. Keeps top 10 scores, options to view from both start up and game over menu
4. Simple tutorial/how to play screen using a scrollview
5. First project to use KVO - for displaying hint after any incorrect move
6. The number of tiles for the width/height increases every 2 levels
7. The number of moves increases every level
8. To make it not too difficult, the game starts with 5 lives, and you get bonus life for every level that's completed with no mistake
9. Handles rotation

I have also create a short demo video on YouTube as below to show you how it works.


I first read about KVO from "Back to Basics: Using KCO" by Mike Nachbaur, thought it's a pretty cool idea. Unfortunately most of the game already completed, so in the end only use it for displaying the hint when user made a mistake. Will surely try to use it more frequently in future projects.

As the Instrument 4.1 on OS X 10.7 Lion problem still not resolved yet, I can only test my code on the 10.6.7 box in Instrument 4.0 and it passed without any memory leak or zombie problem.

The background image is from defcon-x and I like to thank him/her for scanning all the different wood textures and provide it for free.

The images are from Microsoft Office for Mac 2011.

As I am starting to learn Cocos2D, not sure if I will create any more "pure objective-c" games like this. Let's hope Cocos2D is as good as the others claimed - as that's why it's so popular?

Hope you enjoy the game and can learn something from the code, let me know if need any further information or found any bug.

Happy coding!

Link to Source Code for Follow Me If You Can Ver 1.00

Monday, 10 October 2011

Expect to finish 4th Open Source Game this week

My 4th open source game almost ready. This time I added music, first attempt on KVO, start up/ending menu, a simple scrollable "how to play" view, top scores, ...etc. So far, the most complicated open source game I ever created...

Expect to release it before end of this week...

Sunday, 2 October 2011

Started learning Cocos2D

Just started learning Cocos2D with the Learning Cocos2D book.

Currently halfway through chapter 1 and already found a few issues:
(1) "HelloWorldScene.m" should be "HelloWorldLayer.m"
(2) The new code to add the space cargo ship image should be "under" the existing Hello World label code inside "init()" so that the previously declared variable "size" won't cause compiler error.

The forum for the book is also not as organised as the others I have seen - which organised the questions into different chapters to make it easier for readers to find what they want instead of using search.

Any way, so far so good. Let's wait and see how it goes...

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!