manmanrai’s diary

新米フロントエンジニアの勉強記録ブログ

【新】Pixi.js でパララックススクローラーを作ってみる【第三回】

プロローグ

前回はFarとMidを独立させて、update functionも各自持たせるように変えました。
次はScroller functionを作って、FarとMidを配下に入れて、コントロール権をScrollerに持たせます。

Part2(続き)

Ch03 動作メソッド化

Scrollerに任せる

function init(){
  // レンダラーのサイズを指定する、コンテナ(枠)を作る
  var renderer = PIXI.autoDetectRenderer(512, 384, {view:document.getElementById("game-canvas")}),
      stage = new PIXI.Container();

  // // 画像を呼び出す(Far function使用)
  // far = new Far();
  // stage.addChild(far);

  // // 画像を呼び出す(Mid function使用)
  // mid = new Mid();
  // stage.addChild(mid);

  // 画像をまとめて呼び出す
  scroller = new Scroller(stage);

  requestAnimationFrame(update);


  // update functionの中身
  function update(){

    // 組み合わせたタイルを左へずらす
    scroller.update();
    // far.update();
    // mid.update();

   // コンテナの内容をレンダラーに伝える(setup functionから持ってくる)
    renderer.render(stage);

    // 描画処理を繰り返しupdate functionを実行する
    requestAnimationFrame(update);
  }
}


// Far画像を独立させる
function Far() {

  // 画像を読み込む、textureという名で
  var texture = PIXI.Texture.fromImage("images/bg-far.png");

  // タイル貼る範囲を指定する
  PIXI.extras.TilingSprite.call(this, texture, 512, 256);

  // 位置を指定(全てのデフォルトは0)
  this.x = 0;
  this.y = 0;
  this.tilePosition.x = 0;
  this.tilePosition.y = 0;
}
Far.prototype = Object.create(PIXI.extras.TilingSprite.prototype);
// update function追加
Far.prototype.update = function() {
  this.tilePosition.x -= 0.128;
};

// Mid画像を独立させる
function Mid() {

  // 画像を読み込む、textureという名で
  var texture = PIXI.Texture.fromImage("images/bg-mid.png");

  // タイル貼る範囲を指定する
  PIXI.extras.TilingSprite.call(this, texture, 512, 256);

  // 位置を指定(全てのデフォルトは0)
  this.x = 0;
  this.y = 128;
  this.tilePosition.x = 0;
  this.tilePosition.y = 0;
}
Mid.prototype = Object.create(PIXI.extras.TilingSprite.prototype);
// update function追加
Mid.prototype.update = function() {
  this.tilePosition.x -= 0.64;
};


// farとmid二枚画像をまとめる
function Scroller(stage){
  this.far = new Far();
  stage.addChild(this.far);

  this.mid = new Mid();
  stage.addChild(this.mid);
}
// updateもまとめる
Scroller.prototype.update = function(){
  this.far.update();
  this.mid.update();
}

window.onload = init;

FarとMidのupdate functionをScrollerへ移行

function init(){
  // レンダラーのサイズを指定する、コンテナ(枠)を作る
  var renderer = PIXI.autoDetectRenderer(512, 384, {view:document.getElementById("game-canvas")}),
      stage = new PIXI.Container();

  // 画像をまとめて呼び出す
  scroller = new Scroller(stage);

  requestAnimationFrame(update);


  // update functionの中身
  function update(){

    // 組み合わせたタイルを左へずらす

    // 一旦動きなくす(scroller.update functionなくした)
    // scroller.update();


   // コンテナの内容をレンダラーに伝える(setup functionから持ってくる)
    renderer.render(stage);

    // 描画処理を繰り返しupdate functionを実行する
    requestAnimationFrame(update);
  }
}


// Far画像を独立させる
function Far() {

  // 画像を読み込む、textureという名で
  var texture = PIXI.Texture.fromImage("images/bg-far.png");

  // タイル貼る範囲を指定する
  PIXI.extras.TilingSprite.call(this, texture, 512, 256);

  // 位置を指定(全てのデフォルトは0)
  this.x = 0;
  this.y = 0;
  this.tilePosition.x = 0;
  this.tilePosition.y = 0;

  // 初期化
  this.viewportX = 0;
}
Far.prototype = Object.create(PIXI.extras.TilingSprite.prototype);
// update function破棄
// // update function追加
// Far.prototype.update = function() {
//   this.tilePosition.x -= 0.128;
// };

