検索
現代SFRPG「重力ルーペ/探求リバーブ」

ドラマティックRPG「バンドワゴン」

ハートフルRPG「地図の時間」

ビジュアルノベル「日向と香水」

ノベル×ADV「ストーリーテラー」 title1_2.png
カテゴリ
リンク集
【スポンサードリンク】

【創作全般】






シナリオ制作


設定作り


最近読んでよかった本五選





創作意欲を掻き立てる本


自己管理術


クリエイター向けノウハウ

2018年01月13日

JavaScriptの基礎知識

◆JavaScriptの基礎知識
ツクールMV作品のメンテナンスやプラグインの挙動を学ぶため、JavaScriptの基礎知識を整理しています。
一部はプラグインのメモ欄の記述やスクリプトの記述を見直すときに役立つと思います。
※内容は学習状況にあわせて適宜更新します
※ツクールMVの観点でまとめているため、調べている内容に偏りがあります


■動作しない場合に見直す点

・半角入力が基本
 「''」「""」内は文字列なので日本語が利用可能

・大文字/小文字が厳格に区別される
 $gameVariables.value//正しい
 $gameVariables.Value//認識しない

・文字列やファイル名を指定する時に囲む「''」「""」はどちらでも可
 $gameVariables.setValue(1,"battle1");
 $gameVariables.setValue(1,'battle1');

・0を頭につけない(8進数として認識されてしまう)
 $gameVariables.setValue(1,10)//この場合、変数1は10
 $gameVariables.setValue(1,010)//この場合、変数1は8

・末尾に;をつける(省略も可能だが、区切りを明確にするため記述が一般的)
 $gameVariables.setValue(1,$gameVariables.value(1)+1);
 $gameSwitches.setValue($gameVariables.value(5), true);


■基礎テクニック

・空白、改行、タブ入れをしても影響はない
 コードの見易さを重視して、インデントを設定すれば良い

・一行に対するコメント
 $gameVariables.setValue(1,"battle1");//「//」以降はコメントとして自由に記述が可能

・複数行を使うコメント
 /*
 「/*」から「*/」で閉じるまでの間がコメントとして認識される
 */
 「/*」「*/」を入れ子にすると文法上エラーとなる、正規表現リテラルで発生するなどのリスクがあるため、//の利用が推奨される


■変数

変数(可変の値を扱う)の宣言はvar命令を使う
プラグインを参照するとコードの冒頭部分で確認することができる

・変数AAAを宣言
 var AAA;

・変数AAAとBBBを同時に宣言
 var AAA,BBB;

・変数のAAAの初期値を10に設定
 var AAA;
 var AAA = 10;
 初めて代入されたタイミングで「var AAA;」が実行されるが原則として変数の宣言は行う


■定数

定数(変わらない値)の宣言はconst命令を使う

・定数TAXを値1.08と同時に宣言
 const TAX = 1.08;


■命名規則

変数、関数、メソッド、ラベル、クラスの命名規則

・1文字目は$を使用する
 例.$gameVariables.value(n)

・「@」「-」を利用しない

・予約語を利用しない
 予約語 - JavaScript | MDN
 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Reserved_Words

・名前からデータ名が類推しやすいこと

・以下の記法からいずれかを統一して利用する
 camelCase記法:
  先頭単語の頭文字は小文字、それ以降の単語の頭文字は大文字
  例.lastName
 Pascal記法:
  全ての単語の頭文字は大文字
  例.LastName
 アンダースコア記法:
  単語同士を_で連結
  例.last_name
  ※個人的にはこの記法を推奨(区別しやすい)


■データ型
・基本形と参照系
 変数の扱い方の違い

 基本形:値を指定箇所に格納
  例.true/false,"文字列"、数値など

 参照系:参照値をアドレスに格納、必要範囲の値が呼び出される
  例.関数、配列リテラル(カラー情報[255,255,255])など
 ★JavaScriptから「Invalid or unexpected token」(不正な文字列)エラーが出た場合は値の入力規則を確認する

□配列リテラル
・array.js
 var data = ['0番目','1番目','2番目'];
 $gameVariables.setValue(1,(data[0]));
 変数1に「0番目」

・array2.js
 var data = ['0番目',['1番目A','1番目B'],'2番目'];
 $gameVariables.setValue(2,(data[1][1]));
 変数2に「1番目B」
 ★データベースを参照する場合はこの型が利用される気がする(装備タイプの区別)

・object.js
 var data = { x:1, y:2, z:3};
 $gameVariables.setValue(3,(data.x));
 変数3に「1」

□関数リテラル(function)
・関数
 与えられた入力(パラメーター)に基づいて処理を行い結果を返す仕組み

・ユーザー定義関数
 ユーザーがfunction命令で定義する関数
 showMessageのように「動詞+名詞」の形式で命名するのが一般的(cameCase記法)

