WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

【Cocos2d-x】3Dっぽい画面・エフェクトを作ろう!

こんにちは、デザイナーの上松です。 2Dゲーム隆盛の昨今ですが、そんな2Dゲームの中でも平面的な3D空間を表現したいことって多いと思います。 CCCameraを使って3D的表現も可能ですが、設定が難しく、デフォルトのCocosBuilderやSpriteBuilderでは扱えないなど問題も多々あります。 そのため、弊社を含め多くの会社で2D的なトリックを使って3D表現をしている事例が多いようです。 この記事では画像が3D的に配置されているように見せたり、空間的奥行きを表現する方法を紹介したいと思います。

ちなみに下記は弊社スラッシュオブザドラグーンで私が担当したモンスター詳細画面ですが、 2D的操作のみを使い、立体的に見える魔方陣を作成しています。

Detail2

多重スクロール方法(XY軸カメラ移動)

まずは、古くからある由緒正しき疑似3D技法です。 現在でも、ゲームやアニメではもちろん、リアルな映像制作でも遠景によく使われる方法です。 縦横へのカメラ移動やオブジェクトの移動を表現できます。

下記画像のように、遠景と近景、遠景と中景と近景、それぞれ別の速度で縦や横へスクロールすることで立体的に見せることが可能です。

Scroll

ゲームの背景などで使用する場合は、CCParallaxNodeを使用すると便利です。 デモ用アニメーションで使用したい場合は、単純にキーフレームで調整した方が便利で確実かと思います。 上記GIFは後者の方法で作成しました。

timeline_scroll

カメラの動きに合わせて、移動量の異なるPositionキーフレームを設定しています(プログラムの場合、CCMoveToを使用します)

非常に遠くにある物体は奥行きが圧縮され、一枚の板として描画しても不自然にならないことを利用したテクニックです。 上記動画のように、距離感に沿って、setColorで色合いを変更するのも効果的です

【注意点】 逆に近景に使うと、いかにも「多重スクロール」なルックスになります。 リアルなルックスを求めるゲームでは、距離感に注意が必要です。

多重スケール方法(ドリーイン・ドリーバック)

スクロール方法では、縦横へのアニメーションは対応できますが、 奥行きのあるアニメーションには適しません。 この方法では、奥行き方向への移動を表現できます。

スケールの速度をずらして拡大・縮小することで、奥行き方向のアニメーションを作ることができます。 カメラ操作としては「ドリーイン」「ドリーバック」が行なえます。(*間違えられやすいですが、ズームとは異なります)

Scale

タイムラインはこのような感じになりました。

timeline_scale

【注意点】 スケールをするときの注意ですが、 すべてのレイヤーのスケールの原点を必ず統一してください。 また、カメラ位置に近づくとただスケールしていることがバレてしまいます。 そのため、遠くの背景オブジェクトに使用すると効果的です。近づきすぎたオブジェクトは不透明度を下げて隠してしまいましょう。

基本変形で立体的な配置を表現する

この方法では、立体的に見えるよう画像を変形し配置することで、3D空間上にあるように見せることができます。 平面内で収まるアニメーションであれば効果的に3D的な動きを表現できます。

魔方陣を例にとると、 平面的に回転する魔方陣や発光エフェクトを用意し、CCNodeの子にします。 親CCNodeをスケールで潰すことで、板が回転したように見せることができます。 冒頭にあった、モンスター詳細画面のエフェクトはこの方法で作成されています。

Basic

【注意点】 これはあくまでも平行投影であり透視投影とは異なります。あちこちに要素が配置されると破綻してしまいます。 また、スケールで潰したノードを動かしたりするのはとても難しいので注意が必要です。

おまけ: CCCameraで3D的配置をする

CCCameraはそのノードをどこから見ているかを指定することができるため、本当に立体的に配置することができます。 また、ノード単位で使用できるため、CCNodeParallax的な使い方もできるかと思います。

wars

EyeXYZは視点、CenterXYZは注視点、UpXYZはカメラの上方向の向きです。 カメラ自体の移動はEyeXYZで行い、CenterXYZで向きを決める形で配置します。

また、CCCameraを設定したノードの移動は、カメラを左右にずらすのと同じ効果があります。これを利用して下記画面を作成してみました。 正直なところCCCameraの設定は直感的には分かりにくいので、グラフィカルなツールに統合すると良いのではと思います。 (弊社ではCocosBuilderプラグインを作成し、視覚的に作業できるようになりました)

なお、3D空間にはニアークリップとファークリップ(描画される最小の距離と最大の距離)があり、それを超えると描画されなくなってしまいます。 遠くまで描画する必要がある場合は、CCDirector::setProjection内の下記部分を修正してください。

CCDirector.cpp 415行付近

kmMat4PerspectiveProjection( &matrixPerspective, 60, (GLfloat)size.width/size.height, 0.1f, zeye*2);  

kmMat4PerspectiveProjection( 書き戻しされる行列, 画角, 画面のアスペクト比, ニアクリップ, ファークリップ) となっています。 このファークリップ(zeye*2)の部分を、ゲーム内で使用する最も遠い座標値に指定することで、クリッピングを回避することができます。

それでは、Cocos2d-xで素敵なゲーム開発を!