Tuesday, June 28, 2011

UIAccelerometer | An intuitive way to play around

Shortly after reading through the tutorial about accelerometer in iOS SDK, my eyes were brimming with ideas about how would I go about making games that will make use of this amazing technology. Though the mechanism of accelerometer is complex and at times mind boggling, the implementation in iOS is actually rather simple. Let's take a look at how do we access the accelerometer in objective-c.
    UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;

Firstly, we need to access the shared accelerometer object, then set the update interval to a desired value. I set it in a way that it updates the device 60 times per second. Then we need to declare in the interface that this class will conform to UIAccelerometerDelegate.
   @interface AccelerometerViewController : UIViewController

Lastly, after we set the current class as delegate, we can listen to the values from the Accelerometer.
    - (void)accelerometer:(UIAccelerometer *)acel
didAccelerate:(UIAcceleration *)acceleration {

NSLog(@"x: %g", acceleration.x);
NSLog(@"y: %g", acceleration.y);
NSLog(@"z: %g", acceleration.z);

That's all. Seriously, it's that simple. I have already planning on a simple game that will use this technology, a sniper game. I am also looking at GameKit to explore how bluetooth works to make this game even better, a multiplayer sniper game. Just think about the possibility that has opened for newbies such as me!

With the recent release of iOS5 beta, there are so many welcoming features to developer worldwide. Especially ARC, which stands for Automatic Reference Counting. Any iOS developer will agree with me, the trickiest part in iOS app development memory management. ARC is just like a godsend! More details other time!

Thursday, June 23, 2011

Jason Ding - Distant friends

Few days ago I was browsing in linkedin searching for known friends in my network, and found that Jason Ding, brother to a friend of mine has started his own enterprise! Darn! As far as I know, he is a really good at what he does, here is his portfolio cum enterprise website. I always know from his sister that Jason is doing great work, but haven't really got the chance to take a peek at it.

Just for the sake of it, here it's, a screenshot of his website.

[caption id="" align="alignnone" width="443" caption="Jasonding.com"]Jasonding.com[/caption]

Wednesday, June 15, 2011

JWT Worldmade - My post made it there!

[caption id="" align="alignleft" width="597" caption="JWT Worldmade"]JWT Worldmade[/caption]

Few months ago, JWT Worldwide has requested and encouraged everyone in its offices worldwide to submit any content that could potentially make them proud. I heard the news and quickly submitted one of my pet project, which I named Checkbill.

It's a simple flash application that has the ability to check your electrical appliance's electricity usage and from there your bill can be calculated. This small project took me around 2 months with occasional few hours per day and more hours on weekends to complete.

It was a nice piece of project as it also helped me to further strengthen my understanding of how a more complex flash projects works! Below is another screenshot of the project that is showcased in JWT global network site. If you want to give this small application a try, head over here. I am still maintaining it at its minimum. Am thinking of upgrading some of its components when I have the time after my current iOS casual game project launched! Stay tune!

[caption id="" align="alignnone" width="508" caption="JWT Worldmade"]JWT Worldmade[/caption]

UIGestureRecognizers - UIPanGestureRecognizer - UIPinchGestureRecognizer

Updated post here
UIGestureRecognizers - UIPanGestureRecognizer - UIPinchGestureRecognizer - Part 2

Alright, straight into codes, let's look at one solid example of implementation.

Example goes,
 panGesture = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureMoveAround:)] autorelease];
    [panGesture setMaximumNumberOfTouches:2];
    [panGesture setDelegate:self];
    [dragView addGestureRecognizer:panGesture];

