頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


SpriteKitの物理エンジン使ってみた

頭と尻尾はくれてやる! / UIDynamicAnimatorで遊んでみる
↑ここでBox2Dまがいのことをやってみたけど、こういうのはSpriteKitを使えばいいってことを後で知ったんだよ。
こういうことができるんだね、ってことで作ってみたのが下の動画。



画面をタップしたところにボールを出現させてる。
動画撮影してるせいでFPSの値がだいぶ低下してるんだけど、撮影しなければこのくらいだとほとんど60FPSくらい(第五世代iPod touch)。

なかなか面白いフレームワークだねえ。iOS 7から物理エンジン使ったカジュアルゲームがどんどん出てくるのかな。


ところでこのSpriteKit、物理エンジンで計算される対象を表示させることができないみたいなんだけど、、、俺何か見落としてるのかな。
SKSpriteNodeで見た目を指定、SKPhysicsBodyで物理エンジンで計算させる物体の形状や重さを指定。SKSpriteNodeのプロパティphysicsBodyで関連づけするんだけど、動作チェックとかをするには物理エンジンの対象となってる形状を画像で表示できるといいんだけどね。


iOS 7のナビゲーションバーまわりの変更点は要注意

特にコードはないんだけど、、、ちょっと注意しないといけない場合があるってことで。
iOS 7でナビゲーションバーの操作が少し変わったよね。普通に使っているとなかなか気付かないような地味な変更なんだけど開発者は要注意だよ。
設定アプリなんかで試せばすぐにわかるんだけど、
[self.navigationController pushViewController:viewController animated:YES];
てな感じで次の画面に行くでしょ。

今までだと基本は左上のボタンで戻っていたけど、iOS 7だと画面左はしから指を右へ動かしていくと画面が指に従って操作できるんだよね。指に沿うから途中で戻るのをやーめた、なんてこともできる。
4インチ化の時にちょっと左上の戻るボタン押しにくいよなってなったけど、これなら片手でも簡単に操作できるし、元の画面のタイトルが青から黒に変化してく様が美しいぜえ!なんて最初は感心していたんだけどさ、、、俺アプリだと落ちる場合があったんだ。

画面Aでpush → 画面B
とするよ。よくあるパターンだと画面Aはテーブルビューでいろんな項目があって、あるセルをタップするとその項目の詳細を画面Bで選択できる、とかあるよね。
こういう構成の場合、今までだと左上のボタンを押すと

B, viewWillDisappear:
A, viewWillAppear:
B, viewDidDisappear:
A, viewDidAppear:

↑こんな順番にメソッドがコールされる。これはiOS 6でも7でも同じ。
ところが、iOS 7で戻るのやーめた、ってのができるようになったわけだけど、その場合は、、、

B, viewWillDisappear:
A, viewWillAppear:
↑戻り始めた時にこれがコールされる。
やっぱりやーめた、と画面Bに完全に戻った時に

A, viewWillDisappear:
A, viewDidDisappear:
B, viewWillAppear:
B, viewDidAppear:
↑こんな順でメソッドがコールされる。

こういう流れを考慮しておかないと、アプリが落ちたり、画面Aが全部表示されてから内容がパッと書き換えられるという微妙に悲しいことになるんだよね。


iOS 7で画像を使ったボタンを青くしたい

今までのiOS 6用コードをXcode 5&iOS 7で実行させたら「あら?」ってなることの一つにボタンの色があったんだよね。
特にどうするのよ?って思ったのがデフォルトのあの青色はどうしたらいいの?って思ったんだ。

Setting app in iOS 7

↑ほら、設定アプリとかで見るでしょ?この色よ。iOS 7以前と違いボタンがボタンっぽくなくなったけど、タップできるんだってわかるように青色で統一されてるよね(アプリによって色が違ったりもするけど)。

それで俺アプリもタップできるところはこの色を使いたいなあ、と思ったのよ。

ボタンに画像を使う場合、こういうコードでいいよね。ナビゲーションバーに表示させるようにしてるけど、挙動はself.viewにaddSubview:しようがさして変わらないはず。
{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:[UIImage imageNamed:@"closebutton.png"] forState:UIControlStateNormal];
    button.frame = CGRectMake(0, 0, 40, 40);
    [button addTarget:self action:@selector(buttonTappedHandler) forControlEvents:UIControlEventTouchUpInside];
        
    UIBarButtonItem *buttonItem = [[[UIBarButtonItem alloc] initWithCustomView:button] autorelease];
    self.navigationItem.rightBarButtonItem = buttonItem;
}
iOS 6 button

