2014年11月25日

iOS8に適用する『Sprite Kit iPhone 2Dゲームプログラミング』(その3)

『Sprite Kit iPhone 2Dゲームプログラミング』のiOS8対応というわけではないが、コードの掲載漏れと思われるものが一箇所あったので(著者とはなんの関係もないが)訂正しておく。これを除くと紙面掲載のコード(+画像リソース)だけでサンプルコードが完成するだけにもったいない。

(正誤表により訂正したコードは必要)

8.2.3プレイヤーキャラの配置



GameScene.h中


#include "CharacterNode.h"

@interface GameScene : SKScene
@property (strong,nonatomic) CharacterNode *playerNode;
〜略〜
@end


あと明記されていないが、GameScene.mのコード断片は-initiWithSize:の最後に追加(または-moveToView:)。

8章は紙面の都合からか、ゲームオーバー処理など省かれている。他の画面と同様だから読者への宿題ということだろう。
posted by 永遠製作所 at 21:43| 東京 ☁| Comment(1) | TrackBack(0) | iPhone/iPod touch | このブログの読者になる | 更新情報をチェックする

2014年11月24日

iOS8に適用する『Sprite Kit iPhone 2Dゲームプログラミング』(その2)

前項で紹介した『Sprite Kit iPhone 2Dゲームプログラミング』はiOS7時代に書かれたもので、現時点のiOS8とは少しばかり違いがある。このiOS7とiOS8の違いに着目して実装する時の注意点をまとめたい。

SKSceneのdelegate



SKSceneクラスにiOS8 SDKからdelegateが設定された。本書ではSceneクラスにdelegateを設定してそこへコールバックするコードを書いている。つまり競合するのだ。

もちろんiOS8以降でしか使わないならなんら問題はない。同じ定義が重なっている場合には特にエラーにはならない。でも、iOS7でも動かしたいと思うと問題だ。

「id delegate;」を宣言するだけなら問題はない。型も同じなのでコンパイルできる。だが、iOS7ではSKSceneのインスタンスにはプロバティのdelegateもインスタンス変数の_delegateもないのだから、setDelegate:を呼び出すときに実行時エラーになってしまう。

回避方法としては、自分用に作ったdelegateの名前を変えることが考えられる。
@property (weak,nonatomic) id myDelegate;


    if ( [self.myDelegate respondsToSelector:@selector(sceneEscape:)] ){
id dummy = (id)self.myDelegate;
[dummy sceneEscape:self];
}


実機で動作確認を



シミュレータでもほとんどの機能は使えるようなのだが、ごく一部に正常に動かない機能があるようだ。ほとんど正常に動いているだけに、ちょっとおかしいなと思ってもほとんど正常に動いているので自分のコードが悪いのかと思ってしまう。

とりあえず実機で動かしてみよう。そうすれば正常に動いているかもしれないから。

一つは、CoreImageを使った機能。SKEffectNodeクラスは特殊効果としてCoreImageのフィルターを設定できる。だが、シミュレータではほぼすべて正常に動作しない。SKEffectNodeを使った効果を確認する場合にはシミュレータではなく実機確認が必須。

十分確認したわけではないが、Overtakeサンプルを実行するときに座標変換がおかしくなる。anchorPointを移動しているのが原因ではないかと思うが、衝突判定時に渡されてくるSKContactのcontactPointが間違った値で返ってくる。そのためエフェクトなどがおかしな位置に発生する。実機で確認すると正常な位置にエフェクトが出る。

一体何が正常に動作してなにが正常に動作しないのか整理できていないが、であればちょっとでもおかしかったらまず実機で確認すべきだろう。できることなら最初から実機で動作確認することをおすすめしたい。
posted by 永遠製作所 at 14:55| 東京 ☁| Comment(0) | TrackBack(0) | iPhone/iPod touch | このブログの読者になる | 更新情報をチェックする

2014年11月23日

iOS8に適用する『Sprite Kit iPhone 2Dゲームプログラミング』(その1)

前項で紹介した『Sprite Kit iPhone 2Dゲームプログラミング』はiOS7時代に書かれたもので、現時点のiOS8とは少しばかり違いがある。このiOS7とiOS8の違いに着目して実装する時の注意点をまとめたい。

