cocos2dを使ったアプリ開発 | サイバーエージェント 公式エンジニアブログ
はじめまして。
サイバーエージェントでスマートフォンアプリエンジニアをしています、甲斐と申します。
私は2011年5月にサイバーエージェントに入社致しました。
入社して初めて手がけた開発がiOSアプリ「つりポン!by アメーバピグ」です。

前職では主に携帯端末のプリインアプリやミドルウェアなどの組み込み開発に携わっておりました。
その時にAndroid開発経験はありましたが、iOSアプリ開発は未経験でした。
また「つりポン!by アメーバピグ」は"cocos2d for iPhone"を採用して開発しています。
その為、iOS開発言語のObjective-C、iOS開発技術 、 cocos2d for iPhoneを習得して開発する事が初めての挑戦となりました。

cocos2dは社内でも「興味はあるけど、触る機会がなかなかない…」といった話を聞くことがあります。
確かに開発技術として採用して触らないと、なかなか覚える機会はないと思います。
そこで、今回はcocos2dを使ったアプリ開発について「つりポン!by アメーバピグ」の開発を例に簡単にご紹介したいと思います。

まずは開発したアプリと"cocos2d for iPhone"についてご紹介致します。

「つりポン!by アメーバピグ」とは
自分のピグが登場する新感覚つりゲームです。
東京湾、瀬戸内海、オホーツク海、有明海、日本海の5つのステージがあり、合計100匹を超えるさかなが登場します。各ステージにはヌシが潜んでいます。
$サイバーエージェント 公式エンジニアブログ

「cocos2d for iPhone」とは
2Dゲームを構築する為のフレームワークです。
(※以後、「cocos2d」と記載)

cocos2dの特徴
・オープンソース
  オープンソースなので無償で手に入れる事ができます。

・ゲーム開発に必要な環境が集約されている
  cocos2dにはゲーム開発に必要とされる要素が搭載されています。
  ・高度なグラフィック処理を行うOpenGL ES
  ・ゲーム表現に必要となる物理エンジン、Chipmunk、Box2D

・情報交換できるコミュニティがある
  http://www.cocos2d-iphone.org/forum/
  $サイバーエージェント 公式エンジニアブログ
  
  ※Twitterの日本語ファンアカウントもあります。
  ファンアカウント

「つりポン!by アメーバピグ」にcocos2dを導入した理由
・objecttive-Cで書かれている
cocos2dはiPhoneアプリ開発言語であるObjective-Cで書かれています。
私にとっては初めて触れる言語だったので特に感じませんでしたが、
iPhoneアプリ開発者がゲームアプリを作りたいと思った時にObjective-Cを習得していれば
すぐに取りかかれるフレームワークがあるというのは魅力的だと思います。

・Flasherがアプリ開発に取りかかりやすい
開発チームの中にはFlasherが2名いました。
cocos2dの書式がActionScriptに似ていて、Flasherがアプリ開発に取りかかりやすいのでは?という意見があり「つりポン!」で採用することになりました。

・ゲーム表現に必要な物理エンジンを搭載している
"cocos2dの特徴"でも挙げた通り、cocos2dには2つの物理エンジンが搭載されています。
iPhoneアプリに組み込める物理エンジンは何かと探すより、すでに搭載されているフレームワークがあるというので使わない手はないですね。


次に、cocos2dの基本構成と実装について触れていきます。


cocos2d基本構成
cocos2dではアプリを構成する画面を下記4つの基本要素を使って実装しています。
(※ここではcocos2dの画面構成をする上で必要となる基本要素についてあげています。アニメーションやエフェクトといった部分については触れません。)

(1)Director
cocos2dフレームワークの中心部となります。
主にシーン(画面)管理、ゲームの一時停止・再開・終了、ビューへのアクセス等重要な役割を担っています。

CCDirectorはシングルトンで、ゲーム中は常にメソッドを介してオブジェクトにアクセスすることができます。
CCDirectorにアクセスするメソッドは以下の通りです。
static CCDirector *_sharedDirector = nil;
+ (CCDirector *)sharedDirector
{
if (!_sharedDirector) {

//
// Default Director is TimerDirector
//
if( [ [CCDirector class] isEqual:[self class]] )
_sharedDirector = [[CC_DIRECTOR_DEFAULT alloc] init];
else
_sharedDirector = [[self alloc] init];
}

return _sharedDirector;
}


この他にも"shared"から始まるシングルトンクラスへのアクセスメソッドが用意されています。

(2)Scene
シーンは画面(場面・状態)を表現します。
「つりポン!」では、タイトル画面、ゲームプレイ画面、そうび画面などゲーム構成に必要な画面をそれぞれSceneで用意しています。
それをCCDirectorを介して状態を切り替えることにより画面遷移が実行される事になります。
またCCDirectorはアプリを実装する際に、最低1つのSceneを必要とします。

  $サイバーエージェント 公式エンジニアブログ


