サイトのトップへ戻る

Cocos2d-x ドキュメント 日本語訳

サイト内検索

Cocos2d-x の基本概念

この章では、あなたが既にCocos2d-xを使い始め、念願のゲーム開発の準備ができていることを想定しています。 心配しないでください、これは楽しいものになります!

それでは始めましょう!

Cocos2d-x はクロスプラットフォームのゲームエンジンです。 ゲームエンジンとは、全てのゲームに必要な共通機能を提供するソフトウェアのことです。 API やフレームワークという言葉を聞いたことがあるかもしれませんが、このガイドではCocos2d-x のことを「ゲームエンジン」と呼ぶことにします。

ゲームエンジンには、使用することで開発速度をスピードアップでき、自家製エンジンよりもパフォーマンスが良くなる多くのコンポーネントが含まれています。 通常ゲームエンジンは、レンダラー・2D/3Dグラフィックス・衝突検出・物理エンジン・音声・コントローラーサポート・アニメーションなどのコンポーネントの一部もしくは全てによって構成されています。 ゲームエンジンは通常マルチプラットフォームをサポートしているので、ゲームを開発してそれを複数のプラットフォームに提供する作業が手間を一切をかけずに簡単に行えます。

Cocos2d-x はゲームエンジンなので、クロスプラットフォームの携帯およびデスクトップゲームを開発するための簡略化されたAPIが実装されています。 By encapsulating the power inside an easy to use API, you can focus on developing your games and worry less about the implementation of the technical underpinnings. あなたの好みに応じて、Cocos2d-x に大量の仕事をさせたりわずかな仕事をさせたりできます。

Cocos2d-x では、 Scene, Transition, Sprite, Menu, Sprite3D, Audio オブジェクト、その多くの機能が用意されています。 ゲーム制作に必要なものが全て含まれています。



メインコンポーネント

最初は圧倒されるかもしれませんが、Cocos2d-xでの開発は簡単です。 詳細を見る前に、Cocos2d-xで使用されている概念をいくつか理解する必要があります。 Cocos2d-x で要となるのは、 Scene, Node, Sprite, MenuAction といったオブジェクトです。 あなたの好きなどのゲームでも、これらのコンポーネントを全て何らかの形でみることができるでしょう!

それでは実際に見てみましょう。以下の画面はあなたがこれまでにプレイしたことのある非常に有名なゲームに少し似ているかもしれません。:

下の画像も見てください、スクリーンショットを区切って、画面を構成しているコンポーネントを識別しています。:

menu, いくつかのsprites 、 labelsが表示されており、これらの機能は全てCocos2d-xに実装されています。 ゲーム設計ドキュメントのいくつかを見てください。あなたのゲームで使用しているコンポーネントが何なのかを分かります。 おそらく上記のものを同じコンポーネントのはずです。



Director

Cocos2d-x では、ちょうど映画のように Directorという概念を使用しています! Directorは処理の流れを制御し、処理を行うべき受信者に何をするのか指示を出します。 あなた自身のことはエグゼクティブプロデューサーとして考えてください。 あなたは Directorに対して何をするのか指示を出します! Director の一般的な仕事の一つは、 Scene の切り替えと遷移を行うことです。 Directorは、コード上のどこからでも呼び出すことができる共有シングルトン (事実上、一度に一つしか存在できないクラスインスタンス) オブジェクトです。

以下に、代表的なゲームの流れの例があります。あなたが決めたゲームの流れに従って、DirectorScene遷移の制御を行います。:

あなたのゲームのディレクターはあなたです。何がいつどのように起きるかはあなたが決めます。頑張ってください!



Scene

あなたのゲームでは、おそらくメインメニュー、いくつかのステージ、エンディングシーンを実装したいでしょう。 これら全てを、どのようにして個別のパーツにより分ければ良いのでしょうか? ご推察どおり、それが Sceneです。 あなたのお気に入りに映画で考えると、映画は複数のシーンや個別のストーリーラインに分けることができます。 これと同じ思考プロセスをゲームに適用した場合、どんなにシンプルなゲームでも少なくとも数シーンは必要ということが分かります。

先ほどの画像をもう一度見てみましょう:

これはメインメニューで、一つの Sceneになります。 このシーンはいくつかのパーツによって構成されており、それらパーツ全てが組み合わさることによって我々の目の前にスタート画面が表示されています。 Sceneは rendererによって描写されます。 renderer はスプライトとその他オブジェクトを画面に描写する処理を司ります。 もう少し理解しやすくするために、scene graphについて少し説明する必要があります。



Scene Graph