・function関数の構文
 function 関数名(引数,...){//引数は挙動を決めるパラメーター
  ...任意の処理...
  return 戻り値;//任意の処理を経て引数に返す値
 }
・Functionコンストラクターの構文1
 var 変数 = new Function(引数,... ,関数の本体);

・Functionコンストラクターの構文2
 var 変数1 = 変数1の式
 var 変数2 = 変数2の式
 var 変数名3 = new Function(変数1,変数2);

★Functionコンストラクターはコード解析、関数オブジェクト生成を行う。頻度が高いとパフォーマンスに影響する恐れがある

・関数リテラル表現(function_literal.js)
 var 変数名 = function(引数1,引数2){
 return 計算式
};

例.rpg_scenes.jsでエンカウント時のエフェクトスピードを決定(60フレーム)

 Scene_Map.prototype.encounterEffectSpeed = function() {
  return 60;
 };

□未定義値(undefined)
次の場合に発生する
・変数が定義(var宣言)されているが値がない状態
・定義されていない関数のプロパティを参照しようとした

□ヌル(null)
・定義されているが返すものがない空の状態

例.rpg_managers.jsの記述例
 var $dataActors = null;
 var $dataClasses = null;
 var $dataSkills = null;
 var $dataItems = null;
...
各データベースのアクター、職業、スキル、アイテム…に対して空である状態を定義


■演算子
 「+」「=」のように処理を実行する記号(演算子、オペレーター)
 演算子によって処理される側の変数などをオペランド(非演算子)と呼ぶ

 + 加算
 - 減算
 * 乗算
 / 除算
 === 左右が正しいかを判定

内部処理は2進数で行われるため、小数点は正しく処理されない
 小数点の計算を行う場合は整数にしてから小数に戻す
 例.hogehoge.log(0.2 * 3);を求めたい場合
  hogehoge.log(((0.2 * 10) * 3) / 10);//0.2に10をかけて2にしてから結果を10で割る

□代入演算子
 指定された変数に値を代入する演算子
 ★イベントコマンド「変数の操作」→「代入」みたいなもの

 = 変数に値を代入
 += 左辺の値に右辺の値を加算したものを代入
 -= 左辺の値から右辺の値を減算したものを代入
 *= 左辺の値に右辺の値を乗算したものを代入
 /= 左辺の値を右辺の値で除算したものを代入
 ★左から右へ実行され、結果を代入すると覚えればよい

□分割代入(配列)
配列/オブジェクトを分解し、配下の要素/プロパティ値を変数にする構文
 ★稀にプラグインによってはこの記述がメモ欄に適用されている

 例.
 let data = [1,2,3,4,5,6,7,8];
 let[x0,x1,x2,x3,x4,x5,x6,x7] = data

 $gameVariables.setValue(3,x0);//変数3に1が代入
 $gameVariables.setValue(4,x7);//変数4に8が代入

□比較演算子
 左辺/右辺の値を比較し、結果をtrue/falseとして返す演算子
 ★判定に用いるため、利用頻度が高い

 == 左辺と右辺が等しい場合はtrue
 != 左辺と右辺が等しくない場合はtrue
 < 左辺が右辺より小さい場合はtrue
 <= 左辺が右辺以下の場合はtrue
 > 左辺が右辺より大きい場合はtrue
 >= 左辺が右辺以上の場合はtrue
 === 左辺と右辺の値が等しくてデータ型も同じ場合はtrue
 !== 左辺と右辺の値が等しくない場合、またはデータ型が異なる場合はtrue
 ★ここでも原則は左辺に対して右辺がどうかという考え方

□論理演算子
 2つ以上の式を結合して、結果をtrue/falseとして返す演算子
 ★式に対する演算子と考えれば良い

 && 左右の式がともにtrueの場合はtrue //and条件
 || 左右の式のどちらかがtrueの場合はtrue //or条件
 ! 式がfalseの場合はtrue //not条件

□演算子の優先順位
 優先順位の高い順
 ★多くの場合は()でまとめるので()の中に数学知識を当てはめればよい(足し算よりも掛け算が優先される〜レベル)
 ★コードを書く場合は()で可読性を高めるよう意識すると良い

 []、()
 ++、--、~、!
 *、/、%
 +、-
 <、<=、>、>=
 ==、!=、===、!==
 &
 ^
 |
 &&
 ||
 =、+=、-=
 ,


■制御構文

□if命令
if(条件式){
 条件式がtrue時に実行する命令;
 }
★イベントコマンド条件分岐と同じ

□if...else命令
if(条件式){
 条件式がtrue時に実行する命令;
 }else{
 条件式がfalse時に実行する命令;
 }
★イベントコマンド条件分岐(条件を満たさないときの分岐を作成)と同じ

