Submit Search
Cocos2d-xハンズオン#1 in 大阪
4 likes
8,540 views
Shingo Yamano
2016年4月9日 Cocos2d-xハンズオン#1 in 大阪 ~ 簡単なゲームを作ってみよう ~
Engineering
Read more
1 of 57
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
More Related Content
PPT
Cocos2d
Kenji Kamijo
PDF
㉕cocos2dを覚えよう!初級編③
Nishida Kansuke
PDF
2012 03-03-titanium plusquicktigame2d
Hiroshi Oyamada
PPTX
Aiwolf seminar 2019_ja
Takedaatsushi
PDF
㉒初期プロジェクトを改造!
Nishida Kansuke
PDF
【TechBuzz】第9回cocos2d-x勉強会「シェーダ書いてますか?」
nyagasuki
PDF
PF部2011年12月勉強会.androidsola
android sola
PDF
Rubyコードの最適化
よしだ あつし
Cocos2d
Kenji Kamijo
㉕cocos2dを覚えよう!初級編③
Nishida Kansuke
2012 03-03-titanium plusquicktigame2d
Hiroshi Oyamada
Aiwolf seminar 2019_ja
Takedaatsushi
㉒初期プロジェクトを改造!
Nishida Kansuke
【TechBuzz】第9回cocos2d-x勉強会「シェーダ書いてますか?」
nyagasuki
PF部2011年12月勉強会.androidsola
android sola
Rubyコードの最適化
よしだ あつし
Viewers also liked
(12)
PDF
Presentation to Governor Walker (3.14.2017 final)
Brad Keithley
PPTX
IBM cognitive service introduction
Hui Wen Han
PDF
Freedom Comes from Within
Michael Mamas
PPTX
なぜなにリアルタイムレンダリング
Satoshi Kodaira
PDF
The Art of Social Media Infographic
Guy Kawasaki
PDF
13 Slack Tips and Use Cases For Sales Teams On Slack
Troops
PDF
Sage Gold Inc. Corporate Presentation
MomentumPR
PDF
データ分析を支えるクローリング環境の構築
LINE Corporation
PDF
The Data Revolution - Serena Capital
Jean-Baptiste Dumont
DOC
Coming of age
Bob Asken
PPTX
MTAM Connected Technologies Campus
Linda Daichendt
PDF
01 commonsense political thinking booklet
Gerald Furnkranz
Presentation to Governor Walker (3.14.2017 final)
Brad Keithley
IBM cognitive service introduction
Hui Wen Han
Freedom Comes from Within
Michael Mamas
なぜなにリアルタイムレンダリング
Satoshi Kodaira
The Art of Social Media Infographic
Guy Kawasaki
13 Slack Tips and Use Cases For Sales Teams On Slack
Troops
Sage Gold Inc. Corporate Presentation
MomentumPR
データ分析を支えるクローリング環境の構築
LINE Corporation
The Data Revolution - Serena Capital
Jean-Baptiste Dumont
Coming of age
Bob Asken
MTAM Connected Technologies Campus
Linda Daichendt
01 commonsense political thinking booklet
Gerald Furnkranz
Ad
Similar to Cocos2d-xハンズオン#1 in 大阪
(20)
PDF
Cocos2d xで簡単なゲームを作ってみよう!
Tomoaki Shimizu
PDF
Cocos2d-x実践講座 in 鹿児島
Tomoaki Shimizu
PDF
Cocos2d-x公開講座 in 鹿児島
Tomoaki Shimizu
PDF
cocos2d-xハンズオン勉強会 in 名古屋
Tomoaki Shimizu
PDF
Cocos2dx step2 アプリケーション基本
Chu Chu
PDF
Cocos2d-x v3.2を利用してシューティングゲームを作ろう!
Tomoaki Shimizu
PPTX
Cocos2d-x 3.0を使ったゲーム “消滅都市” の開発事例
gree_tech
KEY
Introduction for cocos2d
佐藤 俊太郎
PDF
cocos2d-xにおけるBox2Dの利用方法および便利なツール
Tomoaki Shimizu
PDF
cocos2d-x公開講座 in 鹿児島
Tomoaki Shimizu
PDF
Cocos2dを使ったi phoneゲーム開発手法
Nishida Kansuke
KEY
Cocos2d xをさわってみよう!
Tomoaki Shimizu
PDF
Cocos2d/2d-x/html5 [Objective-C/C++/JavaScript] 好みの言語はどれですか?
Toshio Ehara
PDF
Cocos2d-x勉強会 2014/10/05
Yasuhiro Matsuda
PDF
cocos2d-xとCocosBuilderでゲームを作ってみよう
Tomoaki Shimizu
PDF
㉞cocos2d-xの開発環境をインストールしてみよう
Nishida Kansuke
PDF
㊱タイルマップに挑戦
Nishida Kansuke
PDF
cocos2dxことはじめ(2.2.5)
和樹 川端
PDF
プログラム初心者がCocos2d xで ゲームを作った話
tetu_fs
PDF
cocos2d-xとCocosBuilder
Tomoaki Shimizu
Cocos2d xで簡単なゲームを作ってみよう!
Tomoaki Shimizu
Cocos2d-x実践講座 in 鹿児島
Tomoaki Shimizu
Cocos2d-x公開講座 in 鹿児島
Tomoaki Shimizu
cocos2d-xハンズオン勉強会 in 名古屋
Tomoaki Shimizu
Cocos2dx step2 アプリケーション基本
Chu Chu
Cocos2d-x v3.2を利用してシューティングゲームを作ろう!
Tomoaki Shimizu
Cocos2d-x 3.0を使ったゲーム “消滅都市” の開発事例
gree_tech
Introduction for cocos2d
佐藤 俊太郎
cocos2d-xにおけるBox2Dの利用方法および便利なツール
Tomoaki Shimizu
cocos2d-x公開講座 in 鹿児島
Tomoaki Shimizu
Cocos2dを使ったi phoneゲーム開発手法
Nishida Kansuke
Cocos2d xをさわってみよう!
Tomoaki Shimizu
Cocos2d/2d-x/html5 [Objective-C/C++/JavaScript] 好みの言語はどれですか?
Toshio Ehara
Cocos2d-x勉強会 2014/10/05
Yasuhiro Matsuda
cocos2d-xとCocosBuilderでゲームを作ってみよう
Tomoaki Shimizu
㉞cocos2d-xの開発環境をインストールしてみよう
Nishida Kansuke
㊱タイルマップに挑戦
Nishida Kansuke
cocos2dxことはじめ(2.2.5)
和樹 川端
プログラム初心者がCocos2d xで ゲームを作った話
tetu_fs
cocos2d-xとCocosBuilder
Tomoaki Shimizu
Ad
Cocos2d-xハンズオン#1 in 大阪
1.
Cocos2d-x ハンズオン#1 簡単なゲームを作ってみよう
2.
• 経歴 -株式会社コナミデジタルエンタテインメント(プログラマ) -ポノス株式会社 開発2部(エンジニア) •
担当:クライアントエンジニア • 趣味:お菓子作り、フットサル、旅行 • その他:Cocos2d-x 関西支部長() 山野 真吾
3.
やること • Cocos2d-xの簡単な使い方 • 初歩的なゲームロジック •
説明はXcodeで行う
4.
やらないこと • 画面遷移(E.g. タイトル画面
→ ゲームメイン画面) • アニメーション • マルチ解像度対応 • プログラムの効率性について • C++やSTLの説明 • Cocos2d-xの細かい仕様の説明
5.
ゲームを作ることが目的!!
6.
ライブコーディングしながら説明します
7.
今回はこれだけでゲームが完成します 1. 画像の表示 2. 画像の制御 3.
画面サイズの取得 4. タッチイベントの取り方 5. 簡単なイベント処理
8.
画像の表示手順 画像ファイルの読み込み 画像の位置設定 画像をシーンへ追加 ※ 画像を読み込んだだけでは表示されない!!
9.
画像を表示してみる // 画面サイズを取得する auto winSize
= Director::getInstance()->getWinSize(); // 画像ファイルを読み込み auto cardSprite = Sprite::create("h1.png"); // 画像の位置を設定する cardSprite->setPosition(Vec2(winSize.width * 0.5f, winSize.height * 0.5f)); // 画像をシーンに追加する addChild(cardSprite);
10.
アンカーポイントを移動させる // ファイル名を指定して画像を生成する auto cardSprite
= Sprite::create("h1.png"); // アンカーポイントを左下へ設定する cardSprite->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
11.
アンカーポイントについて 原点(0,0) アンカーポイント (デフォルトは中央) y x
12.
アンカーポイントと画像の位置 原点(0,0) setPosition(x’, y’) y’ y x x’
13.
左下にアンカーポイントを移動させる 原点(0,0) y’ y x x’ setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT)
14.
EventListenerTouchOneByOne • シングルタッチのイベントリスナー • タッチイベント •
onTouchBegan (タッチ開始時) • onTouchMoved (タッチ開始後、タッチ位置を移動した時) • onTouchEnded (タッチ正常終了時) • onTouchCancelled (タッチ異常終了時)
15.
EventListenerTouchOneByOneの使い方 イベントリスナーの生成 タッチイベントを記述 イベントリスナーを登録
16.
EventListenerTouchOneByOneの使い方 // シングルタッチのイベントリスナー生成 auto listener
= EventListenerTouchOneByOne::create(); // タッチ開始時にコールされるイベント(今回はこのイベントしか使わない) listener->onTouchBegan = [this](Touch* touch, Event* event) { /* ここにタッチ開始時の処理を書く */ return true; }; // イベントリスナーの登録 auto dispatcher = Director::getInstance()->getEventDispatcher(); dispatcher->addEventListenerWithSceneGraphPriority(listener, this);
17.
神経衰弱を作ってみる!!
18.
プロジェクトのダウンロード • 時間の都合上、プロジェクト設定の説明は省略 • XcodeとAndroid
Studio共に環境設定済み プロジェクト構成 GameManagerクラス ・神経衰弱の制御クラス Cardクラス ・カード制御クラス Resources > images ・カード画像群
19.
ゲームの初期化:カード読み込み〜配置 カード画像の読み込み カード情報を生成する カードを配置する
20.
カード読み込み、表示する • 1〜9までのハートとダイヤのカードがある • 上記以外のカードは裏面用がある
21.
カード読み込み、表示する ※ 数字カード種類数 =
MAX_CARD_NUMBER = 9 GameManager.cpp // カードをロードする関数 void GameManager::loadCards() { for (int i = 1; i <= MAX_CARD_NUMBER; i++) { // ハート柄のカードをロードする auto heart = Sprite::create(StringUtils::format("h%d.png", i)); heart->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT); addChild(heart); // ダイヤ柄のカードをロードする auto diamond = Sprite::create(StringUtils::format("d%d.png", i)); diamond->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT); addChild(diamond); } }
22.
カード読み込み、表示する 実行すると、以下の様になる
23.
カードを動的配列に入れる Spriteを動的配列に格納する場合 cocos2d::Vector<cocos2d::Sprite*> cards; ・使い方はstd::vectorとほぼ同じ GameManager.h class GameManager
: public cocos2d::Layer { /* 省略 */ private: // 動的配列を宣言する cocos2d::Vector<cocos2d::Sprite*> cards{}; };
24.
カードを動的配列に入れる GameManager.cpp void GameManager::loadCards() { for (int
i = 1; i <= MAX_CARD_NUMBER; i++) { auto heart = Sprite::create(StringUtils::format("h%d.png", i)); heart->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT); addChild(heart); // 動的配列へ追加 cards.pushBack(heart); auto diamond = Sprite::create(StringUtils::format("d%d.png", i)); diamond->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT); addChild(diamond); // 動的配列へ追加 cards.pushBack(diamond); } }
25.
Cardクラスを作る • 数字情報(1〜9) • 画像の管理(表面
and 裏面) • 現在の状態(オープン or クローズ) 必要な変数 必要な関数 • オープン or クローズ制御 • カードを表示有無を制御 • 現在の状態を取得 • カードサイズの取得 • 数字情報の取得
26.
Cardクラス ~必要な変数~ // cocos2d::Vectorで管理するために、cocos2d::Nodeを継承させる class
Card : public cocos2d::Node { /* 省略 */ private: uint8_t number{ 0 }; //カードの数字 cocos2d::Sprite* frontSprite{ nullptr }; // 表面の画像 cocos2d::Sprite* backSprite{ nullptr }; // 裏面の画像 bool bOpen{ false }; // カードの状態管理 }; Card.h
27.
Cardクラス ~実装する関数~ class Card
: public cocos2d::Node { protected: Card() = default; ~Card(); bool init(const uint8_t cardNumber, const std::string& cardFrontSpriteName, const std::string& cardBackSpriteName); public: static Card* create(const uint8_t cardNumber, const std::string& cardFrontSpriteName, const std::string& cardBackSpriteName); void open(); // カードをオープンする void close(); // カードをクローズする void visible(); // カードを表示する void invisible(); // カードを非表示する bool isOpen() const; // カードがオープン状態か判定する uint8_t getCardNumber() const; // カードの数字を取得する cocos2d::Size getCardSize() const; // カードサイズを取得する /* 省略 */ }; Card.h
28.
今回のカード制御ロジックについて 上面下面 重ねて表示する Open カード状態 Close 非表示 非表示 表示 表示 時間の都合上、 画像の削除は行わない
29.
spriteの表示設定 // カードをオープンする void Card::open() { frontSprite->setVisible(true); backSprite->setVisible(false); bOpen
= true; } Spriteの表示設定を変更する関数 sprite->setVisible(bool visible) close()、invisible()、visible()も上記を参考にして作成する Card.cpp
30.
init関数とcreate関数について init関数 create関数 • 初期化関数 • メンバー変数はこの関数内で初期値を束縛する…ことが多い •
インスタンスを生成する関数 • 関数内でinit関数をコールする コードを参照しながら説明します
31.
Cardクラスを動的配列で管理する #include “Card.h” //
カードクラスのインクルード class GameManager : public cocos2d::Layer { /* 省略 */ private: // 動的配列を宣言する(変更) cocos2d::Vector<Card*> cards{}; }; cocos2d::Nodeクラスを継承しているため、 cocos2d::Vectorで管理することが可能!! GameManager.h
32.
loadCards関数の修正 GameManager.cpp void GameManager::loadCards() { for (int
i = 1; i <= MAX_CARD_NUMBER; i++) { auto heart = Card::create(i, StringUtils::format(“h%d.png", i), “back_red.png”); heart->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT); addChild(heart); // 動的配列へ追加 cards.pushBack(heart); auto diamond = Card::create(i, StringUtils::format(“d%d.png", i), “back_red.png”); diamond->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT); addChild(diamond); // 動的配列へ追加 cards.pushBack(diamond); } } create関数をSpriteからCardに変更するだけ
33.
カードを均等に配置する • カードサイズの取得 →
sprite->getContentSize() • 画面サイズの取得 → Director::getInstance()->getWinSize() • 縦、横に並べるカード数 → 今回は3x6で並べる
34.
カードを均等に配置する 縦x横 = 2x3で考えみる
35.
カードを均等に配置する 縦方向のマージン 横方向のマージン = (画面縦幅 -
カード縦幅 * 縦方向の枚数) / (縦方向の枚数 + 1) = (画面横幅 - カード横幅 * 横方向の枚数) / (横方向の枚数 + 1)
36.
カードを均等に配置する 縦方向のマージン 横方向のマージン = (画面縦幅 -
カード縦幅 * 縦方向の枚数) / (縦方向の枚数 + 1) = (画面横幅 - カード横幅 * 横方向の枚数) / (横方向の枚数 + 1)
37.
カードを均等に配置する 横方向の枚数 = MAX_CARD_ROWS
とする 縦方向の枚数 = MAX_CARD_COLS // カードを配置する関数 void GameManager::arrangeCards() { const Size windowSize = Director::getInstance()->getWinSize(); const Size cardSize = cards.back()->getCardSize(); // カードサイズは全て同じ const Size margin((windowSize.width - cardSize.width * MAX_CARD_ROWS) / (MAX_CARD_ROWS + 1), (windowSize.height - cardSize.height * MAX_CARD_COLS) / (MAX_CARD_COLS + 1)); int row = 0; int col = 0; for (auto& card : cards) { card->setPosition((cardSize.width + margin.width) * row + margin.width, (cardSize.height + margin.height) * col + margin.height); row++; if (row % MAX_CARD_ROWS == 0) { row = 0; col++; } } } GameManager.cpp
38.
カードの配置順序 原点(0,0)
39.
カードへのタッチ判定 タッチ位置の取得 カードへのタッチ判定 カードをオープンする
40.
タッチ位置の取得:getLocation() // シングルタッチのイベントリスナー生成 auto listener
= EventListenerTouchOneByOne::create(); // タッチ開始時にコールされるイベント(今回はこのイベントしか使わない) listener->onTouchBegan = [this](Touch* touch, Event* event) { // タッチ位置の取得 auto loc = touch->getLocation() return true; }; // イベントリスナーの登録 auto dispatcher = Director::getInstance()->getEventDispatcher(); dispatcher->addEventListenerWithSceneGraphPriority(listener, this); GameManager.cpp > init関数
41.
カードへのタッチ判定方法 指定した位置がRect(カード)内に存在するか判定する関数 rect.containsPoint(const Vec2& point)
const Rectの作成方法 Rect rect(originのXY座標, rectのサイズ) カード座標 カードサイズ getPosition() sprite->getContentSize()
42.
cocos2d::Rectについて origin width height heightorigin.y+( )origin.x+width,
43.
カードへのタッチ判定 // タッチ位置がカード内に存在するか判定する bool Card::inside(const
cocos2d::Vec2& loc) const { auto position = getPosition(); auto contentSize = frontSprite->getContentSize(); Rect rect(position, contentSize); return rect.containsPoint(loc); } Card.cpp class Card : public cocos2d::Node { /* 省略 */ void invisible(); // カードを非表示する bool inside(const cocos2d::Vec2& loc) const; // カード内へのタッチか判定する /* 省略 */ }; Card.h
44.
CREATE_FUNCマクロについて • create関数を生成するマクロ • 仮引数は設定できない •
init関数は定義する必要がある 仮引数が必要なcreate関数はCardクラスのように 独自実装する必要がある
45.
ゲームの処理ロジック 1枚目のカードを開く 2枚目のカードを選択 カードのマッチング判定 ゲームのリセット カードが全てマッチングした場合 繰り返し処理
46.
ゲーム管理に必要な変数 • オープンしたカードのインデックス • 残りのカードペア数 •
現在のゲーム進行状態管理 class GameManager : public cocos2d::Layer { static constexpr int MAX_CARD_NUMBER = 9; static constexpr int MAX_CARD_ROWS = 6; static constexpr int MAX_CARD_COLS = 3; /* 省略 */ private: cocos2d::Vector<Card*> cards{}; int selectedFirstCardIndex{ 0 }; int selectedSecondCardIndex{ 0 }; int remainingNumberOfPairs{ MAX_CARD_NUMBER }; GameState gameState{ GameState::OpenFirstCard }; }; GameManager.h
47.
ゲームの進行状態管理 • 1枚目のカードをオープンする • 2枚目のカードをオープンする •
オープンしたカードをチェックする • ゲームをリセットする → enum classでゲーム状態を管理する 必要なゲーム状態 どうやってゲーム状態を管理するか
48.
ゲームの進行状態管理:enum class class GameManager
: public cocos2d::Layer { static constexpr int MAX_CARD_NUMBER = 9; static constexpr int MAX_CARD_ROWS = 6; static constexpr int MAX_CARD_COLS = 3; enum class GameState { OpenFirstCard, // 1枚目のカードを選択 OpenSecondCard, // 2枚目のカードを選択 CheckPair, // カードのマッチングを行う ResetGame, // ゲームをリセットする }; /* 省略 */ }; GameManager.h
49.
ゲーム状態毎の処理方法 switch (gameState) { //
1枚目のカードを選択 case GameState::OpenFirstCard: /* 処理 */ break; // 2枚目のカードを選択 case GameState::OpenSecondCard: /* 処理 */ break; // カードのペアチェック case GameState::CheckPair: /* 処理 */ break; // ゲームをリセットする case GameState::ResetGame: /* 処理 */ break; } GameManager.cpp > init関数 > listener->onTouchBeganのラムダ式内
50.
カード選択の処理 switch (gameState) { case
GameState::OpenFirstCard: for (int i = 0; i < cards.size(); i++) { // カードがクローズしているかつタッチポイントがカード内に存在する場合 if (!cards.at(i)->isOpen() && cards.at(i)->inside(loc)) { cards.at(i)->open(); selectedFirstCardIndex = i; gameState = GameState::OpenSecondCard; break; }; } break; /* 省略 */ } GameManager.cpp > init関数 > listener->onTouchBeganのラムダ式内 GameState::OpenSecondCardも同様にして記述する
51.
カードペアチェックの処理 switch (gameState) { /*
省略 */ case GameState::CheckPair: // ペアが成立した場合 if (cards.at(selectedFirstCardIndex)->getCardNumber() == cards.at(selectedSecondCardIndex)->getCardNumber()) { cards.at(selectedFirstCardIndex)->invisible(); cards.at(selectedSecondCardIndex)->invisible(); // 残りのペア数を減らす remainingNumberOfPairs--; } // ペアが成立しなかった場合 else { cards.at(selectedFirstCardIndex)->close(); cards.at(selectedSecondCardIndex)->close(); } /* 省略 */ } GameManager.cpp > init関数 > listener->onTouchBeganのラムダ式内
52.
カードペアチェックの処理 switch (gameState) { /*
省略 */ case GameState::CheckPair: /* 省略*/ // 残りのペアが無くなった場合、ゲームをリセットする if (remainingNumberOfPairs == 0) { gameState = GameState::ResetGame; } else { gameState = GameState::OpenFirstCard; } break; /* 省略 */ } GameManager.cpp > init関数 > listener->onTouchBeganのラムダ式内
53.
ゲームリセットの処理 switch (gameState) { /*
省略 */ case GameState::ResetGame: remainingNumberOfPairs = MAX_CARD_NUMBER; // カードの状態をリセットする for (auto& card : cards) { card->visible(); card->close(); } // カードの再配置 arrangeCards(); // 新しいゲームを開始する gameState = GameState::OpenFirstCard; break; } GameManager.cpp > init関数 > listener->onTouchBeganのラムダ式内
54.
カードをシャッフルする このままだと、いつも同じ並びでカードが配置される → カード配列自体をシャッフルして再配置する 動的配列(cards)をシャッフルする方法 std::shuffle(cards.begin(), cards.end(),
std::mt19937()) cardsのイテレータ 乱数生成器(メルセンヌ・ツイスタ) ※何度実行しても同じようにシャッフルされる → 完全ランダムにシャッフルする方法はあります!!
55.
【祝】ゲーム完成 (๑•̀ㅂ•́)✧و
56.
改良案 • カードをめくるアニメーションの追加 • BGMやSEの追加 •
スコアや制限時間を追加 • オンライン対戦できるようにする • マルチ解像度対応
57.
ゲームの解答 • https://github.com/sngymn/cocos2dx-handson1
Editor's Notes
#3:
コナミはAC機の開発で、キッズ向けや麻雀なんとか作ってた。 その前は、自称メディアアーティスト()してました。 ポノスではにゃんこ大戦争のセキュリティ強化や今からお話するガルズモンをやってました。 お菓子作りはプロラミングに通じるものがある… フットサルは部活です