scene graph とは、sceneを視覚的に配置するためのデータ構造です。 scene graph はツリー構造(はい、これはscene graphのことですが、実際はツリーとして表されます )の中にNode オブジェクトを含んでいます 。

これは複雑なように感じるかもしれません。 あなたに代わってCocos2d-xが大抵の処理を行うのに、なぜこの技術の詳細を理解する必要があるのか疑問に思っているかもしれません。 レンダラーによってSceneがどのように描写されるのかを理解することは本当に重要なのです。

ゲームにノードやスプライトやアニメーションを追加したら、それが想定どおりに描写されているかを確認したいことでしょう。 But what if you are not? 仮にspriteが背景画像の後ろに隠れてしまい、spriteを最前面に表示したとしたらどうでしょうか? 大したことありません。少し振り返り scene graph を紙に書き出して精査すれば、きっと簡単に間違いを見つけることができるでしょう。

Scene Graph はツリー構造なので; あなたは ツリーをたどることができます。 Cocos2d-x では 中間順 アルゴリズムを使用しています。 中間順では巡回したツリーの左側へ行き、ルートノードまで行き、それからツリーの右側へ行きます。 ツリーの右側は最後に描写されるので、scene graphではそれが最前面に表示されます。

scene graphは簡単に動かして見ることができるので、分解したゲームシーンを見てみましょう:

Would be rendered as a tree, simplified to the following:

Another point to think about is elements with a negative z-order are on the left side of the tree, while elements with a positive z-order are on the right side. Keep this in consideration when ordering your elements! Of course, you can add elements in any order, and they're automatically sorted based upon a customizable z-order.

Building on this concept, we can think of a Scene as a collection of Node objects. Let's break the scene above down to see the scene graph uses the z-order to layout the Scene:

The Scene on the left is actually made up of multiple Node objects that are given a different z-order to make them "stack" on top of each other.

Cocos2d-xでは、API 呼び出しaddChild() を使ってscene graphを構築します:

C++
// Adds a child with the z-order of -2, that means
// it goes to the "left" side of the tree (because it is negative)
scene->addChild(title_node, -2);

// When you don't specify the z-order, it will use 0
scene->addChild(label_node);

// Adds a child with the z-order of 1, that means
// it goes to the "right" side of the tree (because it is positive)
scene->addChild(sprite_node, 1);
Javascript
// Adds a child with the z-order of -2, that means
// it goes to the "left" side of the tree (because it is negative)
scene.addChild(title_node, -2);

// When you don't specify the z-order, it will use 0
scene.addChild(label_node);

// Adds a child with the z-order of 1, that means
// it goes to the "right" side of the tree (because it is positive)
scene.addChild(sprite_node, 1);


Sprites

全てのゲームでは Sprite オブジェクトが使われており、あなたはそれが何なのかを知っているかもしれませんし、知らないかもしれません。 スプライトとは、画面上を動き回るブジェクトです。 あなたはそれらを操作することができます。 あなたが作成するゲームにおいて、メインキャラクターにはおそらくスプライトを使うことになるでしょう。 あなたは、全てのグラフィカルなオブジェクトはSpriteではないのか?と考えているかもしれません。 それは違います! なぜかって? あなたがオブジェクトを画面上で動かす場合のみ、それはスプライトということになります。 あなたがオブジェクトを動かさないのであれば、それは単なる Nodeです。

前回の画像をもう一度見て、どれがSpriteでどれが Nodeかを指し示してみましょう:

Spriteは全てのゲームにおいて重要です。 プラットフォーム・ゲームを作成する際に、あなたはおそらく何らかの画像を使用して作成されたメインキャラクターを用意するでしょう。 このメインキャラクターは Spriteです。

Sprites は簡単に作成でき、 position, rotation, scale, opacity, color などのような設定可能なプロパティを持っています。

C++
// This is how to create a sprite
auto mySprite = Sprite::create("mysprite.png");

// this is how to change the properties of the sprite
mySprite->setPosition(Vec2(500, 0));

mySprite->setRotation(40);

mySprite->setScale(2.0); // sets both the scale of the X and Y axis uniformly

mySprite->setAnchorPoint(Vec2(0, 0));
Javascript
// This is how to create a sprite
var mySprite = new cc.Sprite(res.mySprite_png);

// this is how to change the properties of the sprite
mySprite.setPosition(cc._p(500, 0));

mySprite.setRotation(40);

mySprite.setScale(2.0); // sets both the scale of the X and Y axis uniformly

mySprite.setAnchorPoint(cc._p(0, 0));

