2011年4月30日 星期六

自體 IPA 安裝

Distribute Over the Air

在 iOS 4.0 中新增了一個 Protocol,只要在 iOS 裝置的 Safari 打開特製頁面,便能直接安裝授權了的 IPA 檔案。多謝 Thomas 的指導。步驟如下:

1. 在 Build 選單中選 Build and Archive
2. 打開 Organizer
3. 在左方欄選擇應用名稱
4. 點選右上角的 Share
5. 選擇好相應的 Provisioning Profile 後點擊 Distribute for Enterprise
6. 按畫面內容填上資料:

URL 是 IPA 將會存放於 WEB 伺服器的位置及 IPA 檔名
Title 是應用的名稱
Subtitle 我填上公司名稱
Large Image URL 是應用的 iTunesArtwork 檔案在 WEB 伺服器的位置
Small Image URL 是應用在 WEB 伺服器的小圖示位置

7. 之後,會詢問你想儲存 IPA 的位置及檔名
8. 把生成出來的 IPA 及 plist 放到 WEB 伺服器內
9. 建立 html 檔直指 plist 的位置

A href="itms-services://?action=download-manifest&url=http://www.pacess.com/release/ReelGold/20110429_ReelGold_1.00_01.plist"


這是一個非常好用的功能。我把過往的作品以這個方式打包後放到伺服器,並建立出一個 html 清單,方便銷售部門的同事能在任何地方安裝過往的作品,充份發揮了臨場的變化!

另外,今天亦學到了如何利用 php 檢整是否為 iPad 或 iPhone 的方法。基於以上的設計,可以按當前的機型來引導到相應的下載頁,十分好用。其語法如下:

$isiPad = strpos($_SERVER['HTTP_USER_AGENT'], 'iPad');
$isiPhone = strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone');

2011年4月29日 星期五

iPad 2 在兩小時內賣光

All iPad 2 have been sold out within 2 hours

iPad 2 的魅力依然強勁!在零晨 00:30 開賣到 02:20 已經把所有 iPad 2 都賣清光,包括黑色版在內。真的要寫個「服」字!


08:34am 百老匯門外買 iPad 2 的人龍


08:35am 豐澤門外買 iPad 2 的人龍

2011年4月28日 星期四

首個 Android 程序

My First Android Program

今日完成了手頭上的工作,而新的項目還未開始,拿了點時間學習 Android 編程。從安裝 Android SDK 到 Eclipse 的過程都很簡單,沒有問題發生。只是在啟動模擬器時太慢,差點以為自己的程序跑不到。試了幾個款式的 main.xml,感覺上是 HTML 的概念,不太難。不過我想把文字垂直置中時,找了一會都找不到方法,看來要學習一下看 API 資料的方法...。

2011年4月26日 星期二

SVN 伺服器設定成功

公司的 SVN 伺服器終於能成功運作。按照自己之前的教學去做,發現每次伺服器啟動之後,SVN 都能自動執行,可是在連接時卻發生問題。起初還以為是不能用 3690 以外的埠,原來卻是 autorun.sh 內的指令出錯「--listen-port=3690」中是不用「=」。現在己能使用 SVN,但又到另一問題發生,究竟用哪個 SVN 客戶端好呢?之前在 Lakoo 是使用 Eclipse,它的版本比較做得不錯。我其實是想用 XCode 內建的,但功能過份簡單,至少我找不到「比較」這個功能。試過用 SvnX,不懂用。看來要花點時間找一個適合的客戶端了。

2011年4月24日 星期日

艇仔...

最近跟 SHK 做一個項目。這個項目不是跟 SHK 直接溝通,而是作為艇仔的方式處理,當然艇仔是我。能稱為「艇仔」,原因是有多架大船在接駁。以我知道的中間人至少有兩層,即是由 SHK 到我共有四層,可想而知回報也不會好。最終承擔這個項目,是因為幫到朋友之餘,也能賺點錢。不過,經歷過今次的合作,發現代價其實很大。由於對上有三層,若每一層都加入自己的改動時,我的工作可是很大;若加上層與層之間沒有好好溝通,也使到做錯方向,到頭來改的也是我。若我的上家沒有好好把關,照單全收,改死的也是我。再加上上家傾不到訂金之類的東西,亦使得風險增加,雖則 SHK 這麼大的機構不會走數,但中間兩家走數也不為奇,反正一艘「艇仔」沉沒,還有其他「艇仔」可做。就算收足全額,按所花的時間來計算,比起自己寫 App 的收入更差,花的心血更多。下次再有同樣的機會時,真的要三思三思,不要再以「友情」矇蔽理性的眼睛,不竟這是一門生意,而不是友情客串...。