-(void)panGestureMoveAround:(UIPanGestureRecognizer *)gesture;
    UIView *piece = [gesture view];
    [self adjustAnchorPointForGestureRecognizer:gesture];

    if ([gesture state] == UIGestureRecognizerStateBegan || [gesture state] == UIGestureRecognizerStateChanged) {

        CGPoint translation = [gesture translationInView:[piece superview]];
        [piece setCenter:CGPointMake([piece center].x + translation.x, [piece center].y+translation.y*0.1)];
        [gesture setTranslation:CGPointZero inView:[piece superview]];

This simple example, illustrates how do we continuously set the position of an object when it's being panned around.

A short read into iOS Human Interface Guideline here, you might realise something like a zoom button, a left/right button, or any interface that act as most as intermediary between end-user and the application is not encouraged in iOS app.

So, what can the cocoa framework do to help us in this matter? Apple engineer has made it relatively easy for developers to include pinching, panning ability to their apps.

In fact, the most appealing selling point of iOS interface, it's the ability to manipulate photo in Photo Album apps when iOS was first launched back in the 2007.

By getting rid of the intermediaries, your iOS app provides better overall immersive user experience. As such, your app's interface is cleaner and easier to use. Though you might also have to consider the paradigm that you use, as not all users have the same experience as you are.

//Last post, I forgot to add in the protocol that the class has to conform to which is UIGestureRecognizerDelegate
//So your header file will have something like this
@interface MyView : UIView 

//At the header file, just need to write these few lines of code
UIPanGestureRecognizer * panGesture;
UIPinchGestureRecognizer *pinchGesture;

@property(nonatomic, retain) UIPanGestureRecognizer * panGesture;
@property(nonatomic, retain) UIPinchGestureRecognizer *pinchGesture;

//At your implementation file, these few lines of code should get your GestureRecognizer going
panGesture = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureMoveAround:)] autorelease];
    [panGesture setMaximumNumberOfTouches:2];
    [panGesture setDelegate:self];

//The pinch gesture
pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scalePiece:)];
    [pinchGesture setDelegate:self];
    [piece addGestureRecognizer:pinchGesture];

//Down here, we have the UIView that we want to pan around with. Here is a little tips, when you are working with UIImage and want to pan or pinch them around. You may want to add them to a UIView before doing so. Because I was having very peculiar behavior adding gesture recognizer to UIImage directly.
    [dragView addGestureRecognizer:panGesture];

-(void)panGestureMoveAround:(UIPanGestureRecognizer *)gesture;
    UIView *piece = [gesture view];

//We pass in the gesture to a method that will help us align our touches so that the pan and pinch will seems to originate between the fingers instead of other points or center point of the UIView
    [self adjustAnchorPointForGestureRecognizer:gesture];

    if ([gesture state] == UIGestureRecognizerStateBegan || [gesture state] == UIGestureRecognizerStateChanged) {

        CGPoint translation = [gesture translationInView:[piece superview]];
        [piece setCenter:CGPointMake([piece center].x + translation.x, [piece center].y+translation.y*0.1)];
        [gesture setTranslation:CGPointZero inView:[piece superview]];
    }else if([gestureRecognizer state] == UIGestureRecognizerStateEnded)
        //Put the code that you may want to execute when the UIView became larger than certain value or just to reset them back to their original transform scale

- (void)pinchGestureMoveAround:(UIPinchGestureRecognizer *)gestureRecognizer
    [self adjustAnchorPointForGestureRecognizer:gestureRecognizer];

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
        [gestureRecognizer view].transform = CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale]);
        [gestureRecognizer setScale:1];
    }else if([gestureRecognizer state] == UIGestureRecognizerStateEnded)
        //The reset works much different here, where applying transform to CGAffineTransformIdentity doesn't work well. You may need to rescale UIView back using setRect function.

- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
        UIView *piece = gestureRecognizer.view;
        CGPoint locationInView = [gestureRecognizer locationInView:piece];
        CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview];

        piece.layer.anchorPoint = CGPointMake(locationInView.x / piece.bounds.size.width, locationInView.y / piece.bounds.size.height);
        piece.center = locationInSuperview;

Tuesday, June 14, 2011

Flash Facebook API -OAuth - Experimental Attempt

Taking a look back Facebook Flash API, it was a rather thrilling experience as the example providing here has an obvious bug that might have been purposefully placed to keep the newbies on their edge. It had me gnashing teeth for a few hours trying to figure out what the hell did I done wrong. Everything was in place! I have made sure that everything was there, even made extra effort to put in error event listener for network, progress, data and connection. But there was no error being recorded!