// setViewportX function追加
// DELTA_Xは等差の差
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);
};

// Mid画像を独立させる
function Mid() {

  // 画像を読み込む、textureという名で
  var texture = PIXI.Texture.fromImage("images/bg-mid.png");

  // タイル貼る範囲を指定する
  PIXI.extras.TilingSprite.call(this, texture, 512, 256);

  // 位置を指定(全てのデフォルトは0)
  this.x = 0;
  this.y = 128;
  this.tilePosition.x = 0;
  this.tilePosition.y = 0;

  // 初期化
  this.viewportX = 0;
}
Mid.prototype = Object.create(PIXI.extras.TilingSprite.prototype);
// update function破棄
// // update function追加
// Mid.prototype.update = function() {
//   this.tilePosition.x -= 0.64;
// };

// setViewportX function追加
// DELTA_Xは等差の差
Mid.DELTA_X = 0.64;
Mid.prototype.setViewportX = function(newViewportX) {

  // 移動距離
  var distanceTravelled = newViewportX - this.viewportX;

  // 今の位置を
  this.viewportX = newViewportX;
  this.tilePosition.x -= (distanceTravelled * Mid.DELTA_X);
};

// farとmid二枚画像をまとめる
function Scroller(stage){
  this.far = new Far();
  stage.addChild(this.far);

  this.mid = new Mid();
  stage.addChild(this.mid);
}
// update function破棄
// // updateもまとめる
// Scroller.prototype.update = function(){
//   this.far.update();
//   this.mid.update();
// }

// Scrollerで各自のsetViewportXをまとめる
Scroller.prototype.setViewportX = function(viewportX) {
  this.far.setViewportX(viewportX);
  this.mid.setViewportX(viewportX);
};


window.onload = init;

X軸の移動距離をFarとMid各自の変数(viewportX)として設定する

function init(){
  // レンダラーのサイズを指定する、コンテナ(枠)を作る
  var renderer = PIXI.autoDetectRenderer(512, 384, {view:document.getElementById("game-canvas")}),
      stage = new PIXI.Container();

  // 画像をまとめて呼び出す
  scroller = new Scroller(stage);

  requestAnimationFrame(update);


  // update functionの中身
  function update(){

    // 組み合わせたタイルを左へずらす
    // 現在のViewportXを5単位足す
    var newViewportX = scroller.getViewportX() + 5;

    // 新ViewportXをsetViewportXに渡す
    scroller.setViewportX(newViewportX);

   // コンテナの内容をレンダラーに伝える(setup functionから持ってくる)
    renderer.render(stage);

    // 描画処理を繰り返しupdate functionを実行する
    requestAnimationFrame(update);
  }
}


// Far画像を独立させる
function Far() {

  // 画像を読み込む、textureという名で
  var texture = PIXI.Texture.fromImage("images/bg-far.png");

  // タイル貼る範囲を指定する
  PIXI.extras.TilingSprite.call(this, texture, 512, 256);

  // 位置を指定(全てのデフォルトは0)
  this.x = 0;
  this.y = 0;
  this.tilePosition.x = 0;
  this.tilePosition.y = 0;

  // 初期化
  this.viewportX = 0;
}
Far.prototype = Object.create(PIXI.extras.TilingSprite.prototype);

// setViewportX function追加
// DELTA_Xは等差の差
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);
};

// Mid画像を独立させる
function Mid() {

  // 画像を読み込む、textureという名で
  var texture = PIXI.Texture.fromImage("images/bg-mid.png");

  // タイル貼る範囲を指定する
  PIXI.extras.TilingSprite.call(this, texture, 512, 256);

  // 位置を指定(全てのデフォルトは0)
  this.x = 0;
  this.y = 128;
  this.tilePosition.x = 0;
  this.tilePosition.y = 0;

  // 初期化
  this.viewportX = 0;
}
Mid.prototype = Object.create(PIXI.extras.TilingSprite.prototype);

// setViewportX function追加
// DELTA_Xは等差の差
Mid.DELTA_X = 0.64;
Mid.prototype.setViewportX = function(newViewportX) {

  // 移動距離
  var distanceTravelled = newViewportX - this.viewportX;

  // 今の位置を
  this.viewportX = newViewportX;
  this.tilePosition.x -= (distanceTravelled * Mid.DELTA_X);
};


