manmanrai’s diary

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

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

背景

Pixi.jsの公式サイトにはおすすめのチュートリアル幾つか載せています。

Tutorials - PixiJS v4

最近書き終えたばっかのこのシリーズ

pixi.js カテゴリーの記事一覧 - manmanrai’s diary

はこのチュートリアルを参照したものになります。

GitHub - kittykatattack/learningPixi: A step-by-step introduction to making games and interactive media with the Pixi.js rendering engine.

もっともっと練習したいので、チュートリアル第二弾を続けやりたいと思います!

ゴール

前後二枚画像が違うスピードで動くのは目標です。
ここのスクローラーとスクロールとは違い、ただ巻いてるに見えるとのことだと思います。
アニメーションという認識でも良いかと。

材料

参考してるサイトはこちらです。

Building a Parallax Scroller with Pixi.js: Part 1

画像の素材(2枚のみ)はこちらかからダウンロードできます。

http://www.yeahbutisitflash.com/pixi-parallax-scroller/tutorial-1/resources.zip

スタート

なんか書き方少し違いますので、自分に合うように調整しながら整理します。
まず、htmlとpixi.js(CDNで)などのを用意します。

<html>
  <head>
    <meta charset="UTF-8">
    <title>Endless Runner Game Demo</title>
  </head>
  <body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.4.3/pixi.min.js"></script>
  <script>
    // あとはここを書きます。
  </script>
  </body>
</html>

ここで準備できたら、scriptの中身入ります。
pixi.jsのベースを書きます。

var Container = PIXI.Container,
    autoDetectRenderer = PIXI.autoDetectRenderer,
    loader = PIXI.loader,
    resources = PIXI.loader.resources,
    TextureCache = PIXI.utils.TextureCache,
    Sprite = PIXI.Sprite;

var renderer = autoDetectRenderer(512, 384, {antialiasing: true}),
    stage = new Container();
document.body.appendChild(renderer.view);

renderer.render(stage);

この時点出力したcanvasの画面はこうなります。(真っ黒です。)
f:id:manmanrai:20170428141432p:plain 真っ黒なcanvas以外に何にも入ってません。

そして、チュートリアル用意してくれた背景画像を読み込みましょう。

var Container = PIXI.Container,
    autoDetectRenderer = PIXI.autoDetectRenderer,
    loader = PIXI.loader,
    resources = PIXI.loader.resources,
    TextureCache = PIXI.utils.TextureCache,
    Sprite = PIXI.Sprite;

var renderer = autoDetectRenderer(512, 384, {antialiasing: true}),
    stage = new Container();
document.body.appendChild(renderer.view);

// ここから追加する
loader
    .add('images/bg-far.png')
    .load(setup);

function setup(){
  var bgFar = new Sprite(resources["images/bg-far.png"].texture);
  stage.addChild(bgFar);

  renderer.render(stage);
  // ↑これをfunction setupの中に移動する
}
// ここまで追加する

背景入れたらこうなります。
f:id:manmanrai:20170428141826p:plain 元々画像の高さ足りないので、むしろこれで十分です。

次は二枚目画像を追加すると、

// 省略

// もう一枚をloaderの中に入れる
loader
    .add(['images/bg-far.png', 'images/bg-mid.png'])
    .load(setup);

function setup(){
  var bgFar = new Sprite(resources["images/bg-far.png"].texture);
  stage.addChild(bgFar);

  // 新しい一枚を呼び出す、高さを設定する
  var bgMid = new Sprite(resources["images/bg-mid.png"].texture);
  bgMid.y = 128;
  stage.addChild(bgMid);

  renderer.render(stage);
}

結果はこうなります。
f:id:manmanrai:20170428144123p:plain

基本ループ

動かします。

// 変数を外に出した
var bgFar, bgMid;

function setup(){
  bgFar = new Sprite(resources["images/bg-far.png"].texture);
  stage.addChild(bgFar);

  bgMid = new Sprite(resources["images/bg-mid.png"].texture);
  bgMid.y = 128;
  stage.addChild(bgMid);

  // 元々ここにあるrendererをupdate functionへ移動
  requestAnimationFrame(update);
}

function update(){
  // 左へ
  bgFar.position.x -= 0.128;
  bgMid.position.x -= 0.64;

  renderer.render(stage);

  requestAnimationFrame(update);
}

f:id:manmanrai:20170428150847p:plain 開くと画像どんどん左へずらしていく、最後二枚とも画面から消えていきます。

画像パターン化(タイル化)(TilingSpriteタイリングスプライト)

この二枚の画像実はフォトショップのパターンみたいな設計になってるんです。タイルみない横に貼っても繋ぎ目がない完璧なパターン(タイル)です。
でもcssみたいにrepeat-xにしたいのは難しい、最初の画像を読み込みの時にfunctionを変えなければいけません。

ひとまず、setup function内にはこうなります。

function setup(){
  // bgFar = new Sprite(resources["images/bg-far.png"].texture);
  var bgFar = PIXI.Texture.fromImage("images/bg-far.png");

  // PIXI.extras.TilingSprite(texture, width, height);
  far = new PIXI.extras.TilingSprite(bgFar, 512, 256);

  // 貼る時の位置
  far.tilePosition.x = 0;
  far.tilePosition.y = 0;
  stage.addChild(far);

  // bgMid = new Sprite(resources["images/bg-mid.png"].texture);
  var bgMid = PIXI.Texture.fromImage("images/bg-mid.png");

  // PIXI.extras.TilingSprite(texture, width, height);
  mid = new PIXI.extras.TilingSprite(bgMid, 512, 256);

  mid.y = 128;

  // 貼る時の位置
  mid.tilePosition.x = 0;
  mid.tilePosition.y = 0;
  stage.addChild(mid);

  requestAnimationFrame(update);
}

次、移動させるupdate functionも書き換えます。

function update(){
  // far.position.x -= 0.128;
  // mid.position.x -= 0.64;

  // タイルの位置
  far.tilePosition.x -= 0.128;
  mid.tilePosition.x -= 0.64;

  renderer.render(stage);

  requestAnimationFrame(update);
}

そしたら、動き始めました!!
f:id:manmanrai:20170428171503p:plain

最後に

Class: TilingSprite

公式ドキュメントでタイリングスプライトについて検索してみました。ご参考になった幸いでございます。

第二回はこれの進化バージョンを作りたいと思います。