(3)Layer
LayerはScene上に配置するシートです。
画面の構成要素の1つであるSpriteを配置する土台になります。
Layer上にはLayerを配置する事も可能であり、画面タッチや加速度センサーのイベント検知も行います。

  $サイバーエージェント 公式エンジニアブログ

(4)Sprite
Spriteは画面に表示される背景画像やキャラクター、タイトル等のオブジェクトです。
Spriteは基本Layer上に配置されますが、Sprite上にSpriteを配置することも可能です。


実装
画面構成要素1つ1つの実装手順について書いていきたい所ですが、
今ではcocos2dのプログラミング本が書店に並んでいるので、そちらを見ていただければ実装について理解を深める事ができると思います。

  $サイバーエージェント 公式エンジニアブログ

「つりポン!」開発当時はこういったプログラミング本がなかった為、
cocos2d公式サイト(英語)のガイドラインを読み解いたり、ソースコードを解析しながら実装していました。

そんな中、実装に苦労した画面の1つがそうび画面です。
  $サイバーエージェント 公式エンジニアブログ

その理由は…
・画面内に表現するオブジェクトが多い
・スクロール操作での画面表現が必要
・ゲーム内パラメータによって変更が必要なオブジェクトが多い(装備アイテム、アイテム数etc…)
などが挙げられます。

この中でも赤点線で囲っているスクロール操作部分の実装部分には手こずりました。
  $サイバーエージェント 公式エンジニアブログ

cocos2dにはスクロール表現できるクラスがなく、自前で実装する必要がありました。
しかし、タッチイベントの検知、座標オフセット処理などを一から実装し、滑らかなスクロール操作を実現する難しさは試しの実装段階で痛感しました。
スクロール操作はできるものの、1スクロールでスクロール領域の端から端へ一直線という…滑らかさには遠い出来で、スクロールの滑らかさを出すにはスクロールのクッション処理や速度のチューニングなどが必要でした。

結論を言うと…一から実装する労力をかけるよりもUIKitフレームワークのUIScrollViewクラスを使う方が早い!ということで、「つりポン!」ではスクロール部分は全てUIScrollViewを使っています。

iPhone開発者ならご存知の通り、UIKitフレームワーク内にはスクロール表現可能なUIScrollViewクラスがあります。ただ、cocos2dでこのクラスを使うにあたっては1つ問題があります。
LayerにUIScrollViewはaddSubViewできないという事です。

まずはcocos2dとUIKitを融合してビュー表現できる方法を探す必要がありました。
cocos2dで画面表現に使用するLayerやSpriteといったノードは全て、CCDirectorのopenGLView上に描画されます。その為、UIKitのUIScrollViewクラスをopenGLViewにaddSudViewする事でビュー表示が可能ではないかと考えました。

・UIScrollViewクラスでスクロール実装
soubiScrollView = [[UIScrollView alloc] init];
soubiScrollView.frame = CGRectMake(92, 80, 355, 170);
soubiScrollView.backgroundColor = [UIColor clearColor];
soubiScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

soubiScrollView.pagingEnabled = NO;
soubiScrollView.contentOffset = CGPointMake(-100, 0);
soubiScrollView.contentInset = UIEdgeInsetsMake(0,0,0,100 );
[soubiScrollView flashScrollIndicators];

soubiScrollView.showsHorizontalScrollIndicator = YES;
soubiScrollView.scrollsToTop = NO;

・実装したUIScrollVieクラスをopenGLViewにaddSubView
[[[CCDirector sharedDirector] openGLView] addSubview:soubiScrollView];

UIScrollViewクラスでスクロールを実装して、openGLViewにaddSubViewしてみたところ問題なく表示できました!
今ではあたり前のように実装できる画面でも、当時は情報が少なく1つ1つに手がかかっていました。

最後に
cocos2d開発で利用すると便利なサードパーティツールがあります。
それについてはcocos2d開発支援ツールの紹介で色々紹介されているので読んでいただくと、より効率的な開発ができると思います。

また、「つりポン!」のゲームプレイ部分のアニメーション実装についてはPiggをiPhoneで動かすまでをご覧下さい。

参考文献
[1]cocos2d公式サイト
http://www.cocos2d-iphone.org/

[2]cocos2dで作る iPhone&iPadゲームプログラミング
 作者: Steffen Itterheim,畑圭輔,坂本一樹,加藤寛人,高丘知央,株式会社クイープ
 出版社/メーカー: インプレスジャパン

[3]cocos2d for iPhoneレッスンノート
 作者: 加藤寛人,佐藤伸吾
 出版社/メーカー: ラトルズ