それでは、各プロパティについて説明しましょう。この章で使っているサンプルコードから出来上がった、以下のスクリーンショットで考えてみましょう。:

mySprite->setPosition(Vec2(500, 0));を使って位置を設定すると以下のようになります:

Sprite の位置が元の位置から新たに設定した位置に変わっていることに注意してください。

mySprite->setRotation(40);を使って新たに回転度を設定した場合、以下のようになります:

... 新たに設定した値分 Sprite が回転していることが分かります。

mySprite->setScale(2.0);を使って新たにscaleを設定した場合、以下のようになります:

ここでも、修正したコードに応じて Sprite が変化していることが分かります。

最後に、全ての Node オブジェクトは (SpriteNodeのサブクラスなので) anchor pointの値を持っています。 anchor pointについてはまだ説明していなかったので、いい機会です。 anchor point とは、spriteの位置を設定する時に基礎座標として使用される部分を設定するものだと考えることができます。

サンプルのゲームではキャラクター画像を使用し、以下のコードでanchor point を0, 0 に設定しています:

C++
mySprite->setAnchorPoint(Vec2(0, 0));
Javascript
mySprite.setAnchorPoint(cc._p(0, 0));

そうすると、スプライトの左下隅がsetPosition()で設定する基準位置として使用されます。 それでは、実際に実行してこれらのいくつかを見てみましょう:

各画像の赤点を見てください。この赤点が anchor point の位置を表します!

anchor pointNodesの位置を決める際にとても役立つということが分かったでしょう。 ゲーム内での効果をシミュレートするために、 anchor point を動的に変更することもできます。

Spriteはあらゆる部分を微調整することが可能です。 But, what if we wanted to have these same types of changes occur in an automated, time determined manner? Well, keep reading...



Actions

画面上で Sceneを作成して Sprite オブジェクトを追加することは、必要な作業の一部にしか過ぎません。 ゲームがゲームであるためには、モノを動き回らせることが必要です! Action オブジェクトは全てのゲームにおいて不可欠なものです。 Actions を使うことで時間経過ごとに Node オブジェクトを変化させることができます。 Spriteをある Point から別の場所へ移動させ、移動が完了した時にコールバックを使いたくありませんか? 問題ありません! Node上で実行するActionの連鎖を作成することさえ可能です。 アクションではposition、 rotation 、scaleのようなNode のプロパティが変更可能です。 Actionの例には MoveByRotateScaleがあります。全てのゲームは Actionsを使用しています。

この章のために用意したサンプルコードを見てみると、 ここでの Actions は以下のように動作します:

そして5秒後、 sprite は新たな位置に移動します:

Action オブジェクトは簡単に作成できます:

C++
auto mySprite = Sprite::create("Blue_Front1.png");

// Move a sprite 50 pixels to the right, and 10 pixels to the top over 2 seconds.
auto moveBy = MoveBy::create(2, Vec2(50,10));
mySprite->runAction(moveBy);

// Move a sprite to a specific location over 2 seconds.
auto moveTo = MoveTo::create(2, Vec2(50,10));
mySprite->runAction(moveTo);
Javascript
var mySprite = new cc.Sprite(res.mySprite_png);

// Move a sprite 50 pixels to the right, and 10 pixels to the top over 2 seconds.
var moveBy = new cc.MoveBy(2, cc._p(50,10));
mySprite.runAction(moveBy);

// Move a sprite to a specific location over 2 seconds.
var moveTo = new cc.MoveTo(2, cc._p(50,10));
mySprite.runAction(moveTo);


Sequences と Spawns

Sprite オブジェクトを画面上で動かすことができたので、ゲーム制作に必要なことを全て揃ったということでしょうか? いいえ、違います。 複数のActionsを実行することについてはどうでしょう? はい、Cocos2d-x では複数のActionの制御もいくつかの方法で行うことができます。

その名の通り、Sequenceとは指定した順序で実行される複数の Action オブジェクトのことです。 Sequence を逆の順序で実行したい? 問題ありません。 Cocos2d-x では手間をかけずにこれを制御することができます。

Spriteが徐々に移動する Sequence例の流れを見てみましょう:

このSequence は簡単に作成できます:

C++
auto mySprite = Node::create();

// move to point 50,10 over 2 seconds
auto moveTo1 = MoveTo::create(2, Vec2(50,10));

// move from current position by 100,10 over 2 seconds
auto moveBy1 = MoveBy::create(2, Vec2(100,10));

// move to point 150,10 over 2 seconds
auto moveTo2 = MoveTo::create(2, Vec2(150,10));

// create a delay
auto delay = DelayTime::create(1);

