【MV講座】コードをまとめる

前回分で、とりあえず目的の一つは達成できました。
ですが、なーんかコードが何をしているのかいま一つわかりにくい
そこでコードを意味のある塊にまとめちゃいましょう!
「意味のある塊単位でコードを作っていく」ということを僕は結構やっていますが、コードの書き方の流派は色々あるみたいなので、自分が「最も読みやすい」と思うものを選択していけばよいです。
ここでは「意味のある塊単位でコードを作っていく」ことにしましょう。

とりあえず全部消す

えー。
前回までに色々と書いてもらいましたが、「var pluginName = ‘TidyTilingTitleTie’;」より下(つまりこの一行は残す)から「})();」まで(この魔法のような記号は残す)全部消してくださいw

その後、まず名前空間を作成します。
名前空間というのは、簡単にいえば、他のプラグインと競合しにくくするための工夫の一つです。
まあこれ使わなくてもいいとか、即時関数を使えだとか、いや使わなくてもいいだとか、なんやらかんやらあるみたいですが、僕は単純に「区分がわかりやすい」から使っています
この辺の小難しいベストプラクティスについてはJavaScriptの先生たちにお任せしましょう。
というわけで、以下のコードをコピペしてください。

////=============================================================================
//// NTMO
//// Declare NTMO namespace.
////=============================================================================
var NTMO = NTMO || {};
NTMO.TTTT = function(){
};

NTMOというのは、ニート(N)TMO(ツミオ)の略です。よろしくお願いします。
TTTTというのは、プラグイン名の頭文字(TidyTilingTitleTie)を取ったものです。
深い意味はありません。適当です。

スクロール用の背景を描くためのクラスを作る

名前空間を宣言したところで、スクロール用の背景を描くためのクラスを作りましょう。
「これはクラスじゃない」という話もあるようですが、別の言い方を知らないのでここではクラスに統一します(ツクールのヘルプも「クラス」という呼び方で統一されています)。
ただ、確かにJavaScriptにはちゃんと「クラス」という機能が別にあるので、これをクラスと呼ぶのウーン? という気も素人ながらにします。
ま、そんな用語のアレコレもJavaScriptの先生方に任せておいて、僕はさっさと解説に進みます。

////==============================
//// NTMO.TTTT.Scrolling
//// This class is for scrolling title scene images.
//==============================
NTMO.TTTT.ScrollBackImages = function(parent) {
this.initialize.apply(this, arguments);
};

NTMO.TTTT.ScrollBackImages.prototype.initialize = function(parent) {
//Initialize
this._parent = parent;//parent scene.
this._backMainSprite = null;
this._backSubSprite = null;
this._mainSpeedX = 0;
this._mainSpeedY = 0;
this._subSpeedX = 0;
this._subSpeedY = 0;

//Create.
this.createSprites();
this.moveMainSprite(0, 0, Graphics.width, Graphics.height);
this.moveSubSprite(0, 0, Graphics.width, Graphics.height);
};

「うわっ、いきなりなんか長いコード出てきた」と思うかもしれませんが、大丈夫です。
大したことはやっていません。
最初の塊がクラスの宣言です。
最初の塊の中でinitilazeを呼んでいますね。
このinitializeがその後に続く「NTMO.TTTT.ScrollBackImages.prototype.initialize」を呼んでいる感じです。
引数にparentとありますが、ここでは利用するシーンのインスタンスの参照を表します
今回ならScene_Titleのインスタンスの参照ですね。

注*インスタンスの参照と言われてもピンとこない場合でかつ、詳しく知りたい場合は、「基本型と参照型」などでぐぐってみてもよいかもしれません。色々と解説してくれているサイトが出てきます。

その後に続くプロパティやらメソッドについては、このあとで個々に説明するので省略。
はい次のコードに行きましょう。

NTMO.TTTT.ScrollBackImages.prototype.createSprites = function() {
//Create.
this._backMainSprite = new TilingSprite(ImageManager.loadTitle1($dataSystem.title1Name));
this._backSubSprite = new TilingSprite(ImageManager.loadTitle2($dataSystem.title2Name));
//AddChild.
this._parent.addChild(this._backMainSprite);
this._parent.addChild(this._backSubSprite);
};

