2012年1月31日 星期二

『向下拉』提示動畫實作

在遊戲的進行中,雖然讓玩家自行摸索過關的技巧是玩遊戲的一種樂趣,但是我們又不希望玩家卡在一個關卡後,就失去了繼續玩下去的興緻了,所以在樂田麵包屋遊戲中,有很多的操作需要有提示才能讓玩家可以順利的過關。這裡示範一個向下拉動畫的實作。



要完成這樣的一個動畫,可以有2種不同的方法,你可以用setAnimation的方法,也可以用animationImages的方法,如果用setAnimation的方法只要準備2張圖片,一張是向下的箭頭,另一張是手指,然後將箭頭的圖片固定,使用setAnimation的方法讓手指的圖片移動y座標,這樣就可以產生手指向下滑動的動畫。

但是我們今天示範另一個用animationImages的作法:首先,如上圖準備5張分格的圖,分別命名為dragDown_1.png到dragDown_5.png。然後在.h宣告一個

UIImage *dragDown

接著在.m實作dragDownTip的程序


- (void)dragDownTip{
     dragDown.hidden = NO;
     dragDown.animationImages = [NSArray arrayWithObjects:
                            [UIImage imageNamed:@"dragDown_1.png"],
                            [UIImage imageNamed:@"dragDown_2.png"],
                            [UIImage imageNamed:@"dragDown_3.png"],
                            [UIImage imageNamed:@"dragDown_4.png"],
                            [UIImage imageNamed:@"dragDown_5.png"], nil];
     [dragDown setAnimationRepeatCount:3];
     dragDown.animationDuration = 1.5;
     [dragDown startAnimating];
}

當要執行動畫的時侯, 只要下指令:

[self dragDownTip];

就可以了。真是比setAnimation麻煩多了...當初我怎麼沒想到要用setAnimation的方法呢?真是不經一事,不長一智...

2012年1月27日 星期五

『樂田麵包屋』過關畫面分解

在樂田麵包屋遊戲中,每一次過關的時侯,都會有一段6秒鐘的過關畫面。雖然只有短短的6秒鐘,但是裡面包含了不算簡單的工作。在此將這些動作分解讓大家瞭解一下。




















這個畫面雖然只包含了4個元素(從上圖左手邊的objects可以看得出來),一張背景,一個小廚師的圖,一個獎牌,和小廚師身邊的星星。

實際上這6秒的畫面包含了以下的畫面:

1張背景


2張小廚師




- (void)chefAnimate{
    
    animationChef.animationImages = [NSArray arrayWithObjects:
                                    [UIImage imageNamed:@"chef_verygood1.png"],
                                    [UIImage imageNamed:@"chef_verygood2.png"],
                                     nil];
    
    [animationChef setAnimationRepeatCount:10];
    animationChef.animationDuration = 1.5;
    [animationChef startAnimating];
    
    
}


5張獎牌不同光澤


- (void)verygoodAnimate{
    
    animationVerygood.animationImages = [NSArray arrayWithObjects:
                                         [UIImage imageNamed:@"medalVerygood1.png"],
                                         [UIImage imageNamed:@"medalVerygood2.png"],
                                         [UIImage imageNamed:@"medalVerygood3.png"],
                                         [UIImage imageNamed:@"medalVerygood4.png"],
                                         [UIImage imageNamed:@"medalVerygood5.png"],
                                         [UIImage imageNamed:@"medalVerygood1.png"],nil];
    
    [animationVerygood setAnimationRepeatCount:10];
    animationVerygood.animationDuration = 1;
    [animationVerygood startAnimating];
    
    
}


1張閃爍不停的星星
- (void)starAnimation{
    starImage.alpha = 0;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    starImage.alpha = 1.0;
    [UIView commitAnimations];
}




2012年1月24日 星期二

用presentModalViewController跳到另一個畫面

//如果是要從一個畫面(nib)跳到另一個畫面的方法,須指定要跳到的畫面,在這裡就是storeInfoViewController

- (IBAction)gotoStoreInfo:(id)sender {
    storeInfoViewController *storeView = [[storeInfoViewController alloc] initWithNibName:nil bundle:nil];
    [self presentModalViewController:storeView animated:YES];
}

//如果要回到剛才跳回來的畫面, 不需要指定要回到的畫面,反正它會自已回到剛才來的地方

