ブロックチェーン・AI・システム開発の株式会社INDETAIL

COCOS2D-Xで作る音楽ゲーム 第4回(後編)

2017.02.17
Temple

cocos2dx_landscape

久しぶりのCOCOS2D-Xネタの更新です。立て続けにやりたいことが急増している中ではありますが、なんとか走り切りたいと思います。Unityやってみたいなー。

今回作るものは単純ですが、(深夜2時に)作っているとき「あー、こうするのか」とガッテンした場所も含んでいますので、やってることは薄いですが内容は濃い目でいきます。

COCOS2D-Xで作る音楽ゲーム シリーズ記事
「COCOS2D-X 導入編」第1回 第2回

「COCOS2D-X 実装編」

【注意】この記事は、第4回前編のものが手元にあることを前提に進めます。

 

Step 1 : ジャケットを動かすボタンを作る

大抵の音楽ゲームは、多数の音楽から1曲を選びますが、大規模なものでは収録曲数は100曲以上、難易度も変わると譜面の数だけで300は超えるものが多いと思います。

そうなると曲の選び方も重要になっていき、プレイしたい1曲を探すために検索をかけたり、条件を絞ったりと、ユーザーがやりやすいものになればなるほど、ソースコードは複雑になっていきます。

今回はCOCOS2D-Xの基本を学ぶという意味が強いので、「ジャケットは横並び」で「左右のボタンをタップしてジャケットを選ぶ」ものを作ります。 ソート機能は・・・またの機会に・・・。

まずは左右のボタンを設置しますが、今回はラベルで作成し、「<」と「>」をボタンとして扱います。

ここまでは前回でもよく見たものですね。ではここに「ボタンとしての機能」を加えます。

さて、いろいろ増えましたが、追加したのは「<」と「>」のいずれかをタッチすると、コメントの「ジャケットを動かす処理」のところに記載した処理が走るというものです。 そしてこの部分の中に、夜中に私がガッテンした箇所が入っています。

それこそ、getLocation関数です。

「getLocation関数」と「getLocationInView関数」

getLocation関数は、タップした位置を取得するものですが、似たようなものにgetLocationInView関数」があり、私はこれを使っていたために数時間はまりました。

この2つの関数の大きな違いは、タップした位置を返す際の起点が「画面の左下(getLocation)」か「画面の左上(getLocationInView)」かです。基本的にCOCOS2D-Xでの起点は「画面の左下」となっています。LabelやScriptなどを作ったときにsetPosition関数を使って表示する位置を指定しましたが、この起点は「画面の左下」です。

ここで、ソースコードの18行目と36行目にある条件式を見ると「markPoint(Label)のY座標から上下に30ピクセルの範囲内にtouchPoint(タップした位置)のY座標があれば真」という記述になっています。 つまり、markPointが仮にX座標が100, Y座標が100の位置にあれば、タップした位置がX座標が100, Y座標は70~130の位置にあればいいことになります。

が、もしここでtouchPointをgetLocationInViewで取得すると、起点がずれた状態でタップ位置を取得するため、明らかにLabelやSpriteをタップしているのに、タップした箇所のY座標の数値がずれ、正しく判定されません。

実際に値がどう変化するか

実際に値がどう変化するかは、15,16行目と33,34行目にあるコメントを外してログを出力し、13行目と31行目にあるgetLocationをgetLocationInViewに置き換えて「<」の位置をタップしてみてください。

getLocationでは大体「TouchPoint: 80.00, 400.00」に近い数値になると思いますが、getLocationInViewでは「TouchPoint: 80.00, 80.00」に近い数字が出ると思います。

getLocationでは画面の左下が起点なので、Yの値が起点より離れているため大きな値に、getLocationInViewでは画面の左上が起点なので、Yの値が起点より近いため小さな値になります。

さて、けっこう長くなった分、残りはさくっといきましょう。

Step 2 : ジャケットを左右に動かせるようにする

次に、Step1で作ったタップイベントの中にある「// ジャケットを動かす処理」に該当する部分の関数を作ります。「MusicSelectJacketLayer」クラスに作ります。

これもすごい単純ですね。

target_1~3は、それぞれ「ジャケット画像」「曲名」「BPM」の画像とラベルを指定しています。 が、ここで見慣れない「getChildByTag」というのが出てきました。これは「各LabelやSpriteにタグをつけ、関数間で呼び出せるようにするもの」です。init関数のほうはこんな感じで記載しています。

jacket_xxxをレイヤーに出力するaddChildの前にsetTag関数がありますね。 これが「「jacket_xxx」に「JACKET_XXX_TAG」という番号でタグをつける」という関数になります。このようにタグをつけたことで、addChildした後であっても、getChildByTagでタグをつけたときの番号で呼び出せば、追加で処理をつけられるようになります。

では、作ったmovedJacket関数を、先程のタップしたときの処理で呼び出します。

ここでも先ほど話したsetTagとgetChildByTagが出てきましたね。これで実際に「<」と「>」をタップすると、ジャケットが左右に動くと思います。

ただ、何度も同じ方向に押すと消えてしまうので、たとえば「登録している曲の先頭or末尾であったときは、右or左のボタンを押しても動かないようにする」という条件式を追加する必要がありますが、それはCOCOS2D-Xというより、ごく普通のロジックの話になってしまうので、ここでは省略します。

まとめ

今回はgetLocation, setTag, getChildByTagの3つが新しい内容として出てきました。

getLocationはgetLocationInViewと間違って使うと「タップしてるのに反応しない!エラーもでてない!ナンデ!?」ってことになるので注意したいところですね。

setTagとgetChildByTagについては、タグの番号をきちんと管理すれば、いろんな場所でいろんなものを動かすことができるので重宝していきたいですね。

次回の予告

さて次回ですが、遂に音ゲーでは避けては通れぬ場所・・・「譜面」です。 ここだけでけっこうなボリュームになり、かつ私自身、まだ実装の目途が立っていません。

そのため、第5回からは実装でき次第の更新になります。ここまで読んでくださった方々、すみませんがまたしばらくお待ちください。好きなウィスキーと音ゲーを糧にして、「譜面」の記事を書きます。

関連タグ:

Temple

職種:エンジニア 家に帰れば、cocos2d-xで何かしら作るか、オンラインゲームやるか、楽曲アレンジやるか。 外に出れば、スタバでcocos2d-xで何かしら作るか、ビール呑むか、音ゲーやるか。 そんな普通の人間です。

「いいね」ボタンを押すと、最新情報をすぐに確認できます。