_backMainSpriteプロパティと_backSubSpriteがありますね。
これは前回分までの_backSprite1プロパティと_backSprite2プロパティなどに相当します。
1やら2やらじゃわかりにくいので、こうしました。
また、これらのプロパティは前回利用した_backSprite1および2とは全くの別物です(これ結構大事)。
つまり、前回までのコードではcenterSprite()をコメントアウトしていましたが、そういった処理も特に不要になります。

その後、_parentプロパティを介してaddChildしていますね(要はScene_TitleにaddChildする。この_parentプロパティがScene_Mapなら、Scene_MapにaddChildされることになる)。

さて次のコードへ行きます。

NTMO.TTTT.ScrollBackImages.prototype.moveMainSprite = function(x, y, width, height) {
this._backMainSprite.move(x, y, width, height);
};

NTMO.TTTT.ScrollBackImages.prototype.moveSubSprite = function(x, y, width, height) {
this._backSubSprite.move(x, y, width, height);
};

NTMO.TTTT.ScrollBackImages.prototype.setMainSpeed = function(speedX, speedY) {
this._mainSpeedX = (isFinite(speedX)) ? speedX : 0;
this._mainSpeedY = (isFinite(speedY)) ? speedY : 0;
};

NTMO.TTTT.ScrollBackImages.prototype.setSubSpeed = function(speedX, speedY) {
this._subSpeedX = (isFinite(speedX)) ? speedX : 0;
this._subSpeedY = (isFinite(speedY)) ? speedY : 0;
};

おっと4つものメソッドが出てきました。
ですがやっていることは単純です。
メインのスプライト(前回までで言うと_backSprite1)をmoveさせるためのメソッドと、サブのスプライトをmoveさせるメソッドが上の2つ
スプライトのスクロール速度を設定するためのメソッドが下の2つです。
下の方で何やらややこしそうなことをしていますが、speedXやspeedYが数字以外なら0を代入するよう組んでいるだけです。普通のif文で書いても全く問題ありません
速度の設定は、基本的にはこれらのメソッドを介して行うようにしましょう(数字のチェック機能もついてますしね)。

注*三項演算子(ハテナマークがついてるやつ)はあまり使わないほうがよいと聞いていたので今まで使用を控えていたのですが、最近「これ使ったほうがコード読みやすくね?」と感じ始めているので、これから積極的に使っていこうと思っています。

さて最後です。

NTMO.TTTT.ScrollBackImages.prototype.update = function() {
this.updateOriginPosition();
};

NTMO.TTTT.ScrollBackImages.prototype.updateOriginPosition = function() {
//Main.
this._backMainSprite.origin.x += this._mainSpeedX;
this._backMainSprite.origin.y += this._mainSpeedY;
//Sub.
this._backSubSprite.origin.x += this._subSpeedX;
this._backSubSprite.origin.y += this._subSpeedY;
};

上側のコードは、下側のコードを呼んでいるだけです。
下側のコードは、前回までで言うと

this._backSprite1.origin.x += 1;

などとしていた部分ですね。
「なぜ直接1や2などと書かず、this._mainSpeedXと回りくどいことをしているのか」と思う方もいるかもしれませんが、あとで読み直したときに、プロパティ名がある方がわかりやすいのです。
1やら2やらではその数字が何を意味するのかわかりませんが、_mainSpeedXと書かれていれば、「メインのスピードのX座標に関係する何かかな?」と変数名を読むだけである程度の推測ができます
これは特に大きなプログラムを書くときに役に立つので、なるべく「意味のわからない数字を使わない」ことを意識するとよいですね。

Scene_Titleに作成したクラスを適用する

まずはコードをぺたり。

//////=============================================================================
///// Scene_Title
///// Add particle and scrolling background.
/////=============================================================================
var _Scene_Title_createBackground = Scene_Title.prototype.createBackground;
Scene_Title.prototype.createBackground = function() {
_Scene_Title_createBackground.call(this);

//Hide the original background to display the scrolling background.
this._backSprite1.visible = false;
this._backSprite2.visible = false;

//Create scrolling background.You should ‘move()’ each image, if you want to draw a certain range.
this.scrollBackImages = new NTMO.TTTT.ScrollBackImages(this);
this.scrollBackImages.setMainSpeed(1,1);
this.scrollBackImages.setSubSpeed(1,1);
};

