簡単アニメーション!Pixi.jsを触ってみる!
〜(5)インタラクションに挑戦!(ボタン編)〜
こんばんは!。今日は春分の日です。
もう春ですね! と元気よくいきたいところですが。。。
。。。外は凄い風。すっきりしない天気。お決まりのように寒い!
せっかくの休日ですが、外に出る気にならないのでPixi.jsの続きでもやりたいと思います。
Pixi.jsはJavascriptで簡単にアニメーションが作れるライブラリです。
Pixi.jsのサンプルやドキュメントとにらめっこしながら、少しずつ勉強を進めています。
前回までで、なんとか文字や画像を動かせるようになりましたので、今回は ユーザー操作への反応 に挑戦してみたいと思います。
ボタンをつくってみる
インタラクションといえば、最初はボタン(押しボタン)ですね。(そうなのか?w)
さっそく、簡単なのを作ってみます。
(5時間経過)
。。。ぬぅをぅ!。。。ようやくできました。。。
前回までに作ったサンプルにボタン足しただけなんですが。。
簡単なコードでもバグ出るとハマるんですよね。。。
というわけで、昼間に書き始めたはずが、もうすっかり夜です。
つくりかた
おおまかに下記のような流れになります。
- ボタン画像を用意する(サンプルではスプライトシートを作りました)
- ボタン用のスプライトを1つだけ作る
- スプライトにボタン用の設定を行う
- ボタンを押したときに対応するアクションを作る
それでは、順番に見ていきましょう。
ボタン画像をつくる
せっかくスプライトシートを覚えたので、使いたいですね!
というわけで、めっちゃ手抜きのボタンを作ってみました。
今回は、「触ってないとき」「マウスが乗ってるとき」「クリックしたとき」
の3通りを作りました。
スマートフォン向けに作る場合は「マウスが乗った」が判定できないので2通りでもいいかもしれません。
また、クリックをアナログな感じで表現したい場合などは、もっと枚数増えるかもしれません。
jsonは↓こんな感じです。
{"frames":{
"button_normal.png":
{
"frame": {"x":0,"y":0,"w":240,"h":80},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":240,"h":80},
"sourceSize": {"w":240,"h":80}
},
"button_hover.png":
{
"frame": {"x":0,"y":80,"w":240,"h":80},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":240,"h":80},
"sourceSize": {"w":240,"h":80}
},
"button_clicked.png":
{
"frame": {"x":0,"y":160,"w":240,"h":80},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":240,"h":80},
"sourceSize": {"w":240,"h":80}
}
},
"meta": {
"image": "button.png",
"format": "RGBA8888",
"size": {"w":240,"h":240},
"scale": "1"
}
}
ボタン用のスプライトを作る
今回は、1つのボタンだけ配置します。
1つのボタンの動作は、1つのスプライトを用意して、複数(今回は3コ)のテクスチャをマウスイベントに応じて貼り替えることで実現します。
それでは、ボタン用のスプライトを作ってみましょう。
loader2 = new PIXI.AssetLoader(["img/button.json"]);
loader2.onComplete = onButtonLoaded; // 読み込みは非同期で行われます
loader2.load(); // ロード開始!
まず、PIXI.AssetLoader()
を使ってスプライトシートのローダーを作ります。
コールバック関数にonButtonLoaded()
を指定して、ロード開始します。
ここまでは、第3回に出て来た流れと同じです。
次に、onButtonLoaded()
を見てみましょう。
// ボタンの読み込み
var button;
var texNomal;
var texHover;
var texClicked;
function onButtonLoaded(){
button = PIXI.Sprite.fromFrame("button_normal.png");
button.position.x = width / 2;
button.position.y = height / 2;
button.anchor.x = 0.5;
button.anchor.y = 0.5;
texNomal = PIXI.Texture.fromFrame("button_normal.png");
texHover = PIXI.Texture.fromFrame("button_hover.png");
texClicked = PIXI.Texture.fromFrame("button_clicked.png");
:
ここでスプライトを生成して、座標を設定します。
次に差し替え用のテクスチャを3つ生成しています。
スプライトをボタン用に設定する
onButtonLoaded()
の続きです。
// カスタムプロパティ
button.isOver = false; // true: マウスが乗ってる false: 乗ってない
// ボタン状態初期化
button.buttonMode = true;
button.setInteractive(true);
ここで、見慣れないコードがいくつか出てきます。
前半のコードは、スプライトのオブジェクトに独自にプロパティを追加しています。
button.isOver
は、マウスがボタンに乗っているか、乗ってないかを判断できるようにするためのものです。
button.buttonMode
にtrue
を設定することで、カーソルが「手のひらカーソル」に変わります。
これは必須ではありませんが、見た目が変わってボタンを認識しやすくなるので、設定した方が良いと思います。
次のbutton.setInteractive(true)
がとても重要で、これを設定しないと、スプライトを「ボタン」にしてくれません。
マウスイベントを有効にするために必ず設定してください。
ボタンを押したときに対応するアクションを作る
残りは、マウスイベントの処理です。
-
button.mouseover
はボタンにマウスを重ねたときに発行されるイベント -
button.mouseover
はボタンからマウスが離れたときに発行されるイベント -
button.click
はボタンをクリックしたときに発行されるイベント -
button.tap
はボタンを押したときに発行されるイベント
となります。
このイベントハンドラの中に、対応する処理を書いていきます。
アクションといっても、ハンドラに書くのはキッカケだけ。実際の「動き」の部分はアニメーション処理の方で書きます。
// mouseover / mouseout
button.mouseover = function(data){
this.isOver = true;
this.setTexture(texHover);
}
button.mouseout = function(data){
this.isOver = false;
this.setTexture(texNomal);
}
// click / tap
button.click = function(data){
this.setTexture(texClicked);
//
// ここでアクションを書こう!
//
}
button.tap = function(data){
this.setTexture(texClicked);
}
stage.addChild(button);
// 次のアニメーションフレームでanimate()を呼び出してもらう
requestAnimFrame(animate);
}
ボタンなので「押したときのアクション」はbutton.click
に書くことになると思いますが、そうしなければいけないわけではありません。
いろいろ意表を突いたUIを考えても面白いと思います。
最後にステージへボタンのスプライトを登録してから
requestAnimFrame(animate)
を呼び出して、onButtonLoaded()
はおわりです。
アクションの続きはアニメーション処理の中で
もちろん、ボタンを押した後のアニメーションの動きはrequestAnimFrame()
から呼び出されるコールバックで作っていくことになります。
サンプルでは今回も手抜きをして、ボタン押されたら速回しをする!
という単純明快に書いてみましたが、これはあまり参考にならないと思うので、アクションそのものの解説は省略します。
次回もインタラクションつづきます
すいません。時間切れです。冒頭で doodleを語った関係 で、そろそろUpせざるを得ませんw
今回、ボタンになぜか時間がかかりすぎて、目標のところまで書けませんでした。くそー。
というわけで次回もインタラクションの続きになってしまいました。詳細は寝ながら考えますw
それでは次回もよろしくお願いします!