// farとmid二枚画像をまとめる
function Scroller(stage){
  this.far = new Far();
  stage.addChild(this.far);

  this.mid = new Mid();
  stage.addChild(this.mid);

  // 初期化
  this.viewportX = 0;
}
// Scrollerで各自のsetViewportXをまとめる
Scroller.prototype.setViewportX = function(viewportX) {

  // updateできるように変更
  this.viewportX = viewportX;

  this.far.setViewportX(viewportX);
  this.mid.setViewportX(viewportX);
};
// getViewportX functionを追加する
Scroller.prototype.getViewportX = function() {
  return this.viewportX;
};


window.onload = init;

ScrollerにmoveViewportXBy function追加する

X軸の移動距離をFarとMid各自の変数(viewportX)は1単位(1 unit)として使います。このfunctionで何単位でパラメーターとして受けます。
要はスピードのコントロールです。

function init(){
  // レンダラーのサイズを指定する、コンテナ(枠)を作る
  var renderer = PIXI.autoDetectRenderer(512, 384, {view:document.getElementById("game-canvas")}),
      stage = new PIXI.Container();

  // 画像をまとめて呼び出す
  scroller = new Scroller(stage);

  requestAnimationFrame(update);


  // update functionの中身
  function update(){

    // 組み合わせたタイルを左へずらす
    // メソッド化
    scroller.moveViewportXBy(5);

    // // 現在のViewportXを5単位足す
    // var newViewportX = scroller.getViewportX() + 5;
    // // 新ViewportXをsetViewportXに渡す
    // scroller.setViewportX(newViewportX);

   // コンテナの内容をレンダラーに伝える(setup functionから持ってくる)
    renderer.render(stage);

    // 描画処理を繰り返しupdate functionを実行する
    requestAnimationFrame(update);
  }
}


// Far画像を独立させる
function Far() {

  // 画像を読み込む、textureという名で
  var texture = PIXI.Texture.fromImage("images/bg-far.png");

  // タイル貼る範囲を指定する
  PIXI.extras.TilingSprite.call(this, texture, 512, 256);

  // 位置を指定(全てのデフォルトは0)
  this.x = 0;
  this.y = 0;
  this.tilePosition.x = 0;
  this.tilePosition.y = 0;

  // 初期化
  this.viewportX = 0;
}
Far.prototype = Object.create(PIXI.extras.TilingSprite.prototype);

// setViewportX function追加
// DELTA_Xは等差の差
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);
};

// Mid画像を独立させる
function Mid() {

  // 画像を読み込む、textureという名で
  var texture = PIXI.Texture.fromImage("images/bg-mid.png");

  // タイル貼る範囲を指定する
  PIXI.extras.TilingSprite.call(this, texture, 512, 256);

  // 位置を指定(全てのデフォルトは0)
  this.x = 0;
  this.y = 128;
  this.tilePosition.x = 0;
  this.tilePosition.y = 0;

  // 初期化
  this.viewportX = 0;
}
Mid.prototype = Object.create(PIXI.extras.TilingSprite.prototype);

// setViewportX function追加
// DELTA_Xは等差の差
Mid.DELTA_X = 0.64;
Mid.prototype.setViewportX = function(newViewportX) {

  // 移動距離
  var distanceTravelled = newViewportX - this.viewportX;

  // 今の位置を
  this.viewportX = newViewportX;
  this.tilePosition.x -= (distanceTravelled * Mid.DELTA_X);
};


// farとmid二枚画像をまとめる
function Scroller(stage){
  this.far = new Far();
  stage.addChild(this.far);

  this.mid = new Mid();
  stage.addChild(this.mid);

  // 初期化
  this.viewportX = 0;
}
// Scrollerで各自のsetViewportXをまとめる
Scroller.prototype.setViewportX = function(viewportX) {

  // updateできるように変更
  this.viewportX = viewportX;

  this.far.setViewportX(viewportX);
  this.mid.setViewportX(viewportX);
};
// getViewportX functionを追加する
Scroller.prototype.getViewportX = function() {
  return this.viewportX;
};
// moveViewportXBy functionを追加する
Scroller.prototype.moveViewportXBy = function(units) {
  var newViewportX = this.viewportX + units;
  this.setViewportX(newViewportX);
};