□if...else if命令
if(条件式1){
 条件式1がtrue時に実行する命令;
 }else if(条件式2){
 条件式2がtrue時に実行する命令;
 }
}else{
 すべての条件式がfalse時に実行する命令;
}
★イベントコマンド条件分岐(条件を満たさないときの分岐を作成)の入れ子と同じ

例.rpg_manager.jsでマップ情報をロードする時の内部処理
 DataManager.loadMapData = function(mapId) {
  if (mapId > 0) {
  var filename = 'Map%1.json'.format(mapId.padZero(3));
  this._mapLoader = ResourceHandler.createLoader('data/' + filename, this.loadDataFile.bind(this, '$dataMap', filename));
  this.loadDataFile('$dataMap', filename);
  } else {
  this.makeEmptyMap();
  }
 };


■オブジェクトエラーの種類と意味

 EvalError:不正なeval関数
 RangeError:指定された値が許容範囲を超えている
 ReferenceError:var宣言されていない変数にアクセスした
 SyntaxError:文法エラー
 TypeError:指定された値が許容されたデータ型ではない
 ★Developer Toolsで判別する目安


■グローバル変数とローカル変数
・グローバル変数
 関数の外で宣言した変数

例.YEP_CoreEngine.jsでコードの冒頭から「Yanfly」をグローバル変数として宣言
 var Yanfly = Yanfly || {};
 Yanfly.Core = Yanfly.Core || {};
 Yanfly.Core.version = 1.22;

・ローカル変数
 関数の中で宣言した変数

例.rpg_managers.jsのAudioManager.saveBgm関数内で「bgm」をローカル変数として宣言

 AudioManager.saveBgm = function() {
  if (this._currentBgm) {
  var bgm = this._currentBgm;//グローバル変数でbgmと宣言すると競合の恐れがある
  return {
  name: bgm.name,
  volume: bgm.volume,
  pitch: bgm.pitch,
  pan: bgm.pan,
  pos: this._bgmBuffer ? this._bgmBuffer.seek() : 0
  };
  } else {
  return this.makeEmptyAudioObject();
  }
 };

・var命令を使わずに宣言された変数はすべてグローバル変数とみなされる
・作法としては関数の先頭でvar宣言は行われる(コードを見る時のポイント)

2018年01月09日

スクリプトを活用したイベントコマンド操作

◆スクリプトを活用したイベントコマンド操作

スクリプトを扱うための入門的な技術情報を調べ、実践してみました。
以下その覚書です。

■スクリプトで扱う利点

私の目的はスクリプトを活用することで効率化を図ることです。
調べる限り、スクリプトで扱うことでの利点は次のことが挙げられます。

・イベントコマンドにはない値を利用できる
 小数点以下の値、変数、MAPID、イベントIDなど

 特に変数は取得、代入でテンプレート化ができる
 テンプレート化することで入力作業が減り、作業効率化、バグ減少に繋がる

・イベントコマンドにはない処理を実行できる
 セルフスイッチ、スイッチの初期化

・内部処理の理解が進みトラブルに強くなる
 コアスクリプトとの繋がりが分かるとトラブル解決が早くなる

・アイディアが広がる
 可変箇所を知ることでアイディアが閃き、実践できる


◆基礎知識
スクリプトを扱ううえで必要と考える基礎知識を整理しました。

■記述に関する注意点

・半角入力で行う
・大文字/小文字の取り違えに注意する
 $gameVariables.value//正しい
 $gameVariables.Value//認識しない

・文字列やファイル名を指定する時に囲む「''」「""」はどちらでも可
 $gameVariables.setValue(1,"battle1");
 $gameVariables.setValue(1,'battle1');

・複数行を記述する場合、末尾に;をつける
 $gameVariables.setValue(1,$gameVariables.value(1)+1);
 $gameSwitches.setValue($gameVariables.value(5), true);

■便利な変数、スクリプトコマンド

・変数1番
 $gameVariables.value(1)

・変数1番に1を加算
 $gameVariables.setValue(1,$gameVariables.value(1)+1)

・0〜10の乱数
 Math.floor(Math.random() * 11)

・10〜20の乱数
 Math.floor(Math.random() * 11) + 10
 0〜10の乱数に10を足すことで、乱数が0なら10、乱数が10なら20にすることで0〜9を除外

・20〜30の乱数
 Math.floor(Math.random() * 11) + 20

・変数2番に0〜10の乱数を格納
 $gameVariables.setValue(2,Math.floor(Math.random() * 11))

・変数3番に20〜30の乱数を格納
 $gameVariables.setValue(3,Math.floor(Math.random() * 11) + 20)

・メンバーの数(メンバー…戦闘中は戦闘参加人数、移動中はパーティーの人数)
 $gameParty.members().length
 または
 $gameParty.size()