- (IBAction)backToMenu:(id)sender {
    menuViewController *menuView = [[menuViewController alloc] initWithNibName:nil bundle:nil];
    [self presentModalViewController:menuView animated:YES];
}


2012年1月20日 星期五

用NSTimer讓程式慢個幾秒再做事

//在.h先宣告


NSTimer *delayTimer; //宣告一個NSTimer叫delayTimer(自已隨便取)

//在.m實作

delayTimer = [NSTimer scheduledTimerWithTimeInterval:1.5f  //在1.5秒後再去執行stopShakeSalt這個程序
                                                  target:self
                                                selector:@selector(stopShakeSalt)
                                                userInfo:nil
                                                 repeats:NO];

2012年1月13日 星期五

用AVAudioPlayer播放音效

在.h的宣告部份
#import <AVFoundation/AVFoundation.h> //先import AVFoundation後才能使用這個功能

AVAudioPlayer *titleBGM; //宣告一個新的聲音叫titleBGM(自已隨便取)是屬於AVAudioPlayer型式

- (void) playBGM; //宣告播放playBGM的功能

在.m的實作部份
//在init的時侯先設定titleBGM要播放音效檔
-(id)init{
    
    if (self = [super init]) {
        //下面紅字這一段是設定titleBGM
        NSBundle *bundle = [NSBundle mainBundle];
        NSString *path = [bundle pathForResource:@"menu" ofType:@"wav"];
        NSURL * url = [NSURL fileURLWithPath:path];
        titleBGM =[[AVAudioPlayer alloc] initWithContentsOfURL:url
                                                         error:nil];
        self->titleBGM.delegate = self;
    }
    return self;
}

//實作playBGM
- (void) playBGM{
    
    [titleBGM play];
}

//播放的使用方法

[titleBGM play];

2012年1月12日 星期四

操作的學習曲線

雖然大部份的人都會稱許iphone容易上手,連4.5歲的小朋友拿到手上幾分鐘後也知道怎麼操作,但是我相信還是有很大的一群人覺得iphone的操作方式和他們"熟悉的操作方式"很不同。

熟悉的操作方式對5,6年級生來說可能是大型遊戲機台,像快打旋風那種大支搖桿。對7.8年級生來說可能是線上遊戲打怪用的鍵盤加滑鼠,對9年級以後的可能是wii或kinect在空中比手劃腳的操作方式。第一支iPhone也不過是2007年才發表的,到現在也才5年不到的時間。對任何人來說,在螢幕上劃來劃去應該都不算是個原本熟悉的操作方式。所以在開發APP時,除非你是完全使用cocoa touch裡現成的UIController, 像是UITableView, UINavigator, UIPickerView...這些標準的操作界面,要不然只要你想創新,一定會遇到使用者學習曲線的問題。

我不喜歡用iOS裡制式的操作界面,我喜歡加入自已風格的操作方法,所以對剛拿到程式的使用者來說可能都需要多花一點時間去學習如何使用。如果是針對一般的使用者,我是沒辦法聽到他們邊學邊罵的實際狀況。但是如果是針對客戶,當著面看著他們一邊操作一邊抱怨怎麼會這麼的”不人性化“和他們熟悉的方法都不一樣,那真是會當場吐出血來。

雖然古有明訓 - 客戶永遠是對的,但是也不必因為這樣就放棄了創新的想法。任何的設計,其實多多少少都會有學習曲線。只是你怎麼在你的創新設計中加入讓使用者可以逐步趨近正確的行為。這可能又是一門大的學問了。這在『設計法則』(原點出版社)這本書裡提到這種設計法則叫Shaping,中文翻作“塑造”。以下節錄一小段內容來說明:
”塑造通常在無意識下發生。舉例來說,電玩遊戲利用塑造法則,當遊戲剛開始時,需要簡單的輸入就可以過關(得到『增強』),接下來的遊戲則需要益發複雜的操控行為,才能掌控更高的關卡。" 設計法則 P.222
我除了在我開發的第一個APP裡有操作說明的選項外,其它的APP我都是用“提示”的作法,尤其是對第一次的操作者。沒有清楚的提示說明,不只讓操作者不容易猜出正確的操作方法,也有可能讓使用者錯失了你費心設計的貼心功能。

對於客戶的反應,其實就不需要太放在心上,只要善盡對客戶說明你設計的原意,相信客戶也不是非得要堅持他們的想法才對。我相信如果哈利波特的作者在發行第一集哈利波特前,拿著原稿去給你的客戶先看過,客戶應該也會說“你這不對啊,什麼咒語會叫”疾疾 護法現身“啊,以前我們都嘛說”天靈靈.地靈靈“才像真的咒語嘛”!