↑このコードだとiOS 6ではこんな感じ。
一応self.viewにもボタンを表示してる(左下ね)。

iOS 7 button

↑iOS 7だとこのように。
この色が黒いのはもともとの画像の色のままなんだ。
ってことは、iOS 7であの青で表示させたいのなら色を調べてその色で画像素材を作成しなおして、、、って面倒だよねえ。

でもありがたいことにいいのがあるんですよ、奥様!
{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    //以下同じ
}
iOS 7から UIButtonTypeSystem というのが追加されてて、これを使うとさっきのが

UIButtonTypeSystem

↑ほれ、この通り。あああ、ありがたや、ありがたや。


iOS 7の半透明ビューはどうするの

iOS 7の通知センターやコントロールセンターの背景ってすりガラスみたいになってるじゃない?
view.backgoundColor = [UIColor frostedGlass];
とかあってもよさそうだけど、どうもあれを実現するAPIは一般の開発者には公開されていないみたいで、某フォーラムで代替の方法が紹介されてたんだよ。それがこれ。
{
    UINavigationBar *navigationBar = [[[UINavigationBar alloc] initWithFrame:self.view.bounds] autorelease];
    if (type == TYPE2)  navigationBar.barStyle = UIBarStyleBlack;
    navigationBar.translucent = YES;
    self.view = navigationBar;
}
viewController内に置くコードなんだけど、要は画面全体をUINavigationBarオブジェクトをベースにしちゃえってアイデア。



↑モーダルビューの背景がすりガラス(frosted glass)っぽくなるようにしてる。
それっぽくもなるようだけど、、、緊急避難的な感じかな。細かく指定はできないんだよね、、、多分。

あと、このデモ用動画を作ってて初めて気が付いたんだけど、単純にモーダルビューとして新しいビューを表示させたら、アニメ終了直後に背景がすりガラスじゃなくなるんだ。原因はよくわからないんだけどね、、、
それでiOS 7から使えるようになったUIViewControllerAnimatedTransitioningプロトコルあたりを使ってモーダルビューを任意で動かせるようにしたら背景は(デモ動画のように)すりガラスのままなんだよ。うーん、、、?


UIDynamicAnimatorで遊んでみる

iOS 7にDynamicなんちゃらってのができたよね。それでちょっと遊んでみたよ。


[Box2d] Mechanical Clock (機械式時計) - wonderfl build flash online
↑大昔にFLASHのBox2Dでこんなのを作ったことがあった俺としてはどんなことができるのかな?!ってワクワクしながらいじってみたんだ。

まあこんなことができるんだよって動画を、、、↓



妙にカクカクして見えるのは気のせい、、、ではなく、実際にデバイス(iPod touch 第5世代)上で動かすとこんな感じなんだよ。
たかがこれだけのオブジェクトでカクカクするんだねえ。
コード的には改良の余地はあるんだけど、そもそもこのUIDynamicAnimator関連でBox2Dまがいのことまでしようというのが根本的な間違いみたいだね。歯車はないし丸いオブジェクトを作ることもできないし。見た目を丸くすることはできるけど、オブジェクトの衝突判断をする境界はどうやらviewのframeによるみたい(つまり四角形)。四角形のオブジェクトが衝突する相手をUIBezierPath
を使い曲線で指定することはできるんだけど。

ビューが動く時のちょっとしてエフェクトとして使うのが正解なんだろうね。
iOS 7だと6とは違って、通知センターを下に引っ張りだす勢いによって跳ね返る量が変わっているんだけど、こういう感じで使えばいいんだろうな。
じゃあ、、、こういうのはどう?



ほら、広告がこんな風に登場するとこれ動くのかな?って触りたくなるでしょ、、、ってまあこんな実装したら糞アプリ認定確実だね(もちろん俺のアプリには使っていないよ)。
うーん、なにか面白いアイデアはないものかな?


Box2DみたいなのはSpriteKit使えばできるじゃないか!ってこれ書いただいぶ後に知ったよ。




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.