HelloWorldのシーンの分析
以前使用cocos2d-xの3.14時間、HelloWorldのシーンは、HelloWorld ::をcreateScene()がとても長い場合、クラスが、クラス層ではありません
Scene* HelloWorld::createScene()
{
auto scene = Scene::create();
auto layer = HelloWorld::create();
scene->addChild(layer);
return scene;
}
そして今、3.17のHelloWorld ::をcreateScene()限り
Scene* HelloWorld::createScene()
{
return HelloWorld::create();
}
HelloWorldの差は、シーン、シーン自体は、次いで、さらなるHelloWorldの子ノードとして追加シナリオを生成しません
HelloWorldのレイアウト
HelloWorldのココスシーンは、HelloWorldの閉じた単語を、ボタンのロゴを持っていた、これらの小さなオブジェクトが生成されます()HelloWorldのである::のinit
基本クラスを初期化します
私たちは、HelloWorldのシーンに物事を追加する前に、あなたはvisibleSizeとスペアの原点を、基本クラスの初期化関数Sceneクラスを呼び出し、それを取得する必要があります
bool HelloWorld::init()
{
if ( !Scene::init() )
{
return false;
}
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
.................
}
[閉じる]ボタンを生成
bool HelloWorld::init()
{
.................
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
float x = origin.x + visibleSize.width - closeItem->getContentSize().width/2;
float y = origin.y + closeItem->getContentSize().height/2;
closeItem->setPosition(Vec2(x,y));
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
.................
}
ここでは、コードが複雑に見える場合も、それは我々がココス内のオブジェクトの多くを見つけることができる、真ではありません生成時に、この静的ファクトリメソッドを使用して作成され、HelloWorldのこのシーンも例外ではありません、ゲームオブジェクトを作成するに埋めるために必要なパラメータを生成します。構築されたオブジェクトへのポインタを返します
MenuItemImage作成
MenuItemImageのデフォルトの状態で渡されたメソッド作成画面の[閉じる]ボタンを、閉じるボタンは、状態ピクチャをクリックし、コールバックを、コールバックは、このイベントへの応答を行うために押下されるボタンのための手続きを指し、CC_CALLBACK_1の使用してマクロを追加ボイド関数ポインタメンバ関数(T :: *)(参考文献* ) を入力し、オブジェクトのメンバ関数を呼び出すためのポインタコールバックからなるが、それは問題ではありません理解していない、我々は書くことのように輝いている
、それはxとyの値を計算することです、つまり、ボタンの右下隅の座標であるgetContentSize()オブジェクトのサイズを取得し、使用するsetPositionを設定ボタンを座標
メニューの作成
なお、ボタンは直接、シーンにあるメニューボタン、に頼る必要は追加されていないメニューオブジェクトを、私たちは含ま作成closeItemのメニューを、座標(0,0)を設定し、最終的に使用するためにはaddChildをメニューに追加しますシーンに
フォントの世代
bool HelloWorld::init()
{
.................
auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
label->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + visibleSize.height - label->getContentSize().height));
this->addChild(label, 1);
.................
}
また、これはよく理解され、createWithTTFは、ラベルオブジェクトへのポインタを返す文字列が表示され、フォントおよびフォントサイズをパラメータとして、また使用はaddChildする層10の高い比、我々はしようとしたテキストシーンに追加しましたシーンの中心に提供した座標
bool HelloWorld::init()
{
.................
auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
label->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + visibleSize.height/2));
this->addChild(label, 1);
.................
}
上記ロゴのテキストは、高い証拠層は、より後で、最初のレンダリングは、以下のオブジェクトをレンダリングした後に押されるレンダリング
生成ウィザード
bool HelloWorld::init()
{
.................
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));
this->addChild(sprite, 0);
return true;
.................
}
これはさらに簡単です、画像を生成するためのウィザードを使用し、それはまたシーンに追加され、最終的にtrueを返すことを覚えて、init関数がtrueを返さない場合、プログラムは外に崩壊します
深さ探査HelloWorldのシーン
私はいつも、思考のいくつかのデザインパターンがあり、特性はC ++、初心者プログラマの総合的な成長のための大きな助けをオブジェクト指向の多くの機能を使用cocos2dx、Cの++を学習cocos2dxは非常に良い教育であると思いました
ゲームが始まる場所
まず、入り口がrunWithSceneゲームシーンディレクタークラス、開いているAppDelegate.cpp、見つけるAppDelegate :: applicationDidFinishLaunching()関数で、我々はコードを見ることができます
bool AppDelegate::applicationDidFinishLaunching() {
auto director = Director::getInstance();
..............
auto scene = HelloWorld::createScene();
director->runWithScene(scene);
return true;
}
ディレクタークラスはシングルトンクラスであり、それはのgetInstanceインスタンスを使用して得ることができ、シングルトンは、静的な機能を達成するために、コンストラクタの民営化、オブジェクトへのアクセスを通じて実際に、通常我々は、これらを使用するために遅延ロードを使用シングルトンの種類、ディレクターはシングルトン使用していること、引き離す
runWithScene実行HelloWorldのシーンでディレクターをし、子ノードとのHelloWorld HelloWorldの仕事をしましょう
Node类
Nodeクラスは、実際のシーンクラスでもノードで、ゲーム世界のオブジェクトの十分な理解は、実際にはほとんどのノード、ノードとノードの親子関係を介してリンクされている、我々が使用するシーンHelloWorldクラスのほとんどの基本クラスです、ゲームのモデルオブジェクトがツリーで、自分自身のサブノードのキューを管理するために追加されたにaddChild親ノードの子ノードを使用し、ゲームが実行されている場合、ディレクターは、例えば、HelloWorldのシーンのために、これらのノードは、それらが動作せトラバースしますHelloWorldのシーンがルートノードでは、ウィザードのスプライト、テキストラベル、メニュー、メニューのHelloWorldは、子ノードで、ボタンcloseItemは、メニューのメニューの子ノードであります
参考クラス
参考クラスがためである参照カウントオブジェクトの参照カウントを担当するクラス、REFクラスは、すべてがなぜあるメモリ管理システムメモリ管理をカウントノードcocos2dxの参照を、使用していることを意味し、基本クラスのNodeクラスであり、オブジェクトは、新しいによって生成され、削除しますが、その理由で生成されたオブジェクトを作成されていません。ここに関連GCの知識。簡単に言えば、参照カウント法理論は、オブジェクトが参照されたときに、オブジェクトの参照カウントが1になるということです、彼はカウントがあるとき、-1間接参照0オブジェクトが破壊される時に見つけることができます興味スマートポインタとRAII
作ります
この機能は、我々はそれが工場、記事の冒頭で行われる最初の仕事は、このようなコードに達する前に、我々は、オブジェクトを生成するために必要な工場であると言うことができます
Scene* HelloWorld::createScene()
{
return HelloWorld::create();
}
そして、これはHelloWorldScene.hです
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class HelloWorld : public cocos2d::Scene
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
void menuCloseCallback(cocos2d::Ref* pSender);
CREATE_FUNC(HelloWorld);
};
#endif
ああ、不思議、関数を作成見えない理由、それは基底クラスでありますか?あのああ、静的メンバ関数は継承されませんので、問題が表示されますCREATE_FUNCをそうです、上!私たちは見てCREATE_FUNCを定義し
#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
__TYPE__ *pRet = new(std::nothrow) __TYPE__(); \
if (pRet && pRet->init()) \
{ \
pRet->autorelease(); \
return pRet; \
} \
else \
{ \
delete pRet; \
pRet = nullptr; \
return nullptr; \
} \
}
見ることができ、CREATE_FUNCは手動で機能マクロ作成、書き込みする必要はありませんあなたが怠惰なことを可能にするものです
もちろんが、いくつかのクラスは、カスタム例えば、スプライト作成、作成が必要な
Sprite* Sprite::create()
{
Sprite *sprite = new (std::nothrow) Sprite();
if (sprite && sprite->init())
{
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE(sprite);
return nullptr;
}
どのような操作で作成しますか?
1.新世代のオブジェクトを使用して
オブジェクトを初期化する2.使用のinitを
メモリ管理システムのカウントを参照するには、このクラスの自動解放3.文献を
一方、我々はINITに実装されているもののHelloWorldシーンのレイアウトを考えることはないのinitを参照してくださいINIT、それはそれは、テキスト、ボタン、スプライト作成およびシーンに追加呼び出すことによって作成された他のオブジェクトを持っているときのHelloWorldを作成して行う、と言うことであり、これらのオブジェクトも、それは、シーンの時に作成されると言うことです作成によって作成されすべてのオブジェクトは、私たちが試合の流れをより深く理解していないcocos2dxに、init呼び出し
自動解放メソッドのRefクラス、その定義を見て
Ref* Ref::autorelease()
{
PoolManager::getInstance()->getCurrentPool()->addObject(this);
return this;
}
getInstanceはPoolManagerはシングルトンクラスで説明した、見た、このコードの意味が明確で、refは、メモリ管理の現在のプールに追加
、私たちはしばしば限り、我々は上記を満たすために作成するように、その後の開発でカスタマイズ作成する必要があります3つの関数が可能
概要
このセクションでは、我々はのためのHelloWorldコード来るcocos2dx新しいプロジェクトを研究することによって多くのことを学ん小さなデザインパターンの知識、GC、ゲームデザインのアイデアのオブジェクト構造だけでなく、C ++、それに怠惰なマクロの多様性を、マクロ保護はそれをコンパイル重複を避けるために、
ああ?どのようなマクロ保護?
マクロの保護
ここに、ここでコンパイルされるから.hファイルを使用しないように、少しの知識マクロを保護に関するマクロ保護を話をする方法HelloWorldScene.h Aケーススタディ
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
............
#endif
#これは、シンボルコードプリプロセッサの始まりで、プログラムの前にコンパイラは、このシンボルは__HELLOWORLD_SCENE_H__定義__HELLOWORLD_SCENE_H__を定義されていない場合は、数行のコードが意味する前処理作業を、実行し、ENDIFまでの内容をコンパイルします。 __HELLOWORLD_SCENE_H__が一度定義されたときに、次の時間がプリプロセッサは、このプリコマンドに遭遇した彼は、その後、コンパイラのターゲットとして、次のコードをしない場合には、当然のことながら、今一度コマンド対の#pragmaがあり、ファイルが唯一であることを確認一度コンパイルし、我々はまた、私たちの目的を達成することができます