mySprite->runAction(Sequence::create(moveTo1, delay, moveBy1, delay.clone(),
moveTo2, nullptr));
Javascript
var mySprite = new cc.Node();

// move to point 50,10 over 2 seconds
var moveTo1 = new cc.MoveTo(2, cc._p(50,10));

// move from current position by 100,10 over 2 seconds
var moveBy1 = new cc.MoveBy(2, cc._p(100,10));

// move to point 150,10 over 2 seconds
var moveTo2 = new cc.MoveTo(2, cc._p(150,10));

// create a delay
var delay = new cc.DelayTime(1);

mySprite.runAction(Sequence.create(moveTo1, delay, moveBy1, delay.clone(),
moveTo2));

この例では Sequenceを順番通りに実行していますが、設定した全てのActionsの同時実行についてはどうでしょうか? Cocos2d-x では同時実行もサポートしており、これは Spawnと呼ばれています。 Spawnは設定された全ての Action オブジェクトを受け取り、それらを同時に実行します。 Some might be longer than others, so they won't all finish at the same time if this is the case.

C++
auto myNode = Node::create();

auto moveTo1 = MoveTo::create(2, Vec2(50,10));
auto moveBy1 = MoveBy::create(2, Vec2(100,10));
auto moveTo2 = MoveTo::create(2, Vec2(150,10));

myNode->runAction(Spawn::create(moveTo1, moveBy1, moveTo2, nullptr));
Javascript
var myNode = new cc.Node();

var moveTo1 = new cc.MoveTo(2, cc._p(50,10));
var moveBy1 = new cc.MoveBy(2, cc._p(100,10));
var moveTo2 = new cc.MoveTo(2, cc._p(150,10));

myNode.runAction(Spawn.create(moveTo1, moveBy1, moveTo2));

なぜSpawn actionsを使うのでしょう? 理由はあるのでしょうか? もちろんです! What if your main character has multiple Actions when obtaining a power up? Maybe beating the boss at the end of a level has multiple Actions that need to happen to end the level.



親子関係

Cocos2d-x では 親子 関係を使用しています。 これは、親ノードのプロパティや変更はその子へも適用されるということを意味します。 単体のSprite と子を持つ Sprite について考えてみましょう:

子を持っていると、親の回転度を変更すると全ての子の回転度も変更されます:

C++
auto myNode = Node::create();

// rotating by setting
myNode->setRotation(50);
Javascript
var myNode = new cc.Node();

// rotating by setting
myNode.setRotation(50);

回転度と同じ様に、親の scale を変更すると子のscaleも変更されます。:

C++
auto myNode = Node::create();

// scaling by setting
myNode->setScale(2.0); // scales uniformly by 2.0
Javascript
var myNode = new cc.Node();

// scaling by setting
myNode.setScale(2.0); // scales uniformly by 2.0

への全ての変更がへ伝わるわけではありません。 anchor pointを変更しても親のtransform 操作(scale, position, rotate, skew, など...)にのみ影響を与えるだけで、子の位置には影響しません。 実際には、子は常に親の 左下隅 (0,0)に追加されます。



ログ機能を使ってメッセージを出力する

時には、アプリを実行している時に情報取得やデバッグのためにコンソールにメッセージを出力したいことがあるかもしれません。 そうした機能がこのエンジンには組み込まれており、 log()を使用します。例:

C++
// a simple string
log("This would be outputted to the console");

// a string and a variable
string s = "My variable";
log("string is %s", s);

// a double and a variable
double dd = 42;
log("double is %f", dd);

// an integer and a variable
int i = 6;
log("integer is %d", i);

// a float and a variable
float f = 2.0f;
log("float is %f", f);

// a bool and a variable
bool b = true;
if (b == true)
    log("bool is true");
else
    log("bool is false");

そしてご想像通りと思いますが、望むのであればlog()の代わりに std::coutを使うことも可能です。 しかし、log() の方が複雑な出力をより簡単に書式化することができます。

Javascript
// a simple string
cc.log("This would be outputted to the console");

// outputting more than a simple string
var pos = cc._p(sender.x, sender.y);
cc.log("Position x: " + pos.x + ' y:' + pos.y);


まとめ

Cocos2d-x の概念について多くのことを見てきました。ここで深呼吸をしましょう。心配しないでください。 あなたのアイディアを一歩一歩ゆっくりと形にしていけば良いのです。 一般的に、Cocos2d-x と プログラミングについての技術は一晩で学べるようなスキルではありません。 これには何度も練習して理解することが必要です。フォーラムもあなたの疑問の助けになるということを忘れないでください。