SKSceneの初期化



各ゲーム場面ごとの基盤となるSKScene。このクラスのインスタンスを生成するのに-initWithSize:を使うのではなく、Interface Builderに似たXcodeのGUIツールを使って作成できるようになっている。プロジェクトテンプレートで作るとGameScene.sksというファイルが作られ、このファイルを編集することで様々な初期設定ができるようになっている。そのためView Controllerからは-initWithSize:が呼ばれない。

画面が.sksアーカイブファイルから読み込まれて表示されたときに呼ばれるのは-didMoveToView:なので、initiWithSize:で書く初期化コードはここに書くといい。もちろん、.sksファイルを使わずに従来通りalloc - initで生成するのもよい。

WWDC 2014のセッションビデオを見るとGUIツールでは画面の設定だけではなくノードの初期配置などもできるようでそこまでできれば単調なコードの羅列になる初期化処理が随分簡単にできるはずだが、GUIツールの使い方がいまいちわからない。

画面サイズ



書籍内では4inch前提で背景画像が作れらている。が、iOS8ではiPhone6, iPhone6 Plusが発売され4.7inch, 5.5inchにも対応する必要がある。ほとんどは画面サイズの中心や画面最上部など矩形を動的に取得する書き方がされているので問題ないが背景画像は調整しないとまずい。


UIImage *anImage;
anImage = [UIImage imageNamed:@"GameBack.png"];
CGSize imageSize = anImage.size;
SKSpriteNode *backNode;
backNode = [SKSpriteNode spriteNodeWithImageNamed:@"GameBack.png"];
backNode.name = BACK_NAME;
backNode.position = CGPointMake(self.size.width/2, self.size.height/2);
backNode.xScale = self.size.width / imageSize.width;
backNode.yScale = self.size.height / imageSize.height;
[self addChild:backNode];


画面全体にフィットするように拡張している。iPhone5系とiPhone6系はアスペクト比が同じだから上記でも問題ない。3.5inchのiPhone3/4にも対応するには考慮が必要。

Bombエフェクト



iOS7でのSpriteKit開発をしていないのでわからないが本の記述から見るとパーティクルのテンプレートにBombというのがあったようだ。が、iOS8(Xcode6.1)ではテンプレートのリスト中にその名前が見えない。そこでサンプルコードのファイルから.sksファイルを開いて設定を引き写してみた。

Sparkテンプレートを使ってBombファイルを作成し、インスペクターで表示の通りに各パラメータを調整すると...爆発っぽくなったであろうか?

Bomb.png

bomb_effect.png

(その2)に続く
posted by 永遠製作所 at 16:49| 東京 ☀| Comment(0) | TrackBack(0) | iPhone/iPod touch | このブログの読者になる | 更新情報をチェックする

2014年11月22日

[書籍]Sprite Kit iPhone 2Dゲームプログラミング



iPhone/iPadなどのiOSおよびMacのOS X向けに2Dゲームを開発するためのフレームワークSprite Kitの解説書。前半は概要とリファレンス、後半で3本の実用的ゲームアプリを開発。フルカラー。iOS7向け。ゲームサンプルがすごいシューティングゲーム、カーレースゲーム、キャラクターアクションゲームの3種類だが基本的な2Dゲームのほとんどがこのサンプルゲームから発展させて開発可能で、それをさして分厚くない本の一部で全部紹介できてしまう。

リファレンス部分はやや退屈かもしれないので概要だけ読んだらメソッドの説明は飛ばしていいだろう。後半のサンプルなどで登場した時点でリファレンスに戻って確認していけば十分。あとは自作アプリを作ろうというときにどういうメソッドがあるのかなどの確認に使えばいい。

