Pixi.js でパララックススクローラーを作ってみる【第三回】
前回の話
前回は初回で作ったもののリニューアルです。見た目や動き自体変わりがありません。
今回はチュートリアルのpart2の続きです。今まで作ってきたものをメソード化していきます。
Building a Parallax Scroller with Pixi.js: Part 2
続き
先ほどFarとMidはPIXI.extras.TilingSprite.prototypeから引き継いだので、今の全体像はこうなってます。
そしてコードの全体はこんな感じです。
var Container = PIXI.Container, autoDetectRenderer = PIXI.autoDetectRenderer, loader = PIXI.loader; var renderer = autoDetectRenderer(512, 384, {antialiasing: true}), stage = new Container(); document.body.appendChild(renderer.view); loader .add(['images/bg-far.png', 'images/bg-mid.png']) .load(setup); var far, mid; function setup(){ far = new Far(); stage.addChild(far); mid = new Mid(); stage.addChild(mid); requestAnimationFrame(update); } function update(){ far.update(); mid.update(); renderer.render(stage); requestAnimationFrame(update); } function Far(){ var texture = PIXI.Texture.fromImage("images/bg-far.png"); PIXI.extras.TilingSprite.call(this,texture, 512, 256); this.position.x = 0; this.position.y = 0; this.tilePosition.x = 0; this.tilePosition.y = 0; } Far.prototype = Object.create(PIXI.extras.TilingSprite.prototype); Far.prototype.update = function(){ this.tilePosition.x -= 0.128; }; function Mid(){ var texture = PIXI.Texture.fromImage("images/bg-mid.png"); PIXI.extras.TilingSprite.call(this,texture, 512, 256); this.position.x = 0; this.position.y = 128; this.tilePosition.x = 0; this.tilePosition.y = 0; } Mid.prototype = Object.create(PIXI.extras.TilingSprite.prototype); Mid.prototype.update = function(){ this.tilePosition.x -= 0.64; };
次はスクローラー自体をクラス化していきます。
function Scroller(stage) { }
このクラス自体には二つの問題が存在しています。まず、rendererへに繋がってないこと、二つ目は、どのプロトタイプから引き継いでないこと。
MidとFarを利用してアウトプットできるように導入します。
function Scroller(stage) { this.far = new Far(); stage.addChild(this.far); this.mid = new Mid(); stage.addChild(this.mid); }
そしてupdateもScroller functionの後に追加します。
Scroller.prototype.update = function() { this.far.update(); this.mid.update(); };
前のsetup functionをこのように書き換えられます。
midとfarに対しての操作じゃなくなるってことですね。
function setup(){ //far = new Far(); //stage.addChild(far); //mid = new Mid(); //stage.addChild(mid); scroller = new Scroller(stage); requestAnimationFrame(update); }
同じ今までmidとfarこの二つを操作してたupdate functionもこう書き換えます。
function update(){ //far.update(); //mid.update(); scroller.update(); renderer.render(stage); requestAnimationFrame(update); }
ブラウザ開くと、動作変わりがないのかもう一回確認します。問題なければ次へ進みます。
Viewport表示域
まず、ScrollerのupdateをsetViewportXに書き換えます。
function Scroller(stage) { this.far = new Far(); stage.addChild(this.far); this.mid = new Mid(); stage.addChild(this.mid); } // Scroller.prototype.update = function() { // this.far.update(); // this.mid.update(); // }; Scroller.prototype.setViewportX = function(viewportX) { this.far.setViewportX(viewportX); this.mid.setViewportX(viewportX); };
次はFarとMidのupdateも書き換えます。
function Far() { var texture = PIXI.Texture.fromImage("resources/bg-far.png"); PIXI.extras.TilingSprite.call(this, texture, 512, 256); this.position.x = 0; this.position.y = 0; this.tilePosition.x = 0; this.tilePosition.y = 0; // 追加する this.viewportX = 0; } Far.prototype = Object.create(PIXI.extras.TilingSprite.prototype); // Far.prototype.update = function() { // this.tilePosition.x -= 0.128; // }; // 追加する Far.DELTA_X = 0.128; Far.prototype.setViewportX = function(newViewportX) { var distanceTravelled = newViewportX - this.viewportX; this.viewportX = newViewportX; this.tilePosition.x -= (distanceTravelled * Far.DELTA_X); };
最後にupdate functionにも更新します。
function update() { // scroller.update(); renderer.render(stage); requestAnimationFrame(update); }
ブラウザを開くとアニメーション効果がなくなり、静止画面になってます。
そこでコンソール開きます。
scroller.setViewportX(50);
入れると、画像が少しずらしたこと分かります。
scroller.setViewportX(7000);
setViewportXをScrollerに任せる
先までx軸の値はMidとかFarで初期設定しましたが、今度からはscrollerで操作するように変えていきます。
function Scroller(stage) { this.far = new Far(); stage.addChild(this.far); this.mid = new Mid(); stage.addChild(this.mid); // 追加する this.viewportX = 0; }
Scrollerのupdateにも
Scroller.prototype.setViewportX = function(viewportX) { // 追加する this.viewportX = viewportX; this.far.setViewportX(viewportX); this.mid.setViewportX(viewportX); };
そして、Scrollerのprototypeもう一個追加します。
Scroller.prototype.getViewportX = function() { return this.viewportX; };
次はupdate function内部で
function update(){ // 追加する var newViewportX = scroller.getViewportX() + 5; scroller.setViewportX(newViewportX); // 追加する renderer.render(stage); requestAnimationFrame(update); }
ブラウザ開くと結構早めなスピードで動いています。
最後にさっき追加したものをprototypeとしてScrollerの下に付けます。
Scroller.prototype.moveViewportXBy = function(units) { var newViewportX = this.viewportX + units; this.setViewportX(newViewportX); };
そして、updateにそう書き換えます。
function update() { // var newViewportX = scroller.getViewportX() + 5; // scroller.setViewportX(newViewportX); scroller.moveViewportXBy(5); renderer.render(stage); requestAnimationFrame(update); }
コード全体的に簡潔ように見えてきました。
part2意外に長かったのです、読むだけでも結構時間かかりました。
次はpart3向かって進みたいと思います。
ではまた次回で。