createBackground()内で

_Scene_Title_createBackground.call(this);

とあるのがわかりますでしょうか?
前回まではこのようなコードはなく、直接上書きしていました。
そしてよく見ると、this._backSprite1をTilingSpriteとしていません
ただvisibleプロパティをfalseにしているだけです(こうすることにより、スプライトが非表示になります。スクロール用の画像を表示するため、元の背景を非表示にしているのです)。
それもそのはずで、NTMO.TTTT.ScrollBackImagesクラスの中でTilingSpriteを作成しているので、Scene_Titleクラス内でTilingSpriteを作る必要がないのです。
簡単に言えば、NTMO.TTTT.ScrollBackImagesクラスのおかげで、Scene_Titleクラスのものをいじくり回す必要はほとんどないのです。

そして残りの三行。
ここで先ほどえっちらおっちらと作ったNTMO.TTTT.ScrollBackImagesクラスのインスタンスを作成しています。
その作成したインスタンスの参照がthis.scrollBackImagesに代入されているのもわかりますでしょうか?

new NTMO.TTTT.ScrollBackImages(this);

thisはScene_Titleクラスのインスタンスの参照を表します
もしも

this.scrollBackImages = new NTMO.TTTT.ScrollBackImages(this);

をScene_Mapで使えば、Scene_Mapクラスのインスタンスの参照がNTMO.TTTT.ScrollBackImagesクラスのparentプロパティに渡されます。

最後の2行は、メインのスプライトのスピードとサブのスプライトのスピードを設定しています(先ほど作ったメソッドを呼び出しています)。
さてここまでで大方の準備は整いました。
最後に、スプライトのoriginを更新させなければなりません(これも前回やりましたね)。

var _Scene_Title_update = Scene_Title.prototype.update;
Scene_Title.prototype.update = function() {
_Scene_Title_update.call(this);

this.scrollBackImages.update();
};

ここでupdateメソッドが呼ばれていますね。
これは以下のように置き換えても動作します。

//Main.
this.scrollBackImages._backMainSprite.origin.x += this.scrollBackImages._mainSpeedX;
this.scrollBackImages._backMainSprite.origin.y += this.scrollBackImages._mainSpeedY;
//Sub.
this.scrollBackImages._backSubSprite.origin.x += this.scrollBackImages._subSpeedX;
this.scrollBackImages._backSubSprite.origin.y += this.scrollBackImages._subSpeedY;

が、Scene_Titleクラスにこんなものを書くのはなんだかスマートじゃないですよね。
というわけでNTMO.TTTT.ScrollBackImagesクラス内にupdateメソッドをあらかじめ作っておき、それを呼び出すことにしているわけです。

ひとまず完成

プラグインを保存して、実行してみてください。
前回と変わらない画面が表示されたはずです。
「だったら前回のコードでもよくないか?」と思われるかもしれませんが、保守性に優れているのは今回のコードです。
また、Scene_TitleクラスとNTMO.TTTT.ScrollBackImagesクラスは完全に分離しており、NTMO.TTTT.ScrollBackImagesクラスは単体でも動作します
つまり、NTMO.TTTT.ScrollBackImagesクラスを他のプラグインへ流用させることもできるのですね。

と、長くなりましたが、いかがでしたでしょうか?
前回までよりは内容が難しめ(コード量が多い)ですが、一度に全てを理解できなくとも、徐々に理解していればよいのではないかなと思います。
実際、僕もそんな感じで徐々に成長していっています(プログラミング歴まだ四ヶ月ですw)。

「つぎはぎのコードじゃなくて、完成したコード公開してくれ!」という声もありそうなので、あらかじめ書いておきますが、完成したプラグインはツクールの公式フォーラムで公開予定です。
ですので、完成版のコードはもう少々お待ちください(リアルタイムで書いていっているので、まだできていないんですw)。

本当は今回でプラグインパラメーターの設定についても一席ぶとうと思ったのですが、少し長めになってしまったので次回分に取っておこうと思います。
それではまた。
お疲れさまでした!

フォローする