2011年4月22日 星期五

十年一遇

今天作出了回顧及檢討。發現了一個有趣的結果。十年前創造了加薪 50% 的成就,今天創造了加薪 60% 的傳奇,十年後希望是收入提升 70% 的神蹟!說起來好像很容易,但二十年來的薪金都是起起跌跌。在創造了第一次 50% 增長後,我認為無可能再創造出 50% 增長。慢慢的增長當然可以,我指的是爆發性一次增加 50% 的機會。只有在準備好自己,及能把握到機會之時,才能提升 50% 或更多。在此多謝支持過我的人,也多謝給予我機會的人!

2011年4月19日 星期二

新公司開張

今天是公司正式開張的日子。其實早在 4 月 7 日已經開始運作,只是投資者希望開張日子不要在清明節前後一星期的時間。雖然我不相信「好日」,但抱著「寧信莫不信」反正沒有隕失的心態,最終選了今天好日開張。早上開會有很多細節事項需要商量,就例如:辦公時間、清潔、電話系統、寬頻...等事項都要一一取得共識。不知是不是「好日」的影響,中午開張大餐時接到第一單工作的落實,事情來得特別順利。順著興奮的心情,我們決定下一次慶祝的是取得「收支平衡」的時間。我個人目標能在三個月內完成!希望一切順利~

2011年4月16日 星期六

免費下載「連線」雜誌五月號 iPad 版

Free WIRED Magazine

下載了「連線」雜誌五月號,發現它做得很好。有很多頁面能給讀者互動,例如:拿著放大鏡找碴、播放聲效、震走文字...等。最令我好奇的是它是如何透過「內容更新」去達成這些互動部份呢?始終每頁的互動要求都不同,如何能找出共通點並放在應用程式中使用,是一個技術!

既然有參考的價值,當然不會放過拿來「開刀」的機會。原來我想得複雜了。當中使用到的只是 HTML5 技術,加上一連串的動畫圖片,並不需要那麼高深的技巧。今次又受教了。多謝!

2011年4月15日 星期五

手機數據的增長

Mobile Traffic Growth

昨天出席了一個講座,當中講者說到「WEB 已死」及「流動數據」的成長,並帶出了「App 的需求」。上圖是講者引用的數據圖片。

2011年4月14日 星期四

設定 Google Notifier 的檢查時間

Modify Google Notifier Interval

新公司的 Google 電郵系統已經設定好了。為了在最快的時間回覆電郵,我安裝了 Google Notifier 來通知我。可是預設的檢查時間太長(好像有 18 分鐘以上),有時已經看過所有電郵,但通知上面的數字還保持著,反而提供了錯誤訊息。原本以為在「設定」中能找到相關的設定,找遍了卻找不到...。

最後找到了方法。先用滑鼠點擊通知的圖示,在不放滑鼠的情況下,按著 Command 及 Option,再選 Perferences。這時會有輸入視窗彈出,分別在上方輸入「AutocheckInterval」,要留意大小寫。下方輸入檢查的時間,以分鐘計算。我輸入了「1」,即是一分鐘檢查一次。點選「Set」就可以了。

2011年4月13日 星期三

把 Photoshop 內的層輸出成圖片檔

Export Layers to Files

在軟件製作的過程中,有時候需要把 Photoshop 內的每一個層輸出成獨立的圖片檔,這時可以安裝「Photoshop: Export Layers to Files」插件。下載後把 .jsx 安裝到 Macintosh HD > Applications > Adobe Photoshop CS5 > Presets > Scripts。重啟 Photoshop 後在 File > Scripts 便能找到

下載:http://www.pretentiousname.com/ps_exportlayersfast/index.html

2011年4月12日 星期二

SketchUp 貼圖效果

Cylinder with Texture by using SketchUp

經過幾次跟國內繪圖單位的交涉,得出來的都是錯誤的結果;不是解像度出錯,就是圖片沒有「退地」,甚至是圖片完全畫錯。估不到在事前已經用 SketchUp 繪畫了 61 幅參考圖,仍然會出現這樣的問題。與其說是「參考圖」,更應該說是「半成品圖」,他們要做的就是填上材質。看來最有效跟國內同事溝通的方法是當面溝通。

為了解決燃眉之急,我只好向他面索取材質貼圖及 Max 檔。當然,他們也給錯了東西...(汗)。幸好 Max 檔還算正確,至少我能從中取出「貼圖」。放到 SketchUp 出現了另一個問題:貼圖移位。我找不到能輸入貼圖座標的方法。最後用了 Photoshop 的 Offset filter,總算能把問題處理...。

2011年4月11日 星期一

不規則按鈕的檢測方法(二)

