Cocos2d-x-シンプルなゲームの開発

1.はじめに



この記事では、 Cocos2d-xを使用したAndroid / Linux用のプロトタイプゲームの開発に焦点を当てます。 Cocos2d-xは、2次元のゲームやその他のグラフィックアプリケーションを作成するためのクロスプラットフォームフレームワークです。 cocos2d -iphoneに基づいていますが、 Cocos2d- xはObjective-Cの代わりにC ++を使用します。 アプリケーションは、iOS、Android、Windows Phone、OS X、Windows、Linuxのプラットフォームで実行できます。

この記事はAndroid / Linux用のアプリケーションの開発に関するもので、開発プラットフォームはUbuntuです。

残念ながら、Cocos IDEはWindowとMacにのみ存在し、Linuxには期待されるバージョンはありませんが、Ubuntuが本当に好きで、これが毎日作業するプラットフォームであるため、 Clionを開発に使用しています。

この記事の一部は、ドキュメントの関連部分の翻訳です( http://www.cocos2d-x.org/wiki )。

この記事は、Cocos2d-xに精通した人を対象としています。 その中で、スプライト、シーンを使用した最も単純なアプリケーションの作成方法、および加速度計の使用方法について説明します。 これは、将来さらに進んでCocos2d-x APIを掘り下げる何らかの種類の開始かもしれません。



2.要件



必要なツールのセットを定義します。

Ubuntu 14.04-開発プラットフォーム

Cocos2d-x v3.8.1- https: //cocos2d-x.org/download

CMake 2.8+

JDK 1.6以降

Android SDK

Android NDK r9d +

Apache Ant-Androidビルドをビルドします

Python 2.7.5

Clion 1.1-www.jetbrains.com/clion



3. Cocos2d-x



Cocos2d-xは2010年に登場し、 MITライセンスの下で配布されるオープンソースプロジェクトです。 Cocos2d-xでは、C ++、Lua、Javascriptなどの言語で記述できます。 Cocos2d-xは高速でシンプルで強力です。 現在、このフレームワークを使用して記述された多くのゲームは、AppStoreとGoogle Playのトップにあります。

ZyngaWoogaGluBig Fish GamesKonamiなどの大物は 、Cocos2d-xを使用してゲームを開発しています。



ここで少し余談をしなければなりません。 実際には、Cocos2d-xを使用すると、C ++を使用してコードを記述できます。これらはすべて、AndroidおよびLinuxでビルドされます。 Cocos2d-JSを使用している場合、Javascriptで記述できます。 Linux / Ubuntu向けのアセンブリの場合、コードはC ++で翻訳され、コンパイルされます。 これにはさまざまな問題が伴います(たとえば、サードパーティのライブラリでの作業が複雑になります)。 Webの場合、java-scriptが実行されます(ところで、この場合のビルド時間はゼロです。これは悪くありません)。

Cocos2d-xを使用する場合、Webでは機能しませんが、LinuxおよびAndroidではコードは直接コンパイルされます。 もちろん、AndroidにはAndroid NDKが使用されます。





主な機能:






参照:

http://www.cocos2d-x.org/wiki/Cocos2d-x

http://www.cocos2d-x.org/wiki/About_Cocos2d-x



4.アプリケーションをインストールして起動します



記事のこの部分では、最初のアプリケーションを作成して実行する方法を示します。



始めるには、 Cocos2d-xダウンロードして解凍する必要があります 。 または、リポジトリから最新バージョンを使用できます。



git clone https://github.com/cocos2d/cocos2d-x.git
      
      





すべてが正常にダウンロードされたら、すべての依存関係をインストールする必要があります。 これを行うには、スクリプト*を実行できます。



 ~/work/cocos/cocos2d-x-3.8.1/build/install-deps-linux.sh
      
      





*以降、cocos2d-x-3.8.1は〜/ work / cocos / cocos2d-x-3.8.1ディレクトリに展開されていると想定しています。



または、手動でインストールします。

リスト
libx11-dev

libxmu-dev

libglu1-mesa-dev

libgl2ps-dev

libxi-dev

g +±4.9

libzip-dev

libpng12-dev

libcurl4-gnutls-dev

libfontconfig1-dev

libsqlite3-dev

libglew-dev

libssl-dev

glfw3





glfw3をインストールするには、別のスクリプトを実行する必要があります。



 ~/work/cocos/cocos2d-x-3.8.1$ tools/travis-scripts/install_glfw.sh
      
      







その後、インストールを実行します。



 ~/work/cocos/cocos2d-x-3.8.1$ ./setup.py
      
      







cmakeを実行して、メイクファイルを作成します。



 cd ~/work/cocos/cocos2d-x-3.8.1/build mkdir linux-build cd linux-build cmake ../..
      
      







これで、テストアプリケーションを実行できます。



 make cd bin/cpp-tests/ ./cpp-tests
      
      







それだけです すべてがうまくいけば、デモ版のようなテストアプリケーションが表示されるはずです。 すべてがうまくいけば、さらに先へ進むことができます。 プロジェクトを作成する必要があります。

アプリケーションを作成するには、次を実行します。



 cocos new MyGame -p com.your_company.mygame -l cpp -d NEW_PROJECTS_DIR
      
      





MyGameは名前、cppは言語です。 jsまたはluaを指定できます。 ただし、cppを指定します。

これでプロジェクトが作成されました。引き続き作業を続けます。 空のプロジェクトには、ラベルと画像が含まれています。 すぐにそれを見ることができます:



 cocos run -s ~/work/cocos/MyCompany/MyGame/ -p android
      
      





または



 cd ~/work/cocos/MyCompany/MyGame cocos run -p linux
      
      







実際、それは機能し始めます。



5.クライオン



すでに書いたように、Cocos IDEはUbuntu向けではありませんが、メモ帳でコードを書く気はありませんか? 幸いなことに、ジェットブレインのクリオンがいます。



画像








Clionはcmakeをサポートしています。つまり、MyGameプロジェクトを簡単にインポートでき、コードを作成できます。 書くだけでなく、デバッグしてください! 確かに、これはすべてLinuxで実行されます。 しかし、最初はこれで十分だと思います。 デバッグ後、Androidアプリケーションはいつでもコンソールから構築できます。



Clionの詳細: http : //habrahabr.ru/company/JetBrains/blog/255723/



6.基本



そこで、Cocos2d-xをダウンロードし、すべてのツールをインストールし、プロジェクトをClionにインポートし、それを起動してから...そして今、何が何であるかを理解する時です。 始めましょう。

Cocos2d-xは、クロスプラットフォームゲームエンジンです。 しかし、ゲームエンジンとは何ですか? ゲームエンジンは、すべてのゲームに必要な一般的な機能を提供します。 一緒に開発を高速化するコンポーネントが含まれています。 たとえば、レンダラー(記事の一部の用語は一般的に受け入れられているため翻訳していません。「アクティビティ」という単語も使用しません)、グラフィックス、衝突検出、物理学、サウンド、アニメーション。 Cocos2d-xは、クロスプラットフォームアプリケーションを開発するためのシンプルなAPIを提供します(または、異なるプラットフォーム用のアプリケーションを構築できます)。

Cocos2d-xは、シーン、トランジション、スプライト、メニュー、Sprite3D、オーディオなどのオブジェクトを提供します。



主なコンポーネント


最初はそのように見えないかもしれませんが、実際にはCocos2d-xの使用を開始するのは非常に簡単です。 Cocos2d-xのコアは、シーン、ノード、スプライト、およびアクションです。 彼らの何を見てみましょう。



ほとんどのゲームは次のようになります。











これらのコンポーネントはすべて次のとおりです。











監督


Cocos2d-xのディレクターは、セットのディレクターのようなものです。 彼はすべてのオブジェクトを制御し、それらに何をすべきかを伝えます。 ディレクターはシーンとトランジションエフェクトの変更を制御しますが、彼はシングルトンであり、どこでも利用できます(ただし、映画ではおそらくそうではありません)。



シーン


ほとんどの場合、ゲームにはメニュー、いくつかのレベル、さらにいくつかの画面があります(「You lost!」)。 このような画面はそれぞれシーン(シーン)です。 繰り返しますが、映画のように。 各映画はシーンに分割されます-1つのストーリーの別々の部分。 シーンはRendererオブジェクトによって描画されます。 レンダラーは、スプライトやその他のシーンオブジェクトのレンダリングを担当します。 このプロセスをよりよく理解するために、シーングラフについて話しましょう。



シーングラフ


シーングラフは、シーンで使用されるデータ構造です。 シーングラフにはノード(ノード)が含まれます。 ちなみに、シーングラフはシーングラフと呼ばれますが、実際にはツリーです。











すでに少し複雑に見えます。 感動的な人が必要な場合、Sceneが内部にどのように配置されているかを知る必要がありますか? これは、シーンのレンダリング方法を理解するために重要です。 スプライトとアニメーションをゲームに追加するときは、目的の結果が得られることを確認する必要があります。

Cocos2d-xは、対称ツリートラバーサルを実行します(左側のサブツリーが最初にアクセスされ、次にノード、次に右側のサブツリーがアクセスされます)。 これは、ツリーの右側が最後にレンダリングされることを意味し、「上から」表示されることを意味します(つまり、視覚的に残りは下にあります)。











これを説明するのは非常に簡単です。このシーンを見てみましょう。











簡略化されたもの(オブジェクトの一部はシートではなく、ブランチです)はツリーの形で表すことができます:











オーダーに関連付けられている属性はzオーダーです。 ツリーの左側は負のzオーダーで、右側は正です。 これを念頭に置いて、間違いを避けることができます。 さらに、指定されたzオーダーを使用して任意の順序で要素を追加でき、要素は自動的にソートされます。



Sceneはオブジェクトのコレクション(ノード)と考えることができます。 上記のシーンを分割して、シーングラフを表示します。











左側のシーンは、描画される順序を決定するさまざまなzオーダーとともにスタックされたノード(ノード)です。



APIを呼び出すことにより、シーンに要素を追加できます。



 //    z-order −2, //       scene->addChild(title_node, −2); //    z-order ,     — 0 scene->addChild(label_node); //    z-order 1, //       scene->addChild(sprite_node, 1);
      
      







スプライト


すべてのゲームはスプライトを使用します。 これらは、画面上を移動するものです。 それらを管理できます。 ゲームの主なキャラクターは、おそらくスプライトです。 注意することが重要です:ゲームのすべてのグラフィック要素がスプライトではありません。 アイテムが画面上を移動しない場合、それは単なるノードです。

ゲームのシーンをもう一度見てみましょう。











スプライトはゲームの重要な要素です。 スプライトの作成は非常に簡単です。



 //   auto mySprite = Sprite::create("mysprite.png"); //     mySprite->setPosition(Vec2(500, 0)); //   mySprite->setRotation(40); mySprite->setScale(2.0); //  addChild(mySprite); //    .
      
      







アクション


画面にスプライトを追加してシーンを作成することは、タスクの一部にすぎません。 結局のところ、私たちはこれをすべて移動する必要があります。 このために、アクション(アクション)があります。 移動、回転、回転-これらはすべてアクションゲームです。 アクションは、Android APIのValueAnimatorに非常に似ています。



 auto mySprite = Sprite::create("Blue_Front1.png«); //   50     10 ,   : auto moveBy = MoveBy::create(2, Vec2(50,10)); mySprite->runAction(moveBy); //    : auto moveTo = MoveTo::create(2, Vec2(50,10)); mySprite->runAction(moveTo);
      
      







座標系


Cocos2dはデカルト座標系を使用することに注意してください。 つまり、ポイント(0、0)は左下にあります。 これにより、Cocos2dは、たとえば、同じAndroid APIと区別されます。



7.ゲームのアイデア



次に、Cocos2dの動作を説明するために、ゲームのプロトタイプを作成します。 ゲームの考え方は非常に単純です。たとえば、絵文字などのオブジェクト(なぜそうではないのですか?)画面をランダムに動き回り、それらを食べる人がいます。 そして、逆に悲しい笑顔から、隠そうとします。 さらに、食べる人の制御は、異なる方向への電話の偏差によるものです。 したがって、スプライト、アクション、シーンの変更、加速度計の使用を使用します。

アイデアが非常にシンプルで退屈であることは明らかですが、100万を作るというタスクを設定していません(しかし、今のところはい?) さあ、始めましょう!



8.スプライトを追加する



基礎として、記事の冒頭で作成したMyGameアプリケーションを使用します。 インターネットで簡単に見つけることができる、または他の絵文字に置き換えることができる絵文字は、私たちにとって便利です。 いくつかのボール。

すべてのリソースはResourcesディレクトリに配置する必要があります。



次のコードをinit()メソッドに追加します。



 for (int i = 0; i < SMILES_COUNT; i++) { std::string result = «emoji-» + itos(i); Sprite *sprite = Sprite::create(result); if (sprite != NULL) { this->addChild(sprite); listSprites.push_front(sprite); } }
      
      







listSpritesはすべての笑顔のリストです。画面の周りに動きを追加すると便利です。 同時に作成し、移動の過程で少し回転するようにします。



 Point *sizeStart = randomEndPoint(); //   Point *sizeStop = randomEndPoint(); //   auto rotateAction = RotateTo::create(2, 90); //  90    . auto moveAction = MoveTo::create(2, *sizeStop); sprite->setPosition(*sizeStart); auto mySpawn = Spawn::createWithTwoActions(rotateAction, moveAction); auto seq = Sequence::create(mySpawn, CallFunc::create(callback), nullptr); sprite->runAction(seq);
      
      





ここでは、2つのアクションを同時に実行するSpawnとSequenceを作成し、さらに、Sequenceでコールバック(アクションの実行時に呼び出される関数へのリンク)を渡します。 これにより、スプライトが無限に移動するように、アクションを毎回再起動できます。 各スプライトに対してこのようなアクションを作成する必要があります。

randomEndPointメソッドは、画面の境界でランダムに選択されたポイントを返します。

今、多くの動くスプライトがあります:











また、貪食者を追加する必要がありますが、これは同様に行われ、これについては説明しません。



9.衝突解決



ここで、衝突を解決するためのコードを記述する必要があります。 つまり、小さな顔文字が貪食者に触れる瞬間を検出します。

これを行うには、onUpdateメソッドをオーバーライドします。



 void HelloWorld::update(float dt) { ... }
      
      







画面が更新されたときにこのメソッドを呼び出すには、 scheduleUpdate()を呼び出します。



 void HelloWorld::init(float dt) { this->scheduleUpdate(); ... }
      
      







これで、画面が更新されるたびに(およびスプライトの位置がそれぞれ変更されるたびに)、 updateメソッドが呼び出されます。 簡単にするために、次のように記述できます。



 void HelloWorld::init(float dt) { if(spriteSmile->getPosition().distance(eaterSprite->getPosition()) < spriteSmile->getBoundingBox().size.width/2 + eaterSprite->getBoundingBox().size.width/2){} }
      
      







衝突が見つかったら、ポイントを数えてアクションを再開できます。



 void HelloWorld::init(float dt) { if(spriteSmile->getPosition().distance(eaterSprite->getPosition()) < spriteSmile->getBoundingBox().size.width/2 + eaterSprite->getBoundingBox().size.width/2){ score—; spriteSmile->stopAllActions(); spriteSmile->setPosition(0, 0); runActionForSmile(spriteSmile); } }
      
      







10.加速度計



加速度計の操作は、衝突の解決と同じくらい簡単で、さらに簡単です。

開始するには、目的のイベントをサブスクライブします。



 void HelloWorld::init(float dt) { ... this->setAccelerometerEnabled(true); ... }
      
      







加速度計の値を取得するには、 onAccelerationメソッドを再定義します



 void HelloWorld::init(float dt) { void GameScene::onAcceleration(cocos2d::Acceleration *acc, cocos2d::Event *unused_event) { Director *director = Director::getInstance(); auto viewSize = director->getWinSize(); float minSize = MIN(viewSize.width, viewSize.height); double targetSpeedY = acc->y * minSize*2; double targetSpeedX = acc->x * minSize*2; eaterPointsPerSecY = (eaterPointsPerSecY * .8f) + (targetSpeedY * .2f); eaterPointsPerSecX = (eaterPointsPerSecX * .8f) + (targetSpeedX * .2f); } }
      
      







updateメソッドでeaterPointsPerSecXおよびeaterPointsPerSecYを計算した後、 setPosition()を呼び出します。



 float diffY = (eaterPointsPerSecY * dt)*1.3f; float diffX = (eaterPointsPerSecX * dt)*1.3f; float newY = eaterSprite->getPosition().y + diffY; float newX = eaterSprite->getPosition().x + diffX; eaterSprite->setPosition(newX, newY);
      
      







もちろん、実際のゲームでは、食べる人が画面の境界を越えないようにする必要があります。 しかし、今のところ、これについて詳しく見ていきましょう。

そこで、私たちは空飛ぶ顔文字を作成し、食べる人を追加し、加速度計の助けを借りてそれを制御しました...それでも、「ゲームオーバー!」画面を追加しました。



11.ゲームオーバー!



ここに新しいシーンが必要です。 HelloWorldをのぞいて、パターンで作成できます。 だから私たちはやる:



 // GameOverScene.h #include «cocos2d.h» class GameOverScene : public cocos2d::Layer { public: virtual bool init(); static cocos2d::Scene *createScene(); void startAgainCallback(cocos2d::Ref *pSender); CREATE_FUNC(GameOverScene); };
      
      





 // GameOverScene.cpp #include <ui/UIDeprecated.h> #include «GameOverScene.h» #include «GameScene/GameScene.h» using namespace std; using namespace cocos2d; using namespace cocos2d::ui; Scene *GameOverScene::createScene() { auto scene = Scene::create(); GameOverScene* layer = GameOverScene::create(); scene->addChild(layer); return scene; } bool GameOverScene::init() { ////////////////////////////// // 1. super init first if (!Layer::init()) { return false; } Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); auto gameOVerLabel = Label::createWithTTF("Game over!«, «fonts/Comfortaa-Bold.ttf», 24); gameOVerLabel->setTextColor(Color4B::WHITE); auto startAgainLabel = Label::createWithTTF("Play again«, «fonts/Comfortaa-Bold.ttf», 30); startAgainLabel->setTextColor(Color4B::ORANGE); auto playAgainItem = MenuItemLabel::create(startAgainLabel, CC_CALLBACK_1(GameOverScene::startAgaingCallback, this)); auto menu = Menu::create(playAgainItem, NULL); gameOVerLabel->setPosition(visibleSize.width/2, visibleSize.height/2 + gameOVerLabel->getContentSize().height * 3); menu->setPosition(visibleSize.width/2, gameOVerLabel->getPosition().y — gameOVerLabel->getContentSize().height); this->addChild(gameOVerLabel); this->addChild(menu); } void GameOverScene::startAgaingCallback(Ref *pSender) { Director::getInstance()->replaceScene( TransitionFade::create(0.5, HelloWorld::createScene(), Color3B(255, 255, 255))); } #endif //MYGAME_GAMEOVERSCENE_H
      
      





ここに書かれているほとんどすべてのものは、すでに私たちに知られています。

ここでは、HelloWorldと同様に、メニュー項目であるラベルを作成します。つまり、onClickイベントを処理できます。 MenuItemLabelを作成して、パラメーターの1つに、シーンを変更するstartAgaingCallback関数へのリンクを渡します。 TransitionFadeエフェクトを使用してシーンも変更することに注意してください。

同様に、ゲームシーンをGameOverSceneに変更できます。



 void HelloWorld::update(float dt) { if(score <= 0){ Director::getInstance()->replaceScene(TransitionFade::create(0.5, GameOverScene::createScene(score), Color3B(255,0,0))); }}
      
      







GameOver!



参照資料

www.cocos2d-x.org

www.jetbrains.com/clion

habrahabr.ru/post/126582

www.cocos2d-x.org/programmersguide

www.raywenderlich.com/33752/cocos2d-x-tutorial-for-ios-and-android-space-game



All Articles