FrozenBear

f:id:ryufloat:20130317212343p:plain
2/12 に鎖国法人EDOMODEにてリリースしました。

音のならないアラームアプリです。

f:id:ryufloat:20130317212339p:plain
https://itunes.apple.com/jp/app/frozenbear/id556500451?mt=8

2/28 にiPhone女史にて http://www.iphone-girl.jp/application-review/248230.html
3/7   にmeet-iにて http://web.meet-i.com/?area=iphone&genre=new&article_id=00000020229&offset=1
記事を掲載していただきました。ありがとうございます!

使い方はiPhone女史さんの記事に詳しく載っていますし、買っていただければチュートリアルが表示されるのでそちらを参照してください。


ここでは技術的な事を。

iOS4.3以降対応。
フレームワークはkobold2d v2.0.4、内部はcocos2d v2.0.0を採用しました。

今回はタイマーをスタートさせたときに雪を降らせるエフェクトをかけました。
それを実装するためにcocos2dのパーティクルシステムを使っています。

文字はGlyphDesignerで作成し、CCLabelBMFontでおいています。
フォントは Lao-MNと、そのBold。なかなか珍しい物を使っています。
そのままだと少し横幅が広いので、横幅のみ0.9倍にしています。

ボタンは共通のアニメーションをかけるので、次のようなクラスを継承して作成しました。

@interface ButtonMenu : CCMenu 

-(void)toBeEnableWithDuration:(float)duration Opacity:(float)opacity;
-(void)toBeEnableWithDuration:(float)duration Opacity:(float)opacity Delay:(float)delay;

-(void)toBeDisableWithDuration:(float)duration Opacity:(float)opacity;
-(void)toBeDisableWithDuration:(float)duration Opacity:(float)opacity Delay:(float)delay;

@end
@implementation ButtonMenu

-(void)toBeEnableWithDuration:(float)duration Opacity:(float)opacity
{
    [self runAction:[CCSequenceactions:
                     [CCCallBlock actionWithBlock:^{self.isTouchEnabled = YES;}],
                     [CCFadeTo actionWithDuration:duration opacity:opacity],
                     nil]];
}

-(void)toBeEnableWithDuration:(float)duration Opacity:(float)opacity Delay:(float)delay
{
    [self runAction:[CCSequenceactions:
                    [CCDelayTime actionWithDuration:duration],
                    [CCCallBlock actionWithBlock:^{self.isTouchEnabled = YES;}],
                    [CCFadeTo actionWithDuration:duration opacity:opacity],
                    nil]];
}


-(void)toBeDisableWithDuration:(float)duration Opacity:(float)opacity
{
    [self runAction:[CCSequenceactions:
                    [CCCallBlock actionWithBlock:^{self.isTouchEnabled = NO;}],
                    [CCFadeTo actionWithDuration:duration opacity:opacity],
                    nil]];
}

-(void)toBeDisableWithDuration:(float)duration Opacity:(float)opacity Delay:(float)delay
{
    [self runAction:[CCSequenceactions:
                    [CCDelayTime actionWithDuration:duration],
                    [CCCallBlock actionWithBlock:^{self.isTouchEnabled = NO;}],
                    [CCFadeTo actionWithDuration:duration opacity:opacity],
                    nil]];
}
@end

タッチを無効にしてから透明度を変化させる事が多々ありましたのでこのクラスを継承して使っています。

CCFadeToを使用している事に関してはこちらhttp://ryutamaki.hatenablog.com/entry/2013/03/10/065609をどうぞ。
CCCallBlockがすごく便利です。

バックグラウンドでのアラームについては、長いバイブレーションの作成が出来ないようだったので、連続で通知させる事で解決しました。
見た目が悪くなってしまいました、すみません。

セッティング画面でグラフの表示、非表示の切り替えの時はexpで変化させています。
またグラフ上のインディケーターの動きは次のような実装を取っています。

-(void)setDotPos:(CGPoint)pos
{
    targetPosition = pos;
}

-(void)update:(ccTime)delta
{
    float vectorDegree = atan2(targetPosition.y - self.position.y, targetPosition.x - self.position.x);
    float vectorSize = sqrtf(powf((targetPosition.y - self.position.y), 2) + powf((targetPosition.x - self.position.x), 2));
    vector = ccp(vectorSize * cosf(vectorDegree), vectorSize * sinf(vectorDegree));

    float speedAdjust = 12.0;

    self.position = ccpAdd(self.position, ccp(vector.x / speedAdjust, vector.y / speedAdjust));
    if(CGPointEqualToPoint(targetPosition, self.position))
    {
        self.position = targetPosition;
    }
}

targetPositionに最終的な目標となる位置を格納しておき、現在の位置を起点として、目標を表す位置ベクトルを作ります。
そのベクトルで、インディケーターの位置を変更していきます。
speedAdjustで、スピードを調整します。

基本的にcocos2dのdrawメソッドで描画しているのでOpenGL ES 2.0を使って居ます。
アンチエイリアスの掛け方を知っているかた居ませんかね………?

画像をあまり使っていないのですが、重い理由はチュートリアル画像の複数言語対応のためです。


次回アップデートを3月中に予定しており、驚いてもらえるようなものを作っています。
お楽しみに。