本來要提一下這篇“塑造”裡提到一個很酷的例子,叫“信鴿計畫”,但是快睡著了,下次再提好了。有興趣可以自已先查查"Project Pigeon"。

2012年1月11日 星期三

Buenos Aires - Inception Park

剛從放泥就可看到的,真是超有創意的....整段影片不會讓人有賣弄技術的感覺(對,2012我就是在講你),看起來就讓人不會懷疑哪裡有什麼不對。有些事要不就是有創意但還沒那個技術,要不就有了技術但是沒有吸引人的創意。這真是難得又有技術又有創意的作品。


Buenos Aires - Inception Park from Black Sheep Films on Vimeo.

2012年1月10日 星期二

用systemSoundID播放音效

在.h的宣告部份
#import <AudioToolbox/AudioToolbox.h> //先import AudioToolbox後才能使用這個功能

SystemSoundID magicSound; //宣告一個新的聲音叫magicSound(自已隨便取)是屬於SystemSoundID型式

-(void)playMagicSound; //宣告播放magicSound的功能

在.m的實作部份
//在init的時侯先設定magicSound要播放音效檔
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

//下面紅字這一段是設定magicSound
NSURL *magicUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"magic-chime" ofType:@"wav"]];
OSStatus magicError = AudioServicesCreateSystemSoundID((__bridge CFURLRef)magicUrl, &magicSound);
if(magicError){
NSLog(@"error:%ld",magicError);
}
    }
    return self;
}

//實作playMagicSound
-(void)playMagicSound{
AudioServicesPlaySystemSound(magicSound);
}

//播放的使用方法

[self playMagicSound];


2012年1月6日 星期五

用setAnimation呈現動畫


- (void)showLines{
    lines.hidden = NO; //設定原本是隱藏
    CGPoint Lpos = lines.center;
    Lpos.y = -12.0f; //原本的位置是y座標在-12
    lines.center = Lpos;
    //這裡以上是動以前的位置
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:1];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    //這裡以下是預計要動的目的地
    Lpos.y = 10.0f; //讓要移動的物件從-12移到y座標10, 也就是垂直往下移動
    lines.center = Lpos;
    [UIView commitAnimations]; //執行移動的指令
}

2012年1月3日 星期二

用animationImages呈現動畫

-(void)showGood{
    chefAnimation.animationImages = [NSArray arrayWithObjects:
                                     [UIImage imageNamed:@"chef_good1.png"], //動畫由哪些圖片組成
                                     [UIImage imageNamed:@"chef_good2.png"],
                                     [UIImage imageNamed:@"chef_good2.png"],
                                     [UIImage imageNamed:@"chef_good2.png"],
                                     [UIImage imageNamed:@"chef_good2.png"],
                                     nil];
    
    [chefAnimation setAnimationRepeatCount:3]; //動畫重覆播放的次數
    chefAnimation.animationDuration = 3; //動畫每一輪的時間(秒)
    [chefAnimation startAnimating]; //開始執行動畫
}

2012年1月1日 星期日

從這裡開始

投入iPhone APP的開發算算也已經二年多了,雖然這種有一餐沒一餐的日子,在物質生活的享受上是沒辦法和過去安穩的上班收入相比,但是能看到自已絞盡腦汁設計出來的APP順利上架,然後得到一些正面的回應,那種成就感是過去坐辦公室為老板打拚的我從未體會的。

我自已不是個科班出身的程式設計師,更不是美工相關科系畢業,二年前投入這個領域完全是從零開始的學習,光是弄懂什麼是物件導向就花了好幾個月的時間,更別說是要寫出一個能用的軟體,第一個APP總共花了我9個月的時間才順利上到App store。

我相信有很多像我一樣充滿熱情的年輕人及想要追夢的中年人也想要投入App開發的領域,但是覺得不得其門而入。中文的資料少之又少,Apple所提供的資訊雖然完整,但又很艱澀難以難解。我是還有基本的英文閱讀能力才能一路披荊斬棘的走到現在。因此,希望我在這裡開始分享我在APP開發的一些經驗,能讓有興趣往這條路發展的朋友可以順利一點的上手,不需要花這麼多時間在摸索技術的部份,能把時間花在創意的發想上,去創造真正的價值。