Irregular Shaped Button Detection (Part 2)

在一個跟地產發展商開發的項目中,使用了「不規則按鈕的檢測方法」。原本沒有甚麼問題,可是在「住宅平面圖」畫面中,客戶要求能直接點擊平面圖內的單位作出選擇;由於按鈕不能顯示出圖片,所以我把 Alpha 設定為「0」。誰不知就是因為「Alpha = 0」,系統會跳過檢測。

後來想到「Alpha = 0.01f」,結果是能被檢查,但讀進來的「像素」亦因 Alpha 值太低而當作沒被選中...。

最後,我只能改為使用「hitTest」並加入 maskImage 作為檢測的準則:
//-------------------------------------------------------
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if (!CGRectContainsPoint([self bounds], point)) {return nil;}

UIImage *image = maskImage;

// No image found, try for background image
if (image == nil) {
image = [self backgroundImageForState:[self state]];

// No image could be found, fall back to
if (image == nil) {return self;}
}

CGColorRef color = [[image colorAtPoint:point] CGColor];
CGFloat alphaValue = CGColorGetAlpha(color);
if (alphaValue < HPBUTTON_SELECTED_THRESHOLD) {return nil;}

return self;
}

2011年4月10日 星期日

61 顆五星

《AlexPanda》上架一星期,到目前為止的反應都是良好的,全球共有 61 顆五星。總算汲收了《銀行大亨》的經驗,挽回了玩家的心。希望《AlexPanda》的成績繼續「好 Game 有好報」!

2011年4月9日 星期六

有趣的六足

Interesting Hexapod

2011年4月8日 星期五

UILabel 的垂直翻轉

Apply Vertical Flip to UILabel

最近替客人做一個 iPad 項目,當中使用了最新的立體技術。當時客人希望能把時間值顯示於畫面之內。由於我只使用基本的 UIKit 來製作,在技術的限制下,我把時間值改為時間棒來達到相同的目的。可是客人還是有望使用時間值,原因是能帶出一點緊張的感覺;比起慢慢縮短的時間棒來得好。原本我真的不懂得的技術,今天終於學懂了,方法原來很簡單:
 label.layer.transform = CATransform3DMakeRotation(M_PI, 1.0f, 0.0f, 0.0f);

2011年4月6日 星期三

「損財傷丁」格局?

The Most Worst Office?

今天是小弟公司的辦公室收樓的日子。我遲到了十分鐘,到達時已經在處理最後的交樓手續。環顧四周的環境,光線充足,落地玻璃,十分開揚,感覺不錯。在簡單量度過面積後,拿出 iPhone 4 查看我最在意的大門方向。得出「申山寅向」,在八運是「損財傷丁」格局。沒錯,是最差的格局。

既然樓已租,能做的只是想辦法化解。我們決定在大門放置一塊屏風,籍著改變大門氣流的方向,從而改變運勢。雖然得出「損財傷丁」格局,亦計算過三次,確定沒有計錯;但我仍然帶著一份懷疑。原因是我深信正在好運之中,不可能會租到四個格局中最差的一個。雖然在整個決定過程中我沒有參與。而據了解上一手租客不是倒閉,而是換樓才不再續租,至於換大換小就不得而知。相信一定有甚麼地方遺漏了。就在晚上的時候,發現了一個錯誤。這個錯誤足以讓「損財傷丁」格局變成「旺財不旺丁」格局...。

2011年4月5日 星期二

Mobileprovision 及 IPA 的安裝方法

Installation of .mobileprovision and .ipa

以下是安裝 .mobileprovision 及 .ipa 的方法,適用於 Mac / Windows:

1) 打開 iTunes
2) 如圖把 .mobileprovision 證書拖拉到 iTunes 的 Library 內
3) 同步一次,以安裝「證書」到 iPhone / iPad 內
4) 把 .ipa 拖拉到 iTunes 的 Library 內
5) 同步一次,以安裝「程式」到 iPhone / iPad 內

如在上述過程中發生問題,很可能是因為 iPhone / iPad 還沒有設定成「開發用的裝置」。這時便需要用 Mac 機幫忙,到 Apple 網站下載並安裝 XCode。打開 XCode 內的 Organizer 後,在視窗的右方會看到一個「Use for Development」按鈕,點擊一下便能設定為「開發用的裝置」,再重覆一次安裝步驟便可。

2011年4月4日 星期一

安裝 Google SketchUp 8 插件的方法

Google SketchUp 8 Plugins Installation

找到了一個 Google SketchUp 8 的 OBJ 檔輸出插件,要把它安裝。方法如下:
1) 準備好插件檔 .rb
2) 把它拷到 Macintosh HD > Library > Application Support > Google SketchUp 8 > SketchUp > plugins
3) 啟動 SketchUp
4) 在 File 下便多了 OBJexporter 選項