window.onload = init;

init functionの役割をMain functionへ、update functionをMain functionの配下に

// init functionをMain functionへ改名(=中身を引っ張ってくる)
function Main(){
  // 内部変数を「this.」を追加

  // レンダラーのサイズを指定する、コンテナ(枠)を作る
  this.renderer = PIXI.autoDetectRenderer(512, 384, {view:document.getElementById("game-canvas")});
  this.stage = new PIXI.Container();

  // 画像をまとめて呼び出す
  this.scroller = new Scroller(this.stage);

  requestAnimationFrame(this.update.bind(this));
}
// update functionをMain function専属に変える
Main.prototype.update = function() {
  this.scroller.moveViewportXBy(Main.SCROLL_SPEED);
  this.renderer.render(this.stage);
  requestAnimationFrame(this.update.bind(this));
};
Main.SCROLL_SPEED = 5;


// update functionの中身
// function update(){

//   // 組み合わせたタイルを左へずらす
//   // メソッド化
//   scroller.moveViewportXBy(5);

//  // コンテナの内容をレンダラーに伝える(setup functionから持ってくる)
//   renderer.render(stage);

//   // 描画処理を繰り返しupdate functionを実行する
//   requestAnimationFrame(update);
// }



// Far画像を独立させる
function Far() {

  // 画像を読み込む、textureという名で
  var texture = PIXI.Texture.fromImage("images/bg-far.png");

  // タイル貼る範囲を指定する
  PIXI.extras.TilingSprite.call(this, texture, 512, 256);

  // 位置を指定(全てのデフォルトは0)
  this.x = 0;
  this.y = 0;
  this.tilePosition.x = 0;
  this.tilePosition.y = 0;

  // 初期化
  this.viewportX = 0;
}
Far.prototype = Object.create(PIXI.extras.TilingSprite.prototype);

// setViewportX function追加
// DELTA_Xは等差の差
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);
};

// Mid画像を独立させる
function Mid() {

  // 画像を読み込む、textureという名で
  var texture = PIXI.Texture.fromImage("images/bg-mid.png");

  // タイル貼る範囲を指定する
  PIXI.extras.TilingSprite.call(this, texture, 512, 256);

  // 位置を指定(全てのデフォルトは0)
  this.x = 0;
  this.y = 128;
  this.tilePosition.x = 0;
  this.tilePosition.y = 0;

  // 初期化
  this.viewportX = 0;
}
Mid.prototype = Object.create(PIXI.extras.TilingSprite.prototype);

// setViewportX function追加
// DELTA_Xは等差の差
Mid.DELTA_X = 0.64;
Mid.prototype.setViewportX = function(newViewportX) {

  // 移動距離
  var distanceTravelled = newViewportX - this.viewportX;

  // 今の位置を
  this.viewportX = newViewportX;
  this.tilePosition.x -= (distanceTravelled * Mid.DELTA_X);
};


// farとmid二枚画像をまとめる
function Scroller(stage){
  this.far = new Far();
  stage.addChild(this.far);

  this.mid = new Mid();
  stage.addChild(this.mid);

  // 初期化
  this.viewportX = 0;
}
// Scrollerで各自のsetViewportXをまとめる
Scroller.prototype.setViewportX = function(viewportX) {

  // updateできるように変更
  this.viewportX = viewportX;

  this.far.setViewportX(viewportX);
  this.mid.setViewportX(viewportX);
};
// getViewportX functionを追加する
Scroller.prototype.getViewportX = function() {
  return this.viewportX;
};
// moveViewportXBy functionを追加する
Scroller.prototype.moveViewportXBy = function(units) {
  var newViewportX = this.viewportX + units;
  this.setViewportX(newViewportX);
};

// 新しいinit functionを作る
function init() {
  // Mainを呼び出す
  main = new Main();
}
window.onload = init;

エピローグ

実は最初にこのチュートリアルを勉強した時、なかなか最後のステップ(init functionの役割をMain functionへ、update functionをMain functionの配下に)に辿り着けなかったです。
今ちゃんと整理したので、そこまで理解難しくないですが、最初に本当に諦めようなかと何回も考えました。
やっとここまで来ました。次回は三枚目の画像の部分です。

では、また次回。