iOS7がリリースされた直後に発売された本で、iOS8の今だと若干使い方が変わっている部分があってiOSの進歩が早すぎて対応できないのは紙の本の宿命で仕方ないが、この本の内容プラスさらに便利になっているだけなので無駄になる内容はほぼないと言える。iOS8のSpriteKit用の良書が出てない以上、現時点でも必読。2Dゲームを作るのにキャラクター移動や衝突判定、各種エフェクトなど自作するのはもったいない。本当にごく簡単なコードでゲーム実装できてしまうのだから、本書でSpriteKitを習得してオリジナルなゲーム内容に時間を割いたほうが格段に賢い。

後半のサンプルもサポートサイトからダウンロードできるが、できれば本に記述されたコード断片を実際に自分の手入力していってほしい。このプロジェクトは画像リソースを取り出したり、うまく動かない時の比較用に使い、1つづつ入力して段階的に実行確認していくととで各クラスの意味や使い方を習得していけると思う。ゲーム開発の定石も一緒に習得することができる。

一部間違いなどがあるのでサポートサイトの正誤表は必須。

SpriteKitでまた開発者がゲームデザインなど中身に集中していくことができるようになった。多くの独創性ゲームが登場しやすくなるに違いない。
posted by 永遠製作所 at 19:16| 東京 ☀| Comment(0) | TrackBack(0) | iPhone/iPod touch | このブログの読者になる | 更新情報をチェックする

2014年02月25日

[iOS]iPhoneのホーム画面みたないものを作りたい。

iPhoneのホーム画面のようにフルスクリーン画面を複数ページに分けて横スクロールさせる。さらにページ数をページコントロールでの表示も行って、切り替えも可能という画面の作り方。

UIScrollViewとUIPageControlを使う。都合によりiOS 6 SDK、Xcode 4.6.3を使っている。ARCは使う設定。

(0)準備

サンプルはSingle View Applicationのテンプレートで作成。プレフィックスはPGとした。
アプリケーションデリゲートクラス:PGAppDelegate
ベースとなるビューコントローラクラス:PGViewController
スクロール上に配置されるページ毎のクラス:PGPageViewController

paging_view.png

(1)UIScrollViewの配置。

Viewの上に配置すると自然と全画面サイズになってくれてビューサイズ変更に追随されるように設定されるのはInterface Builderならでは。

ポイントとしてはPaging Enabled をセットする。これでページ単位にスナップしてくれるようになる。または今回は横スクロールのみなのでShows Vertical ScrollersははずしてOK。bouncesはないほうがいいので外しているが好みなのでどちらでもいい。

page_preference.png

(2)UIPageControlの配置

UIScrollViewの上に載せるのだが、位置関係に注意しないとUIScrollViewの子になってしまう。Interface Builderでは左側の階層ビューで正しく配置する。親ビューとの関係では上方にあるビューが、実際には下になるので実行時に隠れてしまう。

ダメな例1:
page_control_x1.png

ダメな例2:
page_control_x2.png
(3)ページビューの生成

複数ページの生成をNib上で配置することができないので、viewDidLoad:の中でページ数分だけ生成してUIScrollViewのサブビューとして配置する。ViewControllerはiOS5からはchildViewControllersとして保持できるそこに追加すればいい。

実装の構造上このViewの生成時にはまだWindowには配置されていないのでサイズが確定していない。なのでここではページビューの生成だけにして位置の設定は後回しにする。

page_viewDidLoad.png
(4)ページビューの位置調整

AutoLayoutについて未だ勉強不足なので、もしかしたらもっと適切な設定方法があるのかもしれないが今回は位置調整が必要なタイミングで都度調整することに。

必要なタイミングは二カ所のはず。

初期化時:viewDidAppear:
縦横変更時:didRotateFromInterfaceOrientation:

page_adjustSubviews.png

UIScrollViewのサイズは実際にView上に表示されている範囲を示しているframeと、スクロールされる全体像の大きさを表すcontentSizeがある。

scrollview.png

page viewは0ページ目はUIScrollViewの(x,y)=(0,0)から配置するが、1ページはx座標がframeの幅1つ分ずらして配置、2ページ目はx座標がframeの幅2つ分ずらして配置する。

pageview.png

サンプルはgithubから。
posted by 永遠製作所 at 00:52| 東京 ☀| Comment(0) | TrackBack(0) | iPhone/iPod touch | このブログの読者になる | 更新情報をチェックする