・戦闘参加人数
 $gameParty.battleMembers().length

・戦闘不参加も含めた、パーティーの人数
 $gameParty.allMembers().length

・生きているメンバーの数
 $gameParty.aliveMembers().length

・行動可能なメンバーの数
 $gameParty.movableMembers().length

・敵キャラ総数(まだ出現していない敵キャラは含まない)
 $gameTroop.members().length

・生きている敵キャラの数
 $gameTroop.aliveMembers().length

・倒された敵キャラの数
 $gameTroop.deadMembers().length

・行動可能な敵キャラの数
 $gameTroop.movableMembers().length

・現マップIDの取得
 this._mapId

・現イベントIDの取得
 this._eventId

・ウェイト
 this.wait(フレーム)
 1秒=60フレーム


◆実践
スクリプトで有用そうなものを試してみました。

■スイッチの操作
$gameSwitches.setValue(スイッチ番号, true/false);
 true:ON
 false:OFF

 例.変数5番のスイッチ番号をON
 ◆スクリプト:$gameSwitches.setValue($gameVariables.value(5), true);

□応用:全スイッチを初期化
$gameSwitches.clear();
 マップ切り替えで画面更新後に反映

■セルフスイッチの操作
$gameSelfSwitches.setValue([マップID,イベントID,A〜D], true/false);
 true:ON
 false:OFF
 A〜Dは一行につき一つのみ指定可能

 例.マップID=変数5番、イベントID=変数6番のセルフスイッチAをON
 $gameSelfSwitches.setValue([$gameVariables.value(5),$gameVariables.value(6),A], true);

□応用:全セルフスイッチを初期化
$gameSelfSwitches.clear();
 マップ切り替えで更新処理後に反映

□応用:現マップの現IDを操作
$gameSelfSwitches.setValue([this._mapId,this._eventId,A〜D], true/false);
 マップ切り替えで画面更新後に反映

■タイマーの操作
$gameTimer.start(フレーム);
 始動:
 ・1秒は60フレーム
 ・画面上にタイマーが表示されカウントダウンが始まる

$gameTimer.stop();
 停止:
 ・カウントダウン停止し、タイマーが消える

□応用:変数10のフレーム秒からカウントアップ
変数10番に毎秒1を足すカウントアップタイマー
以下の内容をコモンイベントの並列処理で実行する
 ◆スクリプト:$gameVariables.setValue(10,0)//変数10番に0を入れる
 ◆スクリプト:$gameTimer.start($gameVariables.value(10));//タイマーを開始
 ◆ループ
  ◆スクリプト:this.wait(60);//60フレーム=1秒ウェイトによりタイマーのカウントダウンを止める
  ◆スクリプト:$gameVariables.setValue(10,$gameVariables.value(10)+60);//止めている間に60=1秒を変数10番に加算
  ◆スクリプト:$gameTimer.start($gameVariables.value(10));//変数10番をタイマーに表示するためタイマーを再起動しループする
  ◆
  :以上繰り返し

■遠景の変更
$gameMap.changeParallax("画像ファイル名",横方向にループする,縦方向にループする, 横方向のスクロール速度, 縦方向のスクロール速度);

 横方向にループする:ループ→true ループしない→false
 縦方向にループする:ループ→true ループしない→false
 横方向のスクロール速度:フレーム(右から左の場合は正の値、右から左の場合は負の値、小数点以下も設定可)
 縦方向のスクロール速度:フレーム(下から上の場合は正の値、上から下の場合は負の値、小数点以下も設定可)
 ※超高速や超スローな動きが設定可能

 例.画像BlueSkyを遠景に設定、左から右へ横方向に0.5フレームの速度で動かす
 ◆スクリプト:$gameMap.changeParallax("BlueSky",true,false,-0.5,0);

■ピクチャの移動/ピクチャの回転/ピクチャの色調変更/ピクチャの消去
次の記事を参照

 スクリプトを活用したピクチャの管理
 http://fanblogs.jp/tabirpglab/archive/1075/0



今回は目的に沿って調べたので項目が偏っていますが、必要に応じてバトル関連や、データベース周りの部分も調べたいと思います。
以下サイト様が充実していますので、情報が必要な方はあわせてご覧ください。

謝辞:
RMMV Script Calls
https://goo.gl/3mSSGX

ツクールMVスクリプトリファレンスwiki
http://rpgmaker-script-wiki.xyz/mvscriptwiki.php

RPGツクールMV プラグインコマンド集リファレンス
https://docs.google.com/spreadsheets/d/1rOIzDuhLC6IqJPEFciYOmXWL_O7X9-hMValMs7DpWCk/edit#gid=1183699632

簡単なプラグインを作ってみよう 2(スマイル工房様)
http://blog.livedoor.jp/trb_surasura/archives/8842701.html