After hours of pulling my hair (literally), I began to read the code and digest the content more comprehensively. That's where I found the object being passed as one of the parameters are being instantialized as null and not carrying any data with it. So I thought, well, fuck, I have wasted a good 5 hours of mine on things that were so obvious. Darn.
protected function handleCallApiClick(event:MouseEvent):void {
var requestType:String = getRadio.selected ? "GET" : "POST";
var params:Object = null;
if (requestType == "POST") {
try {
params = JSON.decode(paramsInput.text) as Object;
outputTxt.appendText("\n\nDECODING JSON into Object: " + params.toString());

} catch (e:Error) {
outputTxt.appendText("\n\nERROR DECODING JSON: " + e.message);

//Facebook.api(methodInput.text, onCallApi, params, requestType); //Original
Facebook.api(methodInput.text, onCallApi, params, requestType);

Well, you will notice that I have parsed the text into JSON and cast it as an object before putting it in as one of the parameters. It's a good to know thing, just in case you are wondering why the post from your Facebook Flash API app turns out to be empty post, null post or just more hairs on the floor.

Wednesday, June 8, 2011

Flash Twitter API - OAuth - Proxy to Connect and Communicate

Few days ago, my creative group head asked me to explore into Twitter API for flash. He had some innovative idea of executing some twitter based flash services. That had me scratched my ass for a good few minutes, as my experience with Facebook and Twitter hasn't quite been a nice brownie. It has changed from XAUTH, to OAUTH, the transition hasn't really been friendly to developer. But my experience with Flash remoting using AMFPHP has been particularly rewarding as the implementation is quite similar and simple.

Thus, the journey to re-explore this alien platform had begun. Hours into research the current Twitter API for flash, which is TwitterScript. But looking at the deployment date. It was way back in year 2009. Man, was I too outdated to know that Twitter has abandoned flash platform for good? Or hasn't there been any update to the Twitter API for flash since then? After some code reading into the source files, I realized that there are quite a number of new features that were introduced lately wasn't included in TwitterScript. But that was nothing to be surprise of. Especially Twitter Streaming API, which is highly sought after by developers worldwide.

And so, I stumbled upon this site that offers quite insightful and helpful tutorial of setting up the OAUTH, proxy and all its necessary backend stuff. Here it is.  The steps are quite simple, I managed to set the whole thing up within minutes. It uses flex, but I am not a big fan of flex, I went ahead and made myself a flash version. It's here for peeps who are interested to download. Please get in touch with me on my email or leave a comment here so that I can send you the files.

Anyway, here's the file for download.

Sunday, June 5, 2011

Time Management | iOS Project Management | Business Operation Management

The first question that I get asked the most when I meet new prospect or people is this,
"How do you manage your time? that you seem to have more than 24 hours per day?"

It's indeed true that juggling between a few projects at a time is not an easy feat, especially if you are fully tied down with an employment. With that, you might only have around 6-8 hours left for weekday for yourself. But what were most of us did with our free time, is we slumbered around our lunch and dinner, stuck in traffic jam, sat in front of the dumb box, or spent our brightest hours in pub/club/bar. Those hours could be well spent into doing something that will prove to have value later on in life. But we get this idea that doing small things such as reading an insightful article a day is not much of help to the entire journey. We were most indulged in doing big things like a flash game, an iphone app, or running a roadshow. But how often do we encounter such chances? The likelihood of such cases are quite slim as we might not even be doing anything worth mentioning at all if you are a nobody.

But I believed that nothing you do will go in vain if you have a goal in mind. It's this fortress of thinking that has brought me to where I am today. I set goal as I make full use of the free time I have. That in itself brings more value and meaning to my daily living. Any and everything on my desk has a value and a purpose attached to it. So, lesson number one. Nothing will go in vain, you just need to know where you are going with it.

The other stuff I encountered the most is the scenario where I have a few things to do. And all of them looked extremely important and crucial for me to finish them on the spot. But given the limited human ability and time constraint, I know it's impossible. That's where I prioritize the tasks at hand and find the best way out. It easier said than done, but how?

One way to do it, is to look at the impact of each instance. Which one will hit you hardest if you don't finish it in time? I guess that would shed some light into people who thought everything is important and must be tackled on concurrently. That said, while prioritizing is good, parallel strategy is even better if you know how to balance those difficult choices. One of the benefits of doing things parallel with your other plans, is that it gives you the chances to look back at what you have decided on your other project and apply that learning to others. In other words, you get a bigger picture of what you are doing with all these little projects, and all of the benefits with overall less time spent. Though I wouldn't recommend multitasking if you know you aren't born to be one, it's just natural to me, I certainly hope it's for you!

And the last thing on my list to a better time management, is to keep a list of what you are doing and keep planning. Be more flexible with your own time and always on the go to do more things! Be creative with it, you might find lots of fun in the process.