Showing posts with label sample code. Show all posts
Showing posts with label sample code. Show all posts

Saturday, September 8, 2012

Cocos2d Multi-level Template (including Cocos2d sliding menu grid)

At the beginning....
At first I was working on a proof of concept game, which is multi-levelled and I started thinking about how to create an "Angry Bird" style multi-level sliding grid. To avoid reinventing the wheel, I found this page from Apptinker blog which adds extra labelling for each level icons on top of Brandon Reynold's excellent piece of work (video shown below).


Some extras on top ....
However, after some testings, I found a few things that can be further improved:

(1) It's for iPhone only, doesn't cover iPad or Universal projects that well
==> need to check device type and use device specific parameters/images

(2) All level icons are clickable, which might not be very practical. As normally at the beginning, only the first one or few levels are enabled, rest all locked. Player has to pass the level (or pay extra money or click on ads or install other apps, ...etc to get credits) to unlock other levels. So it should have 2 types of level icons - locked and unlocked, and only those unlocked ones are clickable.
==> use different icons for locked/unlocked level types, plus extra field to keep track if each level is locked or not.

(3) Say if there are 3 x 6 level icons per page, and your total number of levels (e.g. 45) is not the multiples of 18 (e.g. 18, 36, 54, 72), scrolling to the last page (using 45 as example, that will be page 3 of clickable level icons) doesn't work.
==> add extra invisible icons (opacity=0) at the end to make the total number of all level icons equivalent to multiples of the number of total icons per page (45 + 9 invisible ones = 54 in total)

(4) From the level select page, can not return back to main menu page (the page before this page)
==> add extra HUD (Heads Up Display) layer with a home icon

Issues resolved, yeah!
I spent some time and finally got all these issues resolved. Also exchanged a few emails with readers about displaying splash page and localisation (supporting multiple languages) while working on this.

A light bulb appeared on my head, and....
I suddenly realised there's a need for a simple multi-level template which covers:
(a) splash page,
(b) main menu,
(c) level sliding grid,
(d) a simple popup at the end of each level,
==> if passed, unlock next level and show option to proceed to next level, replay same level, home or back to level select screen
==> if failed, only show option to replay same level, home to back to level select screen
(e) audio (one at splash page startup, one as looping background, a few sound effects, ...etc)
(f) localisation (for icon name and messages)

This should be handy to beginners like me, as you then only need to focus on the main game design, fit it into this template (with a bit of work of course), and you got a fully functioning game!

Wonder if there's currently any open source project available for this kind of work? Let me know if you are aware of any!!

Mission accomplished!
I got the first draft of this simple Universal project template sort of completed (link to source available far, far below), some features listed below:
(1) uses Cocos2d V1
(2) include script to run TexturePacker to build 4 ".pvr.ccz" format sprite sheets (iPad SD/HD and iPhone SD/HD) from 2 directories (containing images for iPad HD and iPhone HD) on each build
==> Note that if you only have the free version, you need 4 directories (one each) and have to use other file format which is slower and less efficient
(3) for localisation, includes English, Spanish, Traditional Chinese, Simplified Chinese and Japanese at the moment
(4) keeps track of top score, date top score achieved and number of stars received for each level (stored in NSUserDefaults)

Also have an empty link for Help and another one for GameCenter which I haven't got time to finish yet, will look at that later...

So, what does it look like? Some screen dumps and brief description first...
The application icon name, changes according to the language setting of the device. As the screen below shows, it's defined by "CFBundleDisplayName" inside file "InfoPlist.strings" and there's one for every supported language. Yes, your app can be called "XYZ" in Xcode, "ABC" in App Store, and shows "STU" at the bottom of icon when installed on users' device, they don't have to be the same.


Next, when the app starts, it shows the splash page. All the label/title content read from "Localizable.strings" file. You should get the idea now. The splash page code ("LoadingScene") also plays a short audio, you can use it to announce your company name or some other stuff to greet your users.



