2014年10月25日土曜日

(一応解決)Yosemite非互換:cocos2dのCCRotateByがおかしい(^_^;)

OS X Yosemite環境下のXcode Version 6.1 (6A1052d)でcocos2d 1.0.1使用アプリをビルドするとCCRotateByの挙動(正常に回転しない)がおかしい件ですが、対処法が分かりました。

原因特定のためテスト用コードにてCCActionの組み合わせを変えたりしましたが全然ダメで、ビルド設定をいろいろ試行したところ運良く原因を特定する事ができました。(^^)v

<不具合対処>
1.Targetビルド設定
 Architectures → BaseSDKの設定値を「OS X 10.10」→「OS X 10.9」に変更。

原因としてはYosemite(OS X 10.10)SDKでビルドするとCCRotateBy動作不正が発生するが、Mavericks(OS X 10.9)SDKでは発生しない。

と言うことでBaseSDKを「OS X 10.9」に設定する事で今回は対処出来ましたが、今後も古いSDKを利用し続ける訳には行かないのでどっかのタイミングで抜本的な対応が必要になるかも知れませんね〜 (^^ゞ

しかし、状況的にはYosemite(OS X 10.10)SDKのバグっぽい挙動とも言えますので、バグであればアップルの修正で万事解決なんですけど、どうなることやら。。。

ではまた〜

Yosemite非互換:cocos2dのCCRotateByがおかしい(^_^;)

OS X Yosemiteですが、いろいろ非互換って言うかバグが多いのか調子悪いです。(^^ゞ

操作せずに放置してるだけなのにキー入力を一切受け付けなくなってリセットするしかないとか、スリープから復帰しないとか、リセットする回数が多くなってます。

今、非互換対応でハマっているのが。。。

cocos2d 1.0.1のCCRotateBy(CCRotateTo)がちゃんと回転してくれない(泣)
90度余分に回転しては戻りしているのか回転アニメーションが滑らかじゃなくブリンクしているような感じでチラチラとした動きをします。(^_^;)

その他のアクションは正常に動作しているみたいなので画像回転時の行列計算がおかしくなっている感じもしますが、何が何だか原因不明です。

このアプリで使っているCocos2dライブラリも古いし、バージョンアップするか結構大掛かりな対応が必要かも(^^ゞ

この不具合以外にも画像ファイル読み込み変換処理やiCloud処理とかにも不具合が出ているので、Yosemite対応には時間が掛かりそうな感じ。。。 とほほ(泣)

ではまた〜

2014年10月23日木曜日

OS X Yosemite(Version:10.10)インストールしました

2014年10月17日に公開された「OS X Yosemite」をインストールしました。

いつもは新OSのダウンロード開始とほぼ同時に試してみるのですが、今回はうっかりしてまして。。。(^^ゞ 昨日インストールしました。

念のため、現行メインOSX環境(OS X Mavericks)を外付けHDへ復元保存して、外付HDDからブートもできる状態にした後にアップデートしています。
 └この辺りは外付HDDからも簡単にブートできるMacは便利です。(^^)

この機能のおかげで外付HDD内にはSnow Leopard、Lion、Mavericks等々過去の環境を保持しておくことができます。

少々話が逸れましたが、肝心の「OS X Yosemite」の感想は。。。

懸念していた通り、デザインがチープな感じになって安っぽいイメージがしますね〜(^^ゞ
iOS7の時もそうでしたがフラットデザインに変わった直後は慣れないせいか安っぽい感じが酷かったですが、それも慣れれば違和感を感じなくなりましたからYosemiteに関しても今後の慣れでしょうかね。

iPhoneの場合は本体デバイスもフラットデザインとの相性っていうか違和感も少なかったと思うのですが、MacBookとかはアルミ筐体に黒色キーボードトップとか本体自体が渋めのデザインですから、その画面にパステル調のフラットデザインでは調和が取れないですよねぇ〜 まぁ慣れるまでにはちょっと時間が掛かりそうな感じです。(^_^;)
 └次に発売されるMacBookは白色ポリカーボネイトの筐体になるかも知れませんね。

機能面ではiOSデバイスとの連携機能が強化されてますし、操作性もiOSに合わせていっている感じがします。 別に悪いことではないですけどね。

特にHandoff機能はiCloudによるファイル共有やデータ授受より進んだ連携を提供していますし、スゴイ機能だとは思いますが利用する局面が思い付かないって言うか、便利そうなんだけどどう使えば効率的で重宝するのかが分からない感じかも。。。(^^ゞ

速度面ではかなりチューニングされているのか全ての動作が機敏になりキビキビと動きます。 この点だけでもアップデートする理由になると思うほどですね。

最後に互換性ですが、思っていた以上に非互換がありそうな感じです。。。(^_^;)
私のアプリに問題があるのかも知れませんが、MacOSX用アプリ7本(3種)の内3〜4本のアプリに動作不良がありました。(^^ゞ

GameCenter対応部分とiCloud部分なんで何かしらの非互換がある可能性が考えられますね。
 └早く対応しなくては。。。

全般的には動作も早くなり、iOSデバイスとの連携機能も強化されているYosemiteですが、非互換により正常動作しないアプリが少なからずあると思われますので、Yosemite対応版のアプリが出揃うまでは急いでアップデートしない方が得策かも知れません。

ではまた〜

2014年9月29日月曜日

iOS8非互換:スプラッシュ画像が拡大表示される!?

iOS8ではアプリ非互換は特に問題無いと判断してましたが、一本だけ不具合が発生してました(^^ゞ

<不具合現象>
・アプリ起動時のスプラッシュ画面が拡大されて描画される。

<原因>
・起動直後の画面は正常に描画されているので、起動時にiOSが自動的に描画する画像(Default.png)は正常に処理されているが、cocos2dフレームワークでのスプラッシュ画面表示が拡大されて描画されていると推測される。

<対処方法>
・Xcode 6.0.1でビルドして再現テストするも、シミュレーターで起動しても再現されない。 不具合が発生していたiPad3を接続して実機テストするが再現しない!?
・いろいろ試しましたが原因の特定に至らずで、iOS8ライブラリでリビルドするだけで不具合現象は解消されました。
・OSバージョンを判定している箇所の問題かもと思い、OSバージョン判定箇所も調べたんですが、調べた範囲では問題になりそうな箇所は見付けられず。。。
・う〜ん、何か納得いかないですが。。。 取り敢えずはこのアプリをリリースする事にしました(^^ゞ

<見解>
・拙作アプリだけではなく、他のアプリでも起動時にスプラッシュ画像が拡大表示されているアプリも見かけるので、iOS8非互換による問題の可能性もありますね。
・不具合現象が発生しているアプリは一本だけで他のアプリもcocos2dライブラリを利用していますが、cocos2dバージョンの違いによって当現象の発生有無に違いが出ているのかも知れません。
 └不具合発生あり:cocos2d 2.1.0
 └不具合発生なし:cocos2d 1.0.1 , cocos2d 2.0.0 , cocos2d 3.1.0

ではまた〜

2014年9月22日月曜日

iPhone5:「スリープ/スリープ解除ボタン交換プログラム」申し込み

今までメインで使っていたiPhone5ですが、大分前から「スリープボタン」が押しても反応しない不具合が出ていました。
 └日に日に悪化して今では100回に1回位しか反応してくれない(^^ゞ

その後、アップル社自体が不具合を認め「iPhone 5 スリープ/スリープ解除ボタン交換プログラム」として無償修理を受け付けていました。

しかしながら、故障修理に5〜7日間掛かるので代替機を借りたとしても、日々使うアプリを使えないとか、なにかと不便なんで新機種買うまではと故障修理を見送っていました。

今回、9/19にiPhone6購入を機にiPhone5のボタン交換プログラムに申し込みました。

iPod、iPad、iPhoneと何台(8台!?)も所有してますが、故障修理でAppleサポートのお世話になるのは初めてでしたのでどうなる事かとやや心配でしたが、Webページ上でシリアル番号を入力して修理対象デバイスを確認後、サポートページ上で「スリープ/スリープ解除ボタン交換プログラム」を選び、Apple取扱店へ行くのも面倒だったので「ピックアップ&デリバリー修理 」を選択すべく電話サポートの予約を入れました。

電話サポートの予約では日付と時間帯を指定すればアップルから折り返し電話を掛けてくれます。(こちらから電話することも出来ます)

私は9/22 9:30からの時間帯を前日に指定しておいたら、本日(9/22)9:30丁度に電話が掛かってきました。
 └サポートフリーダイアルに電話して延々と待たせられる事を考えると良い取り組み
  だと思いますね。待たされると繋がった時点でイライラが募ってますからw

私のiPhone5が故障修理対象である事を確認後、指示に従ってデバイス設定を変更→ヤマト運輸の集荷手続きをすれば完了でした。 あとは故障修理後に自宅に宅配されてくるのを待つだけです。
 └梱包する必要もなく、ケースを外してそのままiPhoneを渡すだけでOKです。

ではまた〜

2014年9月21日日曜日

iPhone 6 発売日に入手出来ました

auのファストクーポンでWeb予約してた「iPhone 6 64GB スペースグレー」が9/19(金)午前中に届きました。

機種変更(機種増設)だったんで、現行のiPhone 5からSIMカードをiPhone6へ差し替え後、電源ON → バックアップから復元でiPhone5→iPhone6へ移行完了しました。

引き継ぎ可能な設定も元通りで、アプリもデータも引き継げますのでiPhone間の機種変更は楽ですね〜。


iPhone6とiPhone5を並べた写真ですが、ふた回り程大きいですかね。

最初こそ、「デカっ」って感じましたが直ぐに慣れて逆にiPhone5を見ると良くこんな小さな機種を使っていたなぁって思う程、iPhone6は使い勝手が良いサイズだと思います。

アプリも私の使っている範囲では特に大きな問題も生じておらず快適に使えています。

今までiPhone5で指紋認証機能が付いた機種は今回のiPhone6が初めてでしたが、指紋認証は便利ですね〜。
指の角度を変えたりとか、いろいろ試しましたが誤認識も無く瞬時に認証できるのはとても素晴らしいです。

使い始めて3日程度ですがiPhone5から完全に移行できましたので、お役御免となったiPhone5はロックボタンのリコール対象なのでアップルに無償修理に出したいと思います。

ではまた〜

2014年9月13日土曜日

iPhone 6 なんとか予約注文しました〜(^^ゞ

元々、ポケベル時代からドコモ携帯を使い続けていたのですが、docomoがiPhoneの取り扱いを始めるのが待ち切れなくて、2年前にauキャリアへMNPしました。

softbank製iPhoneは会社自体にあまり良い印象を持っていなかったのでスルーできたんですけど、auのスマートバリュー戦略に乗る形でdocomoガラケーからau iPhone5へ乗り換えました。

今回はiPhone5 → iPhone6への初めての機種変更となります。

auからファストクーポンってのが郵送されてきてまして、1万5千円引きで優先的にiPhone6が自宅に郵送されてくるって内容だったので、安くなるし優先的に実機が届くって言葉に抗えずw 申し込む事に。。。

iPhone6予約申し込みが9/12解禁だったのにファストクーポン専用の予約申込み画面へのSMS通知(Cメール)が届かずでヤキモキしてたんですが、本日(9/13)13時頃に通知メッセージが来ました。

で、少しでも早く予約して発売日(9/19)に手に入れたいと予約画面にて入力しましたが、ここでやっちゃいました。(^^ゞ

オーダー:iPhone6 スペースグレイ 16GB

iPhone6 Plusも考えましたが、1万円札とほぼ同じ大きさって事で1万円札を出して耳に当てるもあまりの大きさに断念。。。(^_^;) 胸ポケットにも入り切らないサイズじゃないのか。

色は携帯は「黒」って決めているんで問題無し。

ディスクサイズが「16GB」って。。。 思いっきり勘違いしてました。(^^ゞ
16GB、64GB、128GBから選ぶのに64GBなんて必要無いし、128GBなんて論外と思い消去法で16GBを選んじゃってました。

今使っているiPhone5が32GBで結構空きが少ない状態なのに。。。 16GBじゃあ流石に足らないよぉ〜

早く予約機種の変更をしないと本申し込みメールが来ちゃうよと思い、予約完了のお知らせメールを見ると、auホームページ内の「注文履歴」から一旦予約をキャンセルしてから再度予約せよとの説明がある。 が、肝心の「注文履歴」機能が昨日からのアクセス集中でメンテナンス中で使えない。。。(^_^;) どないせいちゅーんだ。

これは詰んだかと諦めかけてましたが、自分のミスとは言え16GBじゃ流石に支障が出るので、ダメ元でauお客様窓口へ電話して相談する事に。。。

結構待たされて担当者に電話が繋がり、状況を説明するも「注文履歴」からキャンセルして再度予約して欲しいとの回答。 ある程度は覚悟していたとは言えマニュアル通りの回答に半ば諦めかけましたが、「メンテナンス中」でキャンセルできない旨を伝える。

すったもんだの末、上司に相談するって事で1〜2分待たされた後に、意外にもau側で予約をキャンセルしていただけるとの事。 その後も少しやりとりはあったのですが無事にキャンセルされたようで、再度iPhone6(64GB)を予約する事ができました。

しかし、イレギュラーな手順で一旦キャンセルしているので本申し込みのメールが届くまでは安心できませんが、9/19に届くことを願っております。

ではまた〜

2014年9月11日木曜日

iOS8 GM seedアップデートしてみた

iOS Dev centerサイトにiOS8 GM seedが公開されてましたので、弊社iOSアプリ動作検証のためiOS8へアップデートしました。

9/19にはiPhone6購入予定で、現行メインで使っているiPhone5はiOS7環境での確認用として利用しようと考えていますので、iPad Wi-Fi (3rd generation)をiOS7→iOS8へアップデートする事にしました。

結論から書きますと、iOS7→iOS8は見た目も機能的にも大きな非互換は無く、弊社公開中のアプリは全て問題無く動作しました。

その他、定番アプリやソーシャルアプリ、有名ゲームアプリも私がインストールしているアプリに関しては正常に動作しており、非互換は少なそうな感じですね。

ではまた〜

2014年7月18日金曜日

cocos2d v3.1非互換:CCCallFunc系メソッド置き換えでの留意事項

<留意事項>

  • CCCallFunc系クラス名を単純にCCActionCallFuncに置き換える事でコンパイルエラーは消すことが出来ますが実行時にSender値がNullのためアプリが異常停止する場合がありました。
    (原因)
    ・cocos2d v.3.1ではARC機能が有効になっているため、funcMenuHide:メソッドを呼び出したタイミングで既にオブジェクトが開放されていてエラーになる。
    (対応)
    ・CCActionCallBlockメソッドに置き換える。
  • CCActionCallFuncメソッドは極力使わず、CCActionCallBlockへの置き換えを検討した方が良いと思います。

// Actionメニュー非表示
    [actionMenu runAction:[CCSequence actions:
                            [CCFadeOut actionWithDuration:ACTION_DURATION / 2.0],
                            [CCCallFuncN actionWithTarget:self selector:@selector(_funcMenuHide:)],
                            nil]];

// Actionメニュー非表示
    [actionMenu runAction:[CCActionSequence actions:
                            [CCActionFadeOut actionWithDuration:ACTION_DURATION / 2.0],
                            [CCActionCallBlock actionWithBlock:
                             ^{
                                 [self _funcMenuHide:_actionMenu];
                             }],
                            nil]];




ではまた〜

2014年7月17日木曜日

cocos2d v3.1非互換:CCLayer → CCNodeクラス置き換え時の留意事項

<留意事項>

  • CCLayer → CCNodeクラス置き換え時、継承元クラスを変更するだけではタッチイベントを受け取ることが出来ずハマったんで留意事項としてまとめておきます。
    1.initメソッド:コンテンツサイズ設定
    ・CCNodeクラス生成後は「self.contentSize」がwidth=0,height=0の状態。
    ・初期状態ではタッチイベントが領域外のため発生しない。
    ・コンテンツサイズ設定として画面全体を設定するとタッチイベント取得可能。
    2.initメソッド:タッチイベント有効化
    ・タッチイベントを明示的に有効にする。
    3.touchBeganメソッドは必須
    ・touchMovedイベントのみ使う場合でもtouchBeganメソッドを記述する必要あり。
    ・touchBeganメソッドを書かないとtouchMovedイベントを取得できない。

#import <Foundation/Foundation.h>
#import "cocos2d.h"


@interface TitleEffectLayer : CCNode {
}


@end

#import "TitleEffectLayer.h"

@implementation TitleEffectLayer

// ----- イニシャライザ --------------------------------------------
-(id) init
{
 if( (self = [super init]) ) {
        // コンテンツサイズ設定
        self.contentSize = [[CCDirector sharedDirector] viewSize];
        
        // タッチイベント有効化
        self.userInteractionEnabled = YES;
 }
 return self;
}

//----- アクションメソッド -----------------------------------------
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGPoint touchLocation = [touch locationInNode:self];
 
    DEBUG_NSLog(@"touchBegan[BEGIN](x=%f , y=%f , cnt=%d)",touchLocation.x,touchLocation.y,touch.tapCount);
}

- (void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGPoint touchLocation = [touch locationInNode:self];
 
    DEBUG_NSLog(@"touchMoved[MOVE](x=%f , y=%f , cnt=%d)",touchLocation.x,touchLocation.y,touch.tapCount);
}


@end



ではまた〜

cocos2d v3.1新機能:座標位置設定、コンテンツサイズ設定方法に待ちわびた機能が。。。(^o^)

<新機能項目>

  • 座標位置設定:positionTypeプロパティ
    ・このプロパティで画面座標位置指定方法を変更できます。
    1.CCPositionTypePoints:従来通り(デフォルト)
    2.CCPositionTypeUIPoints:UIKit座標系 - 左上原点
    3.CCPositionTypeNormalized:親ノードの最大値を1.0とした割合指定
  • コンテンツサイズ設定:contentSizeTypeプロパティ
    ・このプロパティでコンテンツサイズ指定方法を変更できます。
    1.CCSizeTypePoints:従来通り(デフォルト)
    2.CCSizeTypeUIPoints:UIKit座標系 - 左上原点
    3.CCSizeTypeNormalized:親ノードの最大値を1.0とした割合指定

    <positionTypeプロパティ設定サンプル>
        // create and initialize a Label
        CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World"
                                               fontName:@"Marker Felt" fontSize:64];
    
        // ask director for the window size
        CGSize size = [[CCDirector sharedDirector] winSize];
    
        // position the label on the center of the screen
        label.position =  ccp( size.width /2 , size.height/2 );
    
        // add the label as a child to this Layer
        [self addChild: label];
      
    
        // Hello world
        CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World"
                                               fontName:@"Chalkduster" fontSize:36.0f];
        label.positionType = CCPositionTypeNormalized;
        label.color = [CCColor redColor];
        label.position = ccp(0.5f, 0.5f); // Middle of screen
        [self addChild:label];
        
    


    <所感>

    • cocos2d v3系の目玉機能と言えそうな新機能です。 うーん素晴らしい(^o^)
    • 上記プロパティを「……TypeNormalized」に設定することで相対位置(割合)で設定可能になりますので、画面サイズに依存しない位置指定やサイズ指定が可能となり柔軟な配置が実現できます。
      └ iPhone 5以降での4インチ画面サイズ(1,136 x 640 px)対応にも使えそうです
    • CCLayout、CCLayoutBox等の配置用ノードと組み合わせて全てのノードを相対配置にしておけば今後新たな画面サイズが登場しても大丈夫そうですね。


    ではまた〜

    cocos2d v3.1新機能:便利そうなCCActionが追加されてる〜

    <新機能項目>

    1. CCActionRemove
      ・CCSprite等のノードオブジェクト消去(cleanup:YES固定)
    2. CCActionSoundEffect
      ・サウンド再生
    3. CCActionSpriteFrame
      ・Spriteフレーム画像の変更
    4. CCActionProgressFromTo
      ・プログレスバーアニメーション:簡単に進捗率バー表示できそう

      <CCActionRemoveサンプル>
          // ダブルタップエフェクトアニメーション
          [animeNode runAction:[CCSequence actions:
                                [CCEaseBackIn actionWithAction:
                                 [CCScaleTo actionWithDuration:0.5 scale:0.2]],
                                [CCCallFuncND actionWithTarget:animeNode
                                                      selector:@selector(removeFromParentAndCleanup:)
                                                          data:(void *)YES],
                                  nil]];
      
      
          // ダブルタップエフェクトアニメーション
          [animeNode runAction:[CCActionSequence actions:
                                [CCActionEaseBackIn actionWithAction:
                                 [CCActionScaleTo actionWithDuration:0.5 scale:0.2]],
                                [CCActionRemove action],
                                nil]];
      
      


      <所感>

      • 今まで「CCCallFunc」で個別に実現していた機能が簡単に実装できますので、かなり便利になってますね。
      • 上記以外にも新しく加わったCCActionもありますのでいろいろと試してみたいと思います。


      ではまた〜

      2014年7月16日水曜日

      cocos2d v3.1非互換:シーン切り替え方法・トランジションの変更

      <非互換項目>

      • シーンから別のシーンへ切り替える方法(replaceScene:メソッド)の使い方が変更になっている。
      • シーン切り替え時のトランジション(切り替えエフェクト)も変更になっている。
        └ トランジションの種類が少なっているような。。。

            // Game画面へ切り替え
            [[CCDirector sharedDirector] replaceScene:
             [CCTransitionZoomFlipAngular transitionWithDuration:1.0
                                                           scene:[GameScene node]]];
        
        
            // Game画面へ切り替え
            [[CCDirector sharedDirector] replaceScene:[GameScene node]
                                       withTransition:[CCTransition transitionFadeWithDuration:1.0]];
        
        


        <対応方法>

        • 上記、コードサンプルの通りシーン切り替え方法を改修する。
        • 「CCTransitionZoomFlipAngular」トランジションが無くなっているので取り敢えずは別のトランジションに置き換えています。

        <所感>

        • トランジションタイプとして「CCTransitionZoomFlipAngular」を使っていましたが、どうもcocos2d v3.1ではこのトランジションが存在していないようです。
          └ cocos2dフォルダを「Angular」文字列で検索してもヒットしない…(^^ゞ
        • cocos2d v3.0のCCTransition.mファイルには「CCTransitionZoomFlipAngular」も存在しているみたいなのですが、v3.1では無くなっている!?
          └ また、トランジション種類自体もかなり減っているみたいです。。。
        • 「CCTransitionZoomFlipAngular」トランジションを置き換える事が可能なのかについては引き続き調査したいと思います。


        ではまた〜

        2014年7月15日火曜日

        cocos2d v3.1非互換:CCMenu,CCMenuItemが無くなっている(^^ゞ

        <非互換項目>

        • CCMenu,CCMenuItemが無くなっており、メニュー操作については完全に書き換えになります。(^_^;)

        <対応方法>

        • CCMenuItemの代わりには新規クラスであるCCButtonで置き換える。
        • CCMenuの代わりには新規クラスであるCCLayoutで置き換える。
          └ CCLayoutの利用な必須では無くメニューアイテム自動配置機能の代替。

                // メニューボタン生成
                _menuItemGamePlay = [CCMenuItemImage itemWithNormalImage:@"Button_GamePlay.png"
                                                           selectedImage:@"Button_GamePlay_Sel.png"
                                                                  target:self
                                                                selector:@selector(tappedGamePlayButton:)];
                CCMenuItem *menuItemNextStage = [CCMenuItemImage itemWithNormalImage:@"Button_NextStage.png"
                                                                       selectedImage:@"Button_NextStage_Sel.png"
                                                                              target:self
                                                                            selector:@selector(tappedNextShapeButton:)];
                CCMenuItem *menuItemPriorStage = [CCMenuItemImage itemWithNormalImage:@"Button_PriorStage.png"
                                                                        selectedImage:@"Button_PriorStage_Sel.png"
                                                                               target:self
                                                                             selector:@selector(tappedPriorShapeButton:)];
                _menuItemHowToPlay = [CCMenuItemImage itemWithNormalImage:@"Button_HowToPlay.png"
                                                            selectedImage:@"Button_HowToPlay_Sel.png"
                                                                   target:self
                                                                 selector:@selector(tappedHowToPlayButton:)];
                // メニュー生成
                CCMenu *topMenu = [CCMenu menuWithItems:_menuItemGamePlay, menuItemNextStage, menuItemPriorStage,
                                   _menuItemHowToPlay, nil];
                
                // メニュー位置設定
                topMenu.position = CGPointZero;
                _menuItemGamePlay.position = ccp(self.contentSize.width/2, self.contentSize.height/2-290);
                menuItemNextStage.position = ccp(self.contentSize.width/2+384, self.contentSize.height/2-291);
                menuItemPriorStage.position = ccp(self.contentSize.width/2-384, self.contentSize.height/2-291);
                _menuItemHowToPlay.position = ccp(38, self.contentSize.height - 38);
                
                [self addChild:topMenu z:1];
                
        
                // メニューボタン生成
                _btnGamePlay = [CCButton buttonWithTitle:@""
                                             spriteFrame:[CCSpriteFrame frameWithImageNamed:@"Button_GamePlay.png"]
                                  highlightedSpriteFrame:[CCSpriteFrame frameWithImageNamed:@"Button_GamePlay_Sel.png"]
                                     disabledSpriteFrame:nil];
                [_btnGamePlay setTarget:self selector:@selector(tappedGamePlayButton:)];
                
                CCButton *btnNextStage = [CCButton buttonWithTitle:@""
                                                       spriteFrame:[CCSpriteFrame frameWithImageNamed:@"Button_NextStage.png"]
                                            highlightedSpriteFrame:[CCSpriteFrame frameWithImageNamed:@"Button_NextStage_Sel.png"]
                                               disabledSpriteFrame:nil];
                [btnNextStage setTarget:self selector:@selector(tappedNextShapeButton:)];
                
                CCButton *btnPriorStage = [CCButton buttonWithTitle:@""
                                                        spriteFrame:[CCSpriteFrame frameWithImageNamed:@"Button_PriorStage.png"]
                                             highlightedSpriteFrame:[CCSpriteFrame frameWithImageNamed:@"Button_PriorStage_Sel.png"]
                                                disabledSpriteFrame:nil];
                [btnPriorStage setTarget:self selector:@selector(tappedPriorShapeButton:)];
                
                _btnHowToPlay = [CCButton buttonWithTitle:@""
                                              spriteFrame:[CCSpriteFrame frameWithImageNamed:@"Button_HowToPlay.png"]
                                   highlightedSpriteFrame:[CCSpriteFrame frameWithImageNamed:@"Button_HowToPlay_Sel.png"]
                                      disabledSpriteFrame:nil];
                [_btnHowToPlay setTarget:self selector:@selector(tappedHowToPlayButton:)];
        
                // メニューボタン登録
                [self addChild:_btnGamePlay z:1];
                [self addChild:btnNextStage z:1];
                [self addChild:btnPriorStage z:1];
                [self addChild:_btnHowToPlay z:1];
                
                // メニューボタン位置設定
                _btnGamePlay.position = ccp(self.contentSize.width/2, self.contentSize.height/2-290);
                btnNextStage.position = ccp(self.contentSize.width/2+384, self.contentSize.height/2-291);
                btnPriorStage.position = ccp(self.contentSize.width/2-384, self.contentSize.height/2-291);
                _btnHowToPlay.position = ccp(38, self.contentSize.height - 38);
                
        


        <所感>

        • ほとんど全てのプログラムで利用していたであろうメニュークラス(CCMenu,CCMenuItem)の改変ですので影響範囲が広く、改変内容も互換性の無い変更(文字列置換では対応できない)ですので、多くのプログラマが「なんでやねん」と突っ込んでいるのではないでしょうかw
        • この改変もSpriteBuilder対応なんでしょうかね!? ここまで既存クラスを変更しまくったんですから、その分はSpriteBuilderから恩恵を受けたいものです。


        ではまた〜

        cocos2d v3.1非互換:CCLabelTTF生成メソッドの引数が変わってる

        <非互換項目>

        • CCLabelTTF生成メソッドの引数が変わっている。
          └ 文字位置揃え指定「hAlignment」が無くなり、プロパティ設定になっています。

        CCLabelTTF *labelVersion = [CCLabelTTF labelWithString:theVersion
                                                      fontName:kFontCopyright
                                                      fontSize:16.0
                                                    dimensions:CGSizeMake(200, 20)
                                                    hAlignment:kCCTextAlignmentRight];
        
        
        CCLabelTTF *labelVersion = [CCLabelTTF labelWithString:theVersion
                                                      fontName:kFontCopyright
                                                      fontSize:16.0
                                                    dimensions:CGSizeMake(200, 20)];
        labelVersion.horizontalAlignment = CCTextAlignmentRight;
        
        


        <対応方法>

        • 上記、コードサンプルの通り文字位置揃え指定プロパティで設定するよう改修する。

        <所感>

        • CCLabelTTF生成メソッドの引数ってバージョンアップの度に変更になっているって言って良い位変更になっており、良く使うメソッドですし毎回修正している感じがします。(^^ゞ
        • CCLabelTTF以外のラベル系クラスでも同様に変更となっている可能性が考えられますね〜。


        ではまた〜

        cocos2d v3.1非互換:ccDrawLine等の直接描画関数が無くなっている!?

        <非互換項目>

        • cocos2dで画面に線や円等の図形を直接描画する関数群(ccDrawXXXX)が利用できなくなっていると思われます。
        • Google検索して関連情報を集めてみましたが"CCDrawingPrimitives.h"ヘッダーをインポート云々の書き込みを見つけましたがv3.1ではこのヘッダーファイル自体存在せず、どうもccDrawLine等の直接描画関数は使えなくなっている感じですね。


        <対応方法>

        • CCDrawNodeクラスを用いた線や円等の図形描画に書き換える。

        -(void)draw{
            // 線の色設定
            ccDrawColor4B(64, 64, 64, 255);
            
            // 線の太さ設定
            glLineWidth(1.0);
            
            // 線の描画幅の設定
            CGFloat gap = kTriLineLength;
            
            // 三角形の高さ計算
            CGFloat takasa = gap * (sqrt(3.0) / 2.0);
            
            // 描画開始Y座標
            CGFloat baseY = -4.0f;
            
            // 横線の描画
            CGPoint p1, p2;
            for (CGFloat y=baseY+takasa; y<self.contentSize.height; y=y+takasa) {
                p1=CGPointMake(0, y);
                p2=CGPointMake(self.contentSize.width, y);
                ccDrawLine(p1, p2);
            }
        }
            
        
        -(id) init
        {
         if( (self=[super init] )) {
                // 画面サイズ取得
                CGSize viewSize = [[CCDirector sharedDirector] viewSize];
                
                // 背景描画ノード生成
                CCDrawNode *drawNode = [CCDrawNode node];
          [self addChild:drawNode z:0];
                
                // --- 背景描画処理 ------------------------------------------
                // 線の色設定
                CCColor *colorLine = [CCColor colorWithCcColor4b:ccc4(64, 64, 64, 255)];
                
                // 線の太さ設定
                CGFloat thickness = 1.0;
                
                // 線の描画幅の設定
                CGFloat gap = kTriLineLength;
                
                // 三角形の高さ計算
                CGFloat takasa = gap * (sqrt(3.0) / 2.0);
                
                // 描画開始Y座標
                CGFloat baseY = -4.0f;
                
                // 横線の描画
                CGPoint p1, p2;
                for (CGFloat y=baseY+takasa; y= 0 && x <= viewSize.width) ||
                        (x-zure >= 0 && x-zure <= viewSize.width)) {
                        p2=CGPointMake(x-zure, viewSize.height);
                        [drawNode drawSegmentFrom:p1 to:p2 radius:thickness color:colorLine];
                    }
                    
                    // 右斜線
                    if ((x >= 0 && x <= viewSize.width) ||
                        (x+zure >= 0 && x+zure <= viewSize.width)) {
                        p2=CGPointMake(x+zure, viewSize.height);
                        [drawNode drawSegmentFrom:p1 to:p2 radius:thickness color:colorLine];
                    }
                }
            }
         return self;
        }
            
        

        <所感>

        • 直接描画関数(ccDrawXXXX)を多用しているプログラムでは対応がかなり大変になると思います。(描画タイミングも変わっちゃいますし)
        • CCDrawNodeクラスでも置き換えが困難なケースでは別の方法を探す事になると思いますが、今回のプログラムではCCDrawNodeクラスでの対応が可能でしたのでそれ以上は調べておりません。  └ 代替策等の情報をお持ちの方はコメントを付けていただければ幸いです。
        ではまた〜

        2014年7月14日月曜日

        cocos2d v3.1非互換:CCLayerクラスが無くなっている(^^ゞ

        <非互換項目>

        • タッチイベントを処理する重要なクラスと位置付けられていると思っていたCCLayerクラスが無くなっている。
        • タッチイベント有効化やイベント名自体も変更されている。


        <対応方法>

        • CCLayerクラスの置き換え
          ・CCLayer → CCNodeクラスへ置き換えます。
        • タッチイベント有効化
          ・「self.touchEnabled = YES;」→「self.userInteractionEnabled = YES;」へ変更
        • タッチイベント処理オーバーライドメソッドの変更
          ・下記、対応例を参照。

        // タッチイベント有効化
        self.touchEnabled = YES;
        
        // タッチイベント処理オーバーライドメソッド
        -(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{}
        -(void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event{}
        -(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event{}
        -(void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event{}
            
        // タッチ開始処理
        -(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
        {
            // タッチ位置取得&変換
            UITouch *touch = [touches anyObject];
            CGPoint location = [touch locationInView: [touch view]];
            location = [[CCDirector sharedDirector] convertToGL:location];
        
        }
        
        // タッチイベント有効化
        self.userInteractionEnabled = YES;
        
        // タッチイベント処理オーバーライドメソッド
        -(void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event{}
        -(void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event{}
        -(void)touchEnded:(UITouch *)touch withEvent:(UIEvent *)event{}
        -(void)touchCancelled:(UITouch *)touch withEvent:(UIEvent *)event{}
            
        // タッチ開始処理
        - (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
        {
            // タッチ位置取得
            CGPoint location = [touch locationInNode:self];
        
        }
        



        <所感>

        • SpriteBuilder開発ツール採用による影響と推測していますが、CCLayerクラスを消しちゃうなんて思い切った事を判断をしたものだと関心します。(^^ゞ
        • CCLayerを機能拡張しているクラスとかどうすんだろって思いますよね〜!?
           CCScrollLayer,CCTMXLayerとか。。。


        ではまた〜

        cocos2d v3.1非互換:画面サイズ取得([[CCDirector sharedDirector] winSize])が変わってる

        <非互換項目>

        • cocos2dで画面サイズを取得するメソッドが変更になっている。
          └取得メソッド名:winSize → viewSize


            // 画面サイズ取得
            CGSize winSize =[[CCDirector sharedDirector] winSize]; 
            
        
            // 画面サイズ取得
            CGSize winSize =[[CCDirector sharedDirector] viewSize];
            
        


        <対応方法>

        • 画面サイズ取得メソッド名変更
          ・文字列への一括置換で対応可能。

        <所感>

        • cocos2dで画面サイズを取得する際に良く使う方法(メソッド)なので置換箇所は多いと思いますが一括置換で対応できますので、大きな影響は無いと思います。
        • 「winSize」と言うメソッド名が用途を示すには分かり辛いがための変更と推測しますが、ホント良く使うメソッドなんでマクロ定義でのサポートも検討して欲しかったですね。
          └画面サイズの取得:ccGetViewSizeとか、ccScreenSizeとか。。。


        ではまた〜

        cocos2d v3.1非互換:オーダー順変更メソッド「reorderChild:」無くなっている!?

        <非互換項目>

        • CCSprite等ノードオブジェクトの重なり順(どっちが前面に存在するか)を変更するメソッド(reorderChild:)が無くなっている。

        <対応方法>

        • 重なり順を変更したいノードオブジェクトのzOrderプロパティで設定する。

        // cocos2d v2での記述
        [_triangleShape.parent reorderChild:_triangleShape z:kOrderNormal];
        
        // cocos2d v3.1での記述
        _triangleShape.zOrder = kOrderNormal;
        


        <所感>

        • zOrderプロパティで直感的に分かり易くなったと思うので、良い改変だと思います。


        ではまた〜

        2014年7月11日金曜日

        cocos2d v3.1非互換:CCSpriteクラスも変えちゃうの(^^ゞ

        <非互換項目>

        1. 「spriteWithFile:」メソッド名変更( →「spriteWithImageNamed:」)
        2. 透明度プロパティ(opacity)が0〜255指定が0.0〜0.1実数指定に変更


            // 爆弾スプライト生成
            CCSprite *theBombSprite = [CCSprite spriteWithFile:@"Bomb.png"];
            
            // 爆弾透明度変更
            theBombSprite.opacity = 128;
            
        
            // 爆弾スプライト生成
            CCSprite *theBombSprite = [CCSprite spriteWithImageNamed:@"Bomb.png"];
            
            // 爆弾透明度変更
            theBombSprite.opacity = 0.5f;
            
        


        <対応方法>

        1. 「spriteWithFile:」メソッド名変更
          ・「spriteWithImageNamed:」文字列への一括置換で対応可能。
        2. 透明度プロパティ(opacity)変更対応
          ・指定方法が0〜255整数値指定から0.0〜1.0実数指定に変わっているので透明度プロパティ設定箇所を実数指定に修正。

        <所感>

        • 「spriteWithFile:」メソッド名変更はUIKitの「[UIImage imageNamed:@"xxx.png"];」のメソッド名命名に合わせたんでしょうか? だとすると、リソースファイルから読み込むメソッドが他にも存在すればメソッド名変更されている可能性がありますね。
        • 透明度プロパティ(opacity)変更については元々整数指定(0〜255)に違和感があったので実数指定(0.0〜1.0)に変更した事には賛成なのですが、Assertionチェック等が入っていないようで1.0より大きな値を代入してもエラーにならないので見落としてしまう危険性が気になりますね。


        ではまた〜

        cocos2d v3.1非互換:定数定義名が結構変わってる!?

        <非互換項目>

        • 「kCC〜〜〜」で始まる定数定義名が違う名前に変わっている。

        <対応方法>

        • 置き換わったと思われる定数名を探して置換する。
        • 先頭の「k」文字を消した命名規則になったと思いきや「kCC」で始まる定数も残っているようで改変の規則性は無いかも。
        • 定数名の中で特徴的な文字列で全ファイル対象に検索を掛けるとそれっぱい定数名定義が見つかるんで地道に調べては置換する。(^^ゞ 面倒くさ!

        <所感>

        • タイプ定義とかしてくれてたらコードアシストで候補が表示されると思うんですけど、単純に「#define」してたりしてるんでイチイチ調べるのが面倒です。(^_^;)


        ではまた〜

        cocos2d v3.1非互換:カラー指定引数がCCColorクラスに統一!?

        <非互換項目>

        • 全部かどうかは調査し尽くしていませんがメソッド呼び出し時の引数でカラー指定している箇所がマチマチ(ccColor4F,ccColor3Bとか)だったのが「CCColor」インスタンスに統一されている感じがします。

        <対応方法>

        • カラー指定の引数値を「CCColor型」インスタンス値に変更する。

        <所感>

        • 今までがマチマチで統一感がなく不便に感じた事はありましたからこれも良い改変と思います。


        ではまた〜

        cocos2d v3.1非互換:CCAction関連クラスが全部クラス名変更

        <非互換項目>

        • CCAction関連のクラス名がほとんど全て変更となっている。

        <対応方法>

        • 下記の対応に従ってクラス名を全置換する。
        No
        旧クラス名
        新クラス名
        1
        CCSequence
        CCActionSequence
        2
        CCRepeat
        CCActionRepeat
        3
        CCRepeatForever
        CCActionRepeatForever
        4
        CCSpawn
        CCActionSpawn
        5
        CCRotateTo
        CCActionRotateTo
        6
        CCRotateBy
        CCActionRotateBy
        7
        CCMoveTo
        CCActionMoveTo
        8
        CCMoveBy
        CCActionMoveBy
        9
        CCSkewTo
        CCActionSkewTo
        10
        CCSkewBy
        CCActionSkewBy
        11
        CCJumpTo
        CCActionJumpTo
        12
        CCJumpBy
        CCActionJumpBy
        13
        CCBezierTo
        CCActionBezierTo
        14
        CCBezierBy
        CCActionBezierBy
        15
        CCScaleTo
        CCActionScaleTo
        16
        CCScaleBy
        CCActionScaleBy
        17
        CCBlink
        CCActionBlink
        18
        CCFadeIn
        CCActionFadeIn
        19
        CCFadeOut
        CCActionFadeOut
        20
        CCFadeTo
        CCActionFadeTo
        21
        CCTintTo
        CCActionTintTo
        22
        CCTintBy
        CCActionTintBy
        23
        CCDelayTime
        CCActionDelay
        24
        CCReverseTime
        CCActionReverse
        25
        CCAnimate
        CCActionAnimate
        26
        etc…
        etc…

        <所感>

        • こうやって一覧で見ると元々のクラス名が雑然としている感じもして、CCAction系のクラスである事が一目で分かるって意味では改変後のクラス名の方が分り易い感はありますね。
        • Xcodeエディタでのコードアシストで「CCAction…」まで入力するとアクションクラスが並びますから選択し易いです。
        • 置換しないといけないのは手間ですが、この改変は「良し」としましょうw


        ではまた〜

        cocos2d v3.1非互換:CCSprite等のノード識別方法の変更

        <非互換項目>

        • CCSprite等のノード識別に使っていた「Tag」が「Name」に変わっている

        <対応方法>

        • getChildByTag:」,「removeChildByTag:」とかTag値で識別していた箇所はそれぞれ対応する「ByName」新メソッドへ全部置き換え。

          <改修例>

          1. addChildメソッド
            [_triangleShape addChild:theBombSprite z:1 tag:kTagMark];
                        ↓
            [_triangleShape addChild:theBombSprite z:1 name:kTagMark];

          2. getChildByTagメソッド
            [_triangleShape getChildByTag:kTagMark]
                        ↓
            [_triangleShape getChildByName:kTagMark recursively:NO]
              …「recursively:」は再帰的に探すって意味でしょうか!?

          3. removeChildByNameメソッド
            [_triangleShape removeChildByTag:kTagMark cleanup:YES];
                        ↓
            [_triangleShape removeChildByName:kTagMark cleanup:YES];


          <所感>

          • Tag指定は整数値だったのがName指定ではNSString文字列に変更となっていますので上記例では「kTagMark」は文字列定数として宣言しています。
          • この改変もSpriteBuilder採用による判断だとは推測できますし、確かに文字列での名前付けは自然で人間にも分り易いとは思いますがTag値による識別も残しても良かったんではないでしょうか。(Tagは使わなければ影響無いですし、既にTagを使っているプログラムの互換性も保てますので。。。)

          ではまた〜

          cocos2d v3.1非互換:「SimpleAudioEngine」クラスの置き換え

          <非互換項目>

          • 「SimpleAudioEngine」クラスが無くなっている

          <対応方法>

          • 「OALSimpleAudio」クラスへ置き換える
          • 「SimpleAudioEngine sharedEngine」文字列を「OALSimpleAudio sharedInstance」へ置き換えれば一気に改修可能かも。
          • playEffectメソッド以外にBGM再生とかしていればそれぞれ対応しているメソッドへ置き換える。

          <改修例>


          - (ALuint)playSound:(SoundIDType)inSoundType
          {
              // サウンド再生
              ALuint retSoundId = [[SimpleAudioEngine sharedEngine] playEffect:
                                            [_arraySounds objectAtIndex:inSoundType]];
              
              // 再生中サウンド識別子を返す
              return retSoundId;
          }

                    ↓

          - (id<ALSoundSource>)playSound:(SoundIDType)inSoundType
          {
              // サウンド再生
              id<ALSoundSource> retSoundId = [[OALSimpleAudio sharedInstance] playEffect:
                                                      [_arraySounds objectAtIndex:inSoundType]];
              
              // 再生中サウンド識別子を返す
              return retSoundId;
          }


          <所感>

          • ほとんどのケースでは文字列置換だけで対処可能そうですけど凝ったサウンド機能を利用していた場合は結構大変かも知れませんね。


          ではまた〜

          cocos2d最新バージョン v3.1非互換に驚愕!(その2)

          記事タイトルに「驚愕!」と煽りながら前回の記事ではARC対応程度の非互換だけでしたので、今回はまず現時点までに発見した「驚愕!」の非互換項目を一覧でどうぞ!

          <非互換項目>
          • 「SimpleAudioEngine」クラスが無くなっている
            └サウンド再生関連は別のクラスに置き換えとなります。
          • CCLayerクラスが無くなっている
            └「CCScene」と並んで基本的と思われた「CCLayer」クラスがありません。(^_^;)
          • CCMenuクラスが無くなっている
            └こちらも必ず利用する基本的なクラスですが無くなっています。
          • CCSprite等のノード識別に使っていた「Tag」が「Name」に変わっている。
            └「getChildByTag:」,「removeChildByTag:」とかTag値で識別していた箇所は全部修正

          まだ、移行作業を始めたばかりですが上記のような「何故それを変える!?」って言いたくなるような根底を揺るがすような非互換が多く一瞬自分の目を疑いたくなりました。(^^ゞ

          冷静になって好意的に考えるとこのバージョンから開発ツールのベースとなった(したい?)「SpriteBuilder」使用を前提に考えた改変のような気はします。

          「SpriteBuilder」がCCSceneをベースに生成するのでCCLayerは不要にしたとかCCMenuもメニューコントロールのグループ化と配置制御ならばCCLayoutに統合しようとか。。。

          また、Tag識別も整数値で識別するよりかは文字列で名前付けした方が分かり易いとの判断なのでしょうけど、イキナリ過ぎるような気はしますね。

          でもさすがに今回の改変は下位互換とか常に移行やメンテに重点を置いて考える日本人には理解し難いですね。(^^ゞ 欧米人の割り切り加減には驚くばかりです。。。(^_^;)

          と言うことで結論としてはcocos2d v2系列とv3系列は別物と捉えた方が良いと思いますので、既存v2で作成しているプロジェクトはそのままの方が良さそうです。

          新規作成で且つ「SpriteBuilder」の開発効率の恩恵を受けたい場合はv3.1の利用も検討できると思います。

          私は引き続きv2 → v3.1へのマイグレーション作業は続けていきたいと思いますので、新たに発見した非互換項目については随時当ブログにて公開させていただきます。


          ではまた〜