之後,找到了 iPhone 用的 OBJ parser,嘗試讀入 OBJ 檔,一切順利。稍後會試一試貼圖方面。

2011年4月3日 星期日

AlexPanda 經已上架

AlexPanda is available in App Store now

《AlexPanda》在昨天上架了。今次的過程順利,亦好運地趕在周末上架,創造了一個很好的起步時機。

汲收了《帝國》及《銀行大亨》的經驗,在提交時做足了充份的檢查,確保了在 iOS 3.1.3 及最新版 iOS 4.3 下能運作正常,降低了玩家在購買後發生問題的機會。然而,最終還是有所錯失,在購買關卡上出現問題。幸好能及時修正,避免了「35 顆一星」的危機。

問題源於遊戲分開了測試用及上架用的連結地址,以便在修正時不會影響正常運作。然而,在提交後沒有檢查兩個連結地址的內容是否已經同步。由於上架用的連結地址版本較舊,所以發生問題。這是一個不能犯的錯誤!真的要大為警惕,好運不一定伴左身邊。下次有機會製作遊戲時,會考慮選擇一個地方先行開放,一切順利後才在全球發售。

這真是一個好運的開始,希望《AlexPanda》能成為小弟最大賣的一個作品!有興趣的朋友可到 http://itunes.apple.com/hk/app/alexpanda/id415787972?mt=8 免費下載。

2011年4月2日 星期六

不規則按鈕的檢測方法

Irregular Shaped Button Detection

今日遇到了一個難題,就是按鈕的設計是不規則。原本打算還是以方形的檢測來搞定,但這個問題一直在腦海中困擾著。相信是一號仔性格使然,不達至完美不罷休。於是決定要把問題解決。

要解決這個問題,需要由兩方面入手:
1) UIButton(決定是否被擊中)
2) UIImage(傳點圖片的 UIColor 數據)

我製作了一個新的 UIButton 類,專門用來檢測不規則的圖案,內裡只有一個 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 功能。這個功能會在點擊時執行,用以檢查當前按鈕是否被擊中。檢測的方法就是根據點擊位置,從按鈕圖片中取出 UIColor 值。有了這個值之後,檢查 alpha 便行。原本打算只取出 alpha 值,但想深一層,取出 UIColor 值會更好用。

為方便起見,對於 UIImage 要加入的部份,我都把它放到這個類之中。主要加入了 - (UIColor *)colorAtPoint:(CGPoint)point 功能,傳回 UIColor 數據。結果成功了,所有透明的地方都不會當作選中!

@implementation UIImage(PacessButton)

//-------------------------------------------------------
- (UIColor *)colorAtPoint:(CGPoint)point {

// Cancel if point is outside image coordinates
CGRect rect = CGRectMake(0.0f, 0.0f, self.size.width, self.size.height);
if (CGRectContainsPoint(rect, point) == NO) {return nil;}

// Create a 1x1 pixel byte array and bitmap context to draw the pixel into.
CGImageRef image = self.CGImage;
size_t width = CGImageGetWidth(image);
size_t height = CGImageGetHeight(image);

int bytesPerPixel = 4;
int bytesPerRow = (bytesPerPixel*1); // 8bpp
unsigned char pixelData[4] = {0, 0, 0, 0};

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixelData, 1, 1, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
if (context == NULL) {
NSLog(@"[colorAtPixel] Unable to create context!");
return nil;
}

CGContextSetBlendMode(context, kCGBlendModeCopy);

// Draw the pixel we are interested in onto the bitmap context
CGFloat pointX = point.x;
CGFloat pointY = height-point.y;
CGContextTranslateCTM(context, -pointX, -pointY);
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), image);
CGContextRelease(context);

// Convert color values [0..255] to floats [0.0..1.0]
CGFloat red = (CGFloat)pixelData[0]/255.0f;
CGFloat green = (CGFloat)pixelData[1]/255.0f;
CGFloat blue = (CGFloat)pixelData[2]/255.0f;
CGFloat alpha = (CGFloat)pixelData[3]/255.0f;
return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}

@end

//-------------------------------------------------------
@implementation PacessButton

//-------------------------------------------------------
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {

// We can't test the image's alpha channel if the button has no image. Fall back to super.
UIImage *image = [self backgroundImageForState:UIControlStateNormal];
if (image == nil) {return YES;}

CGColorRef color = [[image colorAtPoint:point] CGColor];
CGFloat alphaValue = CGColorGetAlpha(color);
return (alphaValue >= 0.1f);
}