Note 1: with the Spanish version on upper right hand side, you can see a common problem - the label is too wide and need to reduce the font size to fix that! Please refer to this post of mine for further info: "Things learned about multi-language"
Note 2: the images with orange background are captured from iPad 2, the green ones are from iPhone 3GS.
Note 3: the blue popup in the middle is because I wasn't signed in to GameCenter, can ignore that.


Next is the main page, a bit too simple right? Yes, because I expect you to completely replace this page with a proper one for your game! (Note: latest version in the video was updated with extra Sound On/Off option)
"Help" and "GameCenter" not working yet, "Start Game" will bring you to the level select screen, "Reset" resets all the level data.

Next, the most important part thast most of you would be interested with - the level select screen (sliding menu grid). As you can see the "home" button floats in the HUD layer, doesn't move when you slide between different pages, and only 1st level was unlocked initially. Second one shows the last page - with 9 invisible ones at the back.


Finally the GameLayer - as you are also supposed to replace this with your own game, I quickly built a simply single page test game layer based on Ray Wenderlich's Cocos2D button tutorial to simulate the result of a real game. You can use the lower right hand side buttons to specify how many stars current level received, use the "+", "-" and 3 buttons above to change the score, and click on the middle 2 to pass or fail the game, very simple.

There will be 2 different popups when game ended depending on whether you passed or failed, as shown below:



Don't like the images/screen design? Me too...
Well, I am a developer, not designer... I am only providing a fully functioning "template", would suggest you to get some proper designer to do all the nice looking stuffs if you don't like mine, you are welcomed to change it!!


Short demo video
For those who like to see how it works, a short demo video covering both iPhone and iPad, as it's an universal project. Oops, as it's screen capture by QuickTime, unfortunately no sound... But if you download the source code and run from your Mac, you will get all the sound and background music.


Where is the code?!! Any copyright/left requirement thing?
I only have 2 simple requirements:

1) You have to download both my games and play both of them for a few times (help me to help you more!!)
  (a) Where Is It - Smart Kids Edition and (b) Mespfi

2) Optionally, please credit me or provide a link back to this blog either in your App or in your blog.

That's it, simple right? After that you are welcomed to use and change the code in which ever way that suites your needs.

Finally, you can click here (Updated V1.02) (Old Version 1.0 click here) to download the code. When you first run it, TexturePacker will report some errors (as it couldn't find the image files to process), but as the sprite sheets already included it will still work.

If you want to update any images (or fix that error), first you need to download the images, store it somewhere on your local drive, then modify "PackTextures.sh" so that all the path settings match where the images were located. And if you changed any of the image file names, please update the settings in "GameData.h" so that it can be picked up correctly.

I have put most of the changeable settings at the top of "GameData.h", have a look at that first.

Finally, please let me know if you have any problem, any further information required, or if you found any bug or have better ways to improve the project, all comments welcomed!

Thanks, and happy coding!

[Update 24/11/2012]
Thanks to Nick Wilson who pointed out that there's problem when this template runs in iOS 6. I have created a fix, please see this post for further details.

[Update 25/11/2012]
Updated links to source/images to V1.02, history info:

// Ver 1.00 - 28/09/2012 First version
// Ver 1.01 - 24/11/2012 Fixed iOS 6 orientation issue
// Ver 1.02 - 25/11/2012 Add background image for iPhone 5 (1136x640), add version number display on Main Menu


Credit
I used some Starburst Images from Vicki Wenderlich, followed tutorials from Ray Wenderlich for the HUD layer and the test game layer, and used quite a lot of stuffs from Steffen's excellent Cocos2d Book. The nice music is from redhouse91 on freesound.org, I hand-drawn some of the images, some are from OpenClipArt. So like to thank them for that.


Monday, January 16, 2012

How to run "Puff Puff 1.1" in iOS5 Simulator?

Thanks to 6thMega (Note: site still down when checked 25/11/2012) who generously published source code of their game "Puff Puff" Version 1.1. I have downloaded the source code for a while but wasn't able to let it compile at all.

The game uses Cocos2D for iPhone (Version 0.99.04) and OpenFeint, and it's written in C++.

This week after I finally worked out the fix for the problem mentioned in this old post "Error "Sending 'ccColor4B' (aka 'struct_ccColor4B') to parameter of incompatible type 'CIColor *'"", plus the knowledge about upgrading from chapter 7 of Steffen's book, I decided to give it another go.

It was quite challenging and a bit frustrating at the beginning. I was also stuck with "OpenFeint" problem for a long time - until I later decided to completely remove/disable it and that makes everything a lot easier!

So the notes below is only about how to modify the downloaded "Puff Puff 1.1" code so that it can compile and run in iOS5 simulator (with sound!!) under Xcode 4.2. Sorry I can't answer any question about the code, a more suitable place to discuss that would be at this post on cocos2d forum.

Please let me know if you found any problem or got any other information to share!



Step 1. Download the Puff Puff v1.1 source code from this link on 6thMega web site.

Step 2. Unzip it (as shown below) and double click on the "PuffPuffV.xcodeproj" file to open the project in Xcode.

Step 3. Let's fix all the frameworks and libraries first. With "Puff Puff" selected as "Targets" (middle of screen), select "Summary" tag (right hand side) and then scroll down to the bottom of the right hand side panel. You should see as below, a few missing frameworks/libraries shown in red colour under "Linked Frameworks and Libraries"

Using the "+" and "-" button we are going to fix them one by one. Starting with the "CFNetwork.framework", click "+", locate it from the list and then click "Add".

After it's added, you can now highlight the old, not working one (in red colour) and click "-" to remove it.

Repeat this until all of the red ones are gone. However, one of them called "libz.1.2.3.dylib" no longer existed and I can only find this "libz.1.2.5.dylib". As the name is quite similar with only minor difference in the version number, this should be the best choice. Note: please ignore the hint box as it's showing details of a different file while my mouse was over it

Step 4. Scroll back to the top, select "Build Settings" tab, and change all the "Base SDK" to "Latest iOS(iOS 5.0)"

Step 5. We can now start changing the files. Find "PuffPuffAppDelegate.mm" and look for this line as shown below. Either remove it or disable it by adding "//" at the front.

[PlayHaven preloadWithPublisherToken:@"token" testing:NO];


Step 6. If you try to "Build" now you will get quite a lot of errors. Let's start by fixing the easiest one - the "ccColor4B" problem I mentioned in this old post.


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


There should be 2 of them, one in "cocos2d sources -> cocos2d -> CCLayer.m" and other in "GameScene.mm".

The fix is as below, change to as below:

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


Step 7. Next we want to remove/disable "OpenFeint" - mainly because I can't get it to work. If anyone has better idea or know how to fix it, please let me know and we can then probably skip this whole step :-) ...

There are quite a few things to remove, so I am using "Step 7-x" as below to make it easier to follow.

Step 7-1. Highlight the 2 OpenFeint folder/file as shown below and select "Delete" to remove it.

At the next screen as shown below, click on "Delete" to remove all files.

Step 7-2. Remove all the imports for OpenFeint related header files. As shown below the line has to be removed or add "//" at the front to disable it. There's a few of them as listed below:

Classes -> Scenes -> MenuScene.mm - remove '#import "OpenFeint.h"'
Classes -> Scenes -> GameScene.mm - remove '#import "OFHighScoreService.h"'
Classes -> Scenes -> SplashScene.h - remove '#import "OpenFeint.h"' and '#import "OpenFeintSettings.h"'
Other Sources -> PuffPuffV_Prefix.pch - remove '#import "OpenFeintPrefix.pch"'
Classes -> PuffPuffAppDelegate.h - remove '#import "OpenFeintDelegate"' and '#import "OFNotificationDelegate.h"'


Step 7-3. Since last step ends with the file PuffPuffAppDelegate.h, might as well remove the "OFCallbackable" at the end. Don't forget you also have to remove the "," too and DON'T remove the closing bracket ">" after that. Be careful!

Step 7-4. Disable "InitializeOpenfeint()". As below, in Classes -> Scenes -> MenuScene.mm, disable the whole block inside the method "InitializeOpenfeint()".

Also, inside Classes -> Scenes -> SplashScene.mm, remove or disable the following line by adding "//" at the front in "aaa" method.

[self initializeOpenfeint];

Step 7-5. As shown below in Classes -> Scenes -> MenuScene.mm, remove the highlighted line about OpenFeint launchDashboardWithHighscorePage.


Step 7-6. Almost there. Next in Classed -> PuffPuffAppDelegate.mm, as shown below, remove or disable the 2 highlighted lines starting with "[OpenFeint userDidApproveFeint:"

Also in same file, completely remove or disable the 2 methods causing compilation error as shown below.

Step 7-7. As shown below, in Classes -> GameScene.mm remove or disable the line "[OFHighScoreService ...."

That's it! As below, you should be able to compile and play the game in iOS5 simulator, and the music is really cool too! Enjoy!




[Updated 5/4/2012]
As the 6thMega web site is currently down (see this post), I have uploaded the copy of PuffPuff V1.1 I downloaded last November to this link. Please note that the copyright still belongs to 6thMega, and this is just a temporarily work around while the 6thMega site is unavailable. Please let me know if you have problem with the link or any other issue with this sharing. Thanks.

[Update 25/11/2012]
Tested in XCode 4.5 with iOS 6 simulator running in 4 inch Retina display (iPhone 5), other than the 2 black stripes on both side as shown below, the game still works! Unfortunately looks like the 6thMega site no longer exist....



Friday, August 26, 2011

Neon Label Test

Saw quite a lot of games using fancy label/text/drawings with nice "neon" effect. Searched on the net for a while and found 2 sites ( Cocoanetics and stackoverflow.com info by Brad Larson) which have some useful information. So I combined the 2, plus some colour info from Visibone, and I was able get some nice labels with Neon effect working.

But I think that's not enough. Mainly because the effect of these neon labels will also depend on the background colour/image underneath.  So I modified one of my old projects (the "project#2" mentioned in this post, based on Chapter 7 example code from the iPhone Application Development for iOS4 Visual QuickStart guide book) a bit. It used to have 3 little squares which you can drag it around. I changed it into 12 different coloured squares, with the different Neon labels at the front. So you can easily change the background colour by dragging different square behind the neon coloured text.

When the project starts, you will see something as below. You will notice each colour was displayed twice. The reason for that is, the 2 links I mentioned above used slightly different techniques. The Cocoanetics one defined 3 colours (insideColor, outlineColor, blurColor) with different "alpha" value. So I created 2 objects (both extending UILabel) one accepting UIColor, while the other accepts R/G/B value separately so that the code can have different alpha value specified (this is because I can't change alpha value of UIColor?). The top 5 labels uses "NeonLabel" while the bottom 5 uses "NeonLabelRGB" object, have a look carefully and see if you can spot the differences.


In my opinion, although the RGB method indeed creates a slightly better blurring effect, it's too much trouble to have to pass R/G/B value on every call. I still prefer the easier way to make my life easier...

After you dragged a few boxes around, you will get a slightly messier screen as below for you to compare the effect of different coloured neon label on different coloured background.
Hope you find this project interesting!


Source of the Neon Label Test project


Improved ListAllFonts

I was playing around with the "ListAllFonts" project I had before, but noticed a problem: although it's quite handy to have al the font names available, it's not much use unless I can visually see what each font looks like. Changing the font of a label one font name at a time is just too dumb...

Also added 2 new things just learned: block-code and UIScrollView.

A simple block-code to show font and automatically increase the "y" value is as below. It accepts 3 parameters: the view (UIScrollView), the string to be displayed and the font name.


void (^showFonts)(UIView *,NSString *,NSString *) = ^(UIView *uView, NSString *msg,NSString *fName) {
    UILabel *tmpLabel = [[UILabel alloc] initWithFrame:CGRectMake(xx, yy, uView.frame.size.width, fontSize*2)];
    [tmpLabel setText:msg];
    [tmpLabel setFont:[UIFont fontWithName:fName size:fontSize]]; 
    [tmpLabel setTextColor:[UIColor blackColor]];
    [tmpLabel setBackgroundColor:[UIColor clearColor]];
    [tmpLabel setShadowColor:[UIColor yellowColor]];
    [tmpLabel setOpaque:NO];
    [tmpLabel setAlpha:1.0];
    [uView addSubview:tmpLabel];
    [tmpLabel release];
    yy+=fontSize*1.5;
    
};


The UIScrollView is also quite simple, I was stuck with the "content size" for a while - I set it to be the same as current screen size in the beginning and was scratching my head wondering how come it wouldn't scroll??  Well, of course it won't, unless I set it to a much bigger size....


    scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)];   
    [scrollView setScrollEnabled:YES];
    [scrollView setContentSize:CGSizeMake(screenWidth,(1000-screenHeight)*25)];
    [self.view addSubview:scrollView];
    [scrollView release];


The result is quite nice, as shown below.

And yes, with the limited display area, how could I forget about the landscape mode? So I also changed it a bit so that it automatically redisplay the content if the device orientation changed:

Note: hasn't got time to run through instruments to check for memory leak or other problems - please let me know if you noticed any.

Enjoy!

Source to V2 of ListAllFonts

[Update 05/04/2012] Found this web site which listed out all iOS fonts for iOS5, which you might also find it handy.

[Update 03/05/2012]
I run it with iPhone 4.3 simulator, it listed 42 different fonts.
Then run it with iPhone 5.0/5.1 simulator, both listed 58 different fonts.

Wednesday, August 24, 2011

Don't always need an UILabel to display a NSString

I always thought to display a NSString on a view, you need to create a UILabel. But from Apple's "iOS Development Guide", looks like this might not be the case. The "Hello World" example in Page 23 of the guide shows some code (Listing 1-1) as below to display a NSString directly using "drawAtPoint", which is quite interesting...

- (void)drawRect:(CGRect) rect { 
    NSString *hello = @"Hello, World!"
    CGPoint location = CGPointMake(10, 20); 
    UIFont *font = [UIFont systemFontOfSize:24.0]; 
    [[UIColor whiteColor] set]; 
    [hello drawAtPoint:location withFont:font];
}

I guess the downside of doing it like this is, you can't reference back to the same NSString later to perform further actions, such as change content, change location, hide the text, ...etc.

Saturday, August 20, 2011

Better way to handle switching between multiple view controllers?

Was looking at this sample code from Apple called "AlternateViews" which demonstrates the switching between 2 View Controllers when the device orientation changes.

I found a few interesting things about the code:

1. The "PortraitViewController" is loaded first, it then loads the "LandscapeViewController" in the viewDidLoad() of "PortraitViewController".

2. There's this new piece of code which I never seen before (as below) using NSNotificationCenter, which sets to call "orientationChanged" method when the orientation changed.


[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:)  name:UIDeviceOrientationDidChangeNotification object:nil];


3. When the orientation changed to Landscape, it calls the following "presentModalViewController" code to switch to the "LandscapeViewController"


[self presentModalViewController:self.landscapeViewController animated:YES];


4. When the orientation changed back to Portrait, it calls the following code to switch back.


[self dismissModalViewControllerAnimated:YES];


This way of switching between multiple view controllers is new to me, plus the way the change of orientation been handled is quite interesting too. Will certainly give it a try on some of my projects.

Friday, August 19, 2011

Minutes to Midnight - rotatable version

The 3rd and 4th project with AppsAmuck wasn't that interesting. So I updated the "Minutes to Midnight" project with rotation capability.


Now the display automatically adjusts it's location when the device rotated. Source code available below.

Code for Rotatable Minutes to Midnight

Wednesday, August 17, 2011

List out all font names

Thanks to Ajnaware’s Weblog I was able to list out all the font names, as shown in the attached screen dump. You should have a try too!

[Update] Please see this new post which shows improved version that also displays each font in scrollable view.



    // List all fonts on iPhone
    NSArray *familyNames = [[NSArray alloc] initWithArray:[UIFont familyNames]];
    NSArray *fontNames;
    NSInteger indFamily, indFont;
    for (indFamily=0; indFamily<[familyNames count]; ++indFamily)
    {
        NSLog(@"Family name: %@", [familyNames objectAtIndex:indFamily]);
        fontNames = [[NSArray alloc] initWithArray:
                     [UIFont fontNamesForFamilyName:
                      [familyNames objectAtIndex:indFamily]]];
        for (indFont=0; indFont<[fontNames count]; ++indFont)
        {
            NSLog(@"    Font name: %@", [fontNames objectAtIndex:indFont]);
        }
        [fontNames release];
    }
    [familyNames release];


[Update 05/04/2012] Found this web site which listed out all iOS fonts for iOS5, which you might also find it handy.

Wednesday, July 27, 2011

New/Better way of releasing object?

Noticed some codes are using a new (better?) way of releasing objects in the "dealloc". As below, an extra "," was added and then followed by assigning it to "nil"... Which is quite interesting...


- (void)dealloc
{
    [_window release], _window=nil;
    [_viewController release], _viewController=nil;
    [super dealloc];
}

Less typing required!

Not sure when did this start, but now when I create a new project in XCode 4, found that in the header ".h" file, the default property/variable disappeared!

As below, at the line where I put the "//", we used to have to repeat the declaration of "UIWindow *window" and "ScrollViewTestViewController *viewController;", now it all disappeared - which is cool as we can now save some typing...


#import <UIKit/UIKit.h>

@class ScrollViewTestViewController;

@interface ScrollViewTestAppDelegate : NSObject <UIApplicationDelegate> {

//


}

@property (nonatomic, retainUIWindow *window;

@property (nonatomic, retain) ScrollViewTestViewController *viewController;

@end

UIWebView with MathJax working!

After a few tests, I was able to get a few weird Math formulas display working in a UIWebView using MathJax as shown in screen dump below.


The codes are based on examples from This page on MathJax site, I stripped out the CSS/JS files and converted into a long NSString as below. Then based on parameter passed on from the caller, concatenated into a long string, write it into a temp HTML file.


    NSString *foo = @"<html><head><meta name='viewport' content='initial-scale=1.0' />"
    "<script type='text/javascript' src='http://www.mathjax.org/wp-includes/js/l10n.js?ver=20101110'></script>"
    "<script type='text/javascript' src='http://www.mathjax.org/wp-content/plugins/syntax-highlighter-mt/scripts/shCore.js'></script>"
    "<script type='text/javascript' src='http://www.mathjax.org/wp-content/plugins/syntax-highlighter-mt/scripts/shAutoloader.js'></script>"
    "<link type='text/css' rel='stylesheet' href='http://www.mathjax.org/wp-content/plugins/syntax-highlighter-mt/styles/shCore.css'/>"
    "<link type='text/css' rel='stylesheet' href='http://www.mathjax.org/wp-content/plugins/syntax-highlighter-mt/styles/shThemeDefault.css'/>"
    "<style type='text/css'>body { background-color: #d2d3d3; }</style>"
    "<script type='text/x-mathjax-config'>"
    "MathJax.Hub.Config({ MMLorHTML: { prefer: {Firefox: \"HTML\"} } });"
    "</script>"
    "<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/1.1-latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML-full'></script>"
    "</head>"
    "<body>";
    
    NSString *foo2 = [foo stringByAppendingString:strContent];
    NSString *foo3 = [foo2 stringByAppendingString:@"</body></html>"];


Then in the main file, it's loaded into an UIWebView, with the content (also extracted from same test page).


    NSString *fName = @"test1.html";
    
    NSString *xContent = @"<p>\\["
      "\\left( \\sum_{k=1}^n a_k b_k \\right)^{\\!\\!2} \\leq"
      "\\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)"
      "\\]</p>"
      "<BR/>"
      "<p>\\["
      "\\frac{1}{(\\sqrt{\\phi \\sqrt{5}}-\\phi) e^{\\frac25 \\pi}} ="
      "1+\\frac{e^{-2\\pi}} {1+\\frac{e^{-4\\pi}} {1+\\frac{e^{-6\\pi}}"
      "|{1+\\frac{e^{-8\\pi}} {1+\\ldots} } } }"
      "\\]</p>";
    
    //write to temp file first
    [self writeStringToFile:tempDir fileName:fName content:xContent];
  
    //create UIWebView
    CGRect webRect = CGRectMake(10,10,300,400);
    myWebView =[[UIWebView alloc] initWithFrame:webRect];
    myWebView.scalesPageToFit = YES;
    myWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
myWebView.delegate = self;
        
    NSString *path4 = [tempDir stringByAppendingPathComponent:fName];
     
    NSURL* url = [NSURL fileURLWithPath:path4]; 
    NSURLRequest* req = [[NSURLRequest alloc] initWithURL:url]; 
    [myWebView loadRequest:req];
    [self.view addSubview:myWebView];
    [req release];
  
    activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.frame = CGRectMake(0.0, 0.0, 40.0, 40.0);
activityIndicator.center = self.view.center;
[self.view addSubview: activityIndicator];

Unfortunately, I don't know how to include the whole MathJax into the project yet (the size is 16MB even after compressed into .ZIP file!!!), so although the HTML is first written to local temp directory then loaded back, it still has to go out through Internet to load those .JS files - which might not be the best solution for "off-line" mode operation I guess.

The source project is available below. Note that for the content you have to change every "\" into "\\" otherwise it won't work as that's the escape character.


Source for UIWebViewTest

[Update 1] After tested from local directory, found that to have the whole MathJax fully functioning, you need:
(1) the main "MathJax.js" file, plus
(2) all the files under the 4 sub-directories: "config", "extensions", "fonts" and "jax".
Just that "fonts" one by itself is more than 10MB in size!
Definitely much easier to get everything from Internet then...

[Update 2] Further test shows that as below, the "*foo" can be even further simplified by removing some of the settings in the middle (about 9 lines) and it still works ok (Note: only tested in Safari 5.0.5).

    NSString *foo = @"<html><head><meta name='viewport' content='initial-scale=1.0' />"
    "<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/1.1-latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML-full'></script>"
    "</head>"
    "<body>";

[Update 3] In case you wonder what does the following META tag mean, I will cover that in a separate post.
 "<meta name='viewport' content='initial-scale=1.0' />" 

[Update 4 (26/02/2012)] Please have a look at this new post about how to setup MathJax "Locally".

Monday, July 18, 2011

Glass Button Generator

Was looking for ways to draw those nice glass buttons on the net, found this link from Anders Brownworth which not only generates a beautiful glass button, it also saved it as a .PNG file which you can then re-use in the future, which is pretty cool!

Played around with it a bit, and added some looping and tried to covered lots of colours (colorWithHue accepts value from 0 to 1 only)  and when executed will almost fill up the screen with glass buttons in different colours as shown below. Now I didn't spend lots of time in the calculation to make sure it covers all of the numbers, so you are welcomed to adjusted the parameters to different sizes and colours.

Also, before you run the code, please be aware that the following line controls where should all the image buttons be saved/written to your local drive and you should change it according to your system.


tmpStr = [tmpStr stringByAppendingFormat:@"/Users/qq/tmp/testButton%d_%d.png",ii,jj];


Then you will see lots of nice glass button files ready to be re-used in other projects.

Have fun!

Source for Glass Button image Generator

Sunday, July 17, 2011

How to assign initial values to variables in your init methods with proper memory management

A simple but important technique learned from Chapter 15 of the book "Learn Objective-C on the Mac", which I think is quite important when you are assigning initial values to variables in your init methods.



@implementation Thingie 
@synthesize name; 
@synthesize magicNumber; 
@synthesize shoeSize; 
@synthesize subThingies;

- (id)initWithName: (NSString *) n 
       magicNumber: (int) mn
          shoeSize: (float) ss {
    
    if (self = [super init]) {
        self.name = n; 
        self.magicNumber = mn; 
        self.shoeSize = ss; 
        self.subThingies = [NSMutableArray array];
    } 
    return (self);
}

"Notice that in the init method we’re using self.attribute on the left-hand side of the assignments. Remember that this actually means that we’re calling the accessor methods for those attributes, and these methods were created by @synthesize. We’re not doing a direct instance variable assignment. This object creation technique will get us proper memory management for the passed in NSString and for the NSMutableArray we create, so we don’t have to provide it explicitly."