Files
krkr2doc/docs/kag3doc/contents/TJSTips.html
2016-09-08 17:50:19 +09:00

816 lines
65 KiB
HTML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<!-- generated by to_html.pl from TJSTips.xml -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>TJSをもっと使うために</title>
<meta name="author" content="W.Dee" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link href="browser.css" type="text/css" rel="stylesheet" title="吉里吉里関連リファレンス用標準スタイル" />
<link href="mailto:[email protected]" rev="Made" />
<link href="index.html" target="_top" rel="Start" title="トップページ" />
</head>
<body>
<h1><a id="id202" name="id202">TJS2とKAG</a>
</h1><div class="para"><div>
 TJS ( TJS2 ) は吉里吉里本体が直接理解できるスクリプト言語で、JavaScript や JAVA ににています。KAG はこの TJS スクリプトで記述されています。<br />
 TJS スクリプトは KAG が理解する ( 抽象的な ) シナリオよりもよりシステム側に近い ( 具体的な ) 記述をすることが可能で、扱いは難しくなりますができることの幅はぐっと広がります。<br />
<br />
 KAG には eval emb link if タグなどの exp 属性、各タグの cond 属性、エンティティ ( &amp; 付きのタグの属性 ) などなど、「TJS式」を指定する場面がいくつかあります。<br />
 TJS式を使うと、普通は KAG の裏に隠れている 吉里吉里に比較的簡単にアクセスすることができます。<br />
 また、iscript タグは、TJS2 スクリプトを直接実行することができます。これにより、高度な処理を実行したり、KAGの機能を拡張したりすることができます。<br />
<br />
 TJS2 の細かい文法については TJS2 のリファレンスを、吉里吉里本体の機能については吉里吉里2のリファレンスをご覧ください。<br />
</div></div>
<h1><a id="id203" name="id203">KAG のオブジェクト構造</a>
</h1><div class="para"><div>
 KAG それ自体は TJS2 スクリプトで記述されているため、( 良くも悪くも ) KAG の内部構造に直接アクセスすることができます。<br />
 KAG の管理するオブジェクトの変数に値を書き込む事などは相当注意したほうが良いですが、KAG 内部の変数を参照してより高度なシナリオ記述に応用することもできます。<br />
<br />
<dl>
<dt><a id="id204" name="id204" class="targanchor"><dfn>KAGWindow クラス</dfn></a>のオブジェクト</dt>
<dd> KAGWindow クラス ( MainWindow.tjs に記述 ) は、KAG のウィンドウを管理するためのクラスで、このクラスのオブジェクトがグローバル変数の <code class="inlinecode"><a id="id205" name="id205" class="targanchor"><dfn>kag</dfn></a></code> としてアクセスできます。<br />
 たとえば、KAGWindow クラスの <code class="inlinecode">skipMode</code> という変数 ( 現在どのようなモードでスキップ処理中かが入っている変数 ) にアクセスするには <code class="inlinecode"><a id="id206" name="id206" class="targanchor"><dfn>kag.skipMode</dfn></a></code> とします。</dd>
<dt><a id="id207" name="id207" class="targanchor"><dfn>背景レイヤ</dfn></a></dt>
<dd> 背景レイヤは <a id="id208" name="id208" class="targanchor"><dfn>BaseLayer クラス</dfn></a> ( GraphicLayer.tjs に記述 ) のオブジェクトです。<br />
 表画面の背景レイヤは <code class="inlinecode"><a id="id209" name="id209" class="targanchor"><dfn>kag.fore.base</dfn></a></code>、裏画面の背景レイヤは <code class="inlinecode"><a id="id210" name="id210" class="targanchor"><dfn>kag.back.base</dfn></a></code> でアクセスできます。</dd>
<dt><a id="id211" name="id211" class="targanchor"><dfn>前景レイヤ</dfn></a></dt>
<dd> 前景レイヤは <a id="id212" name="id212" class="targanchor"><dfn>CharacterLayer クラス</dfn></a> ( GraphicLayer.tjs に記述 ) のオブジェクトです。<br />
 表画面の前景レイヤは <code class="inlinecode"><a id="id213" name="id213" class="targanchor"><dfn>kag.fore.layers</dfn></a>[n]</code>、裏画面の前景レイヤは <code class="inlinecode"><a id="id214" name="id214" class="targanchor"><dfn>kag.back.layers</dfn></a>[n]</code> でアクセスできます ( n は前景レイヤ番号 0 ~ )。</dd>
<dt><a id="id215" name="id215" class="targanchor"><dfn>メッセージレイヤ</dfn></a></dt>
<dd> メッセージレイヤは <a id="id216" name="id216" class="targanchor"><dfn>MessageLayer クラス</dfn></a> ( MessageLayer.tjs に記述 ) のオブジェクトです。<br />
 表画面のメッセージレイヤは <code class="inlinecode"><a id="id217" name="id217" class="targanchor"><dfn>kag.fore.messages</dfn></a>[n]</code>、裏画面のメッセージレイヤは <code class="inlinecode"><a id="id218" name="id218" class="targanchor"><dfn>kag.back.messages</dfn></a>[n]</code> でアクセスできます ( n はメッセージレイヤ番号 0 ~ )。<br />
 <code class="inlinecode"><a id="id219" name="id219" class="targanchor"><dfn>kag.current</dfn></a></code> は現在操作対象となっているメッセージレイヤを表します。</dd>
<dt><a id="id220" name="id220" class="targanchor"><dfn>メッセージレイヤ内のオブジェクト</dfn></a></dt>
<dd> メッセージレイヤ内に作成した、グラフィカルボタン、エディット、チェックボックスなどにアクセスするにはメッセージレイヤの links を使います。<br />
 links は配列オブジェクトで、リンク、グラフィカルボタン、エディット、チェックボックスなどが作成された順に、それぞれを管理するオブジェクトへの参照が格納されています。そのうち、グラフィカルボタン、エディット、チェックボックス についてはさらにそのなかの object 変数にアクセスすることによって各クラスのオブジェクトに直接アクセスできます。<br />
 たとえば、表画面のメッセージレイヤ0に以下のような記述があって、<br />
<br />
<code class="bq">@cm<br />
@edit&nbsp;length=420&nbsp;name=&quot;f.name&quot;<br />
</code>
<br />
 このエディットにフォーカスを設定する ( キーボードから入力できるようにする ) にはさらに<br />
<br />
<code class="bq">@eval&nbsp;exp=&quot;kag.fore.messages[0].links[0].object.focus()&quot;<br />
</code>
<br />
 と記述することができます ( エディットを表示してユーザに入力をすぐに促したいときに便利 )。</dd>
<dt><a id="id221" name="id221" class="targanchor"><dfn>効果音バッファ</dfn></a></dt>
<dd> 効果音バッファは <a id="id222" name="id222" class="targanchor"><dfn>SESoundBuffer クラス</dfn></a> ( SE.tjs に記述 ) のオブジェクトです。<br />
 <code class="inlinecode"><a id="id223" name="id223" class="targanchor"><dfn>kag.se</dfn></a>[n]</code> でアクセスできます ( n は効果音バッファ番号 0 ~ )。</dd>
<dt><a id="id224" name="id224" class="targanchor"><dfn>BGM オブジェクト</dfn></a></dt>
<dd> BGM オブジェクトは <a id="id225" name="id225" class="targanchor"><dfn>BGM クラス</dfn></a> ( BGM.tjs に記述 ) のオブジェクトです。<br />
 <code class="inlinecode"><a id="id226" name="id226" class="targanchor"><dfn>kag.bgm</dfn></a></code> でアクセスできます。</dd>
<dt><a id="id227" name="id227" class="targanchor"><dfn>メニュー</dfn></a></dt>
<dd> メニューオブジェクトには <code class="inlinecode"><a id="id228" name="id228" class="targanchor"><dfn>kag.menu</dfn></a></code> でアクセスできます。<code class="inlinecode">kag.menu</code>
MenuItem クラスのオブジェクトで、<code class="inlinecode">kag.menu</code> それ自体はメニューバーを
示しており、その子に登録されたアイテムがメニューバーに並ぶことになります。<br />
 メニュー項目は Menus.tjs で作成していていますが、Menus.tjs を直接書き換えると
KAGシステムのアップデートなどでいちいち書き換えなければならなくなるので、後述するように
AfterInit.tjs を作成してそこに変更点を記述すると楽です。</dd></dl></div></div>
<h1><a id="id229" name="id229">TJS を使うときの注意</a>
</h1><div class="para"><div>
 KAG が栞に保存しない物に直接手を加えると、KAG が栞を読み込んでもそこの部分を再現できません。<br />
 KAG プラグインの onStore や onRestore をフックして栞に情報を保存するようにすれば問題ないのですが、そうしない場合は注意する必要があります。<br />
 特に Layer クラスに属する描画メソッドなどを使って、KAG の管理する背景レイヤや前景レイヤの内容に変更を加える場合などは注意が必要です。KAG は、レイヤにどのような画像が読み込まれていたかまでは記録しますが、レイヤに加えられた描画や変更までは記録しません。ですので、そのような状態で「栞を保存可能なラベル」を通過し、そこで栞を保存し、その栞を読み出しても、レイヤに加えた変更は再現できないことになります。<br />
 このような場合は、次に「栞を保存可能なラベル」を通過するまでに画像をクリアしたり別の画像を読み込むなどして KAG が管理しきれる状態に戻しておくか、あるいは「栞を保存可能なラベル」を書かない、などで回避することができます。<br />
 TJS を使う場合は、栞との関連について十分注意してください。<br />
</div></div>
<h1><a id="id230" name="id230">式中の演算や条件判断、表示に使うもの</a>
</h1><div class="para"><div>
<dl>
<dt><code class="inlinecode"><a id="id231" name="id231" class="targanchor"><dfn>&amp;&amp;</dfn></a></code><code class="inlinecode"><a id="id232" name="id232" class="targanchor"><dfn>||</dfn></a></code></dt>
<dd> この二つは演算子で、<code class="inlinecode">&amp;&amp;</code> は「かつ」を表し、<code class="inlinecode">||</code> は「または」を表します。<br />
 たとえば、<code class="inlinecode">f.flag1</code> が 1 で、かつ、<code class="inlinecode">f.flag2</code> が 2 の場合、という条件で何かをやりたい場合は、<br />
<br />
<code class="inlinecode">[if exp=&quot;f.flag1==1 &amp;&amp; f.flag2==1&quot;]</code><br />
<br />
 と書くことができます。<br />
 また、f.flag1 が 1 または 2 または 3 の場合、という条件の場合は、<br />
<br />
<code class="inlinecode">[if exp=&quot;f.flag1==1 || f.flag1==2 || f.flag1==3&quot;]</code><br />
<br />
 と書くことができます ( f.flag1 が整数ならば <code class="inlinecode">f.flag1&gt;=1 &amp;&amp; f.flag1&lt;=3</code> とも書けますが )。<br />
 普通の数式で足し算よりもかけ算を優先して計算しないとならないように、<code class="inlinecode">&amp;&amp;</code><code class="inlinecode">||</code> には優先順位に違いがあって、<code class="inlinecode">&amp;&amp;</code> の方が優先されます。<br />
 ですので、たとえば <code class="inlinecode">f.flag1</code> が 1 の場合で、かつ、<code class="inlinecode">f.flag2</code> が 3 または 5 のとき、という場合は、<br />
<br />
<code class="inlinecode">[if exp=&quot;f.flag1==1 &amp;&amp; (f.flag2==3 || f.flag2==5)&quot;]</code><br />
<br />
 のように ( ) カッコでくくらなければなりません。</dd>
<dt><code class="inlinecode"><a id="id233" name="id233" class="targanchor"><dfn>random</dfn></a></code><code class="inlinecode"><a id="id234" name="id234" class="targanchor"><dfn>intrandom</dfn></a></code></dt>
<dd> random は 0 以上 1 未満の実数の乱数となります。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@eval&nbsp;exp=&quot;f.ransuu&nbsp;=&nbsp;random&quot;</code>
<br />
<br />
 上記の例のようにすると、f.ransuu には 0 以上 1 未満の実数の乱数が入ります。<br />
<br />
 これに対し、intrandom は指定値以上、指定値以下の整数の乱数を返す関数です。<br />
<br />
書式 : <code class="inlinecode">intrandom(<em>最小値</em>, <em>最大値</em>)</code><br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@eval&nbsp;exp=&quot;f.ransuu&nbsp;=&nbsp;intrandom(0,&nbsp;5)&quot;</code>
<br />
<br />
 上記の例
のようにすると 0 以上 5 以下の整数の乱数が f.ransuu に入ります。</dd>
<dt><code class="inlinecode"><a id="id235" name="id235" class="targanchor"><dfn>length</dfn></a></code></dt>
<dd> length は、文字列の長さを得ることのできるものです。使い方は、文字列の代入された変数の後に . (ドット) を書き、続けて length と書きます。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[if&nbsp;exp=&quot;f.namae.length&gt;=8&quot;]名前が長すぎます。[l][jump&nbsp;target=*input][endif]</code>
<br />
<br />
 上記の例では、f.namae の長さが8文字以上だった場合に「名前が長すぎます。」と表示し、*input ラベルにジャンプします。<br />
 文字は半角、全角問わず、一文字は一文字として数えられます。これは他の文字列を扱う機能でも同じです。</dd>
<dt><code class="inlinecode"><a id="id236" name="id236" class="targanchor"><dfn>substring</dfn></a></code></dt>
<dd> substring は、文字列の一部分(部分文字列)を取り出すことのできるものです。<br />
 使い方は、文字列の代入された変数 ( または文字列を表すもの ) のあとに . (ドット) を書き、続けて<br />
<br />
<code class="inlinecode">substring(<em>切り取り開始位置</em>, <em>切り取る長さ</em>)</code><br />
<br />
 の書式で記述します。切り取り開始位置は 0 が先頭を表します。<br />
<br />
 たとえば、f.furigana 変数の2番目の文字を取り出したい場合、<code class="inlinecode">f.furigana.substring(1, 1)</code> で取り出すことができます。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@emb&nbsp;exp=&quot;f.furigana.substring(1,&nbsp;1)&quot;</code>
<br />
<br />
 上記の例では、f.furigana 変数の2番目の文字を表示します。</dd>
<dt><code class="inlinecode"><a id="id237" name="id237" class="targanchor"><dfn>indexOf</dfn></a></code></dt>
<dd> indexOf (インデックス・オブ) は、文字列中の部分文字列が最初に現れる位置を得ることができます。使い方をかえれば、ある文字列中に他の文字列が入っているかどうかを調べることができます。<br />
<br />
書式 : <code class="inlinecode"><em>文字列</em>.indexOf(<em>部分文字列</em>)</code><br />
<br />
 たとえば、文字列が <code class="inlinecode">&quot;ABCDEFGHIJKL&quot;</code> で、部分文字列が <code class="inlinecode">&quot;ABC&quot;</code> であった場合、<code class="inlinecode">&quot;ABCDEFGHIJKL&quot;.indexOf(&quot;ABC&quot;)</code><em>0</em> になります。部分文字列が <code class="inlinecode">&quot;BCD&quot;</code> の場合は <em>1</em><code class="inlinecode">&quot;DEF&quot;</code> の場合は <em>3</em> になります。
 もし、部分文字列が文字列中に現れなかった場合は <em>-1</em> になりますので、部分文字列が文字列の一部であるかどうかを判定するには -1 と比較すればいいことになります。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[if&nbsp;exp=&quot;'尼屁尻'.indexOf(f.objname)!=-1&quot;]~~[endif]</code>
<br />
<br />
 上記例では、<code class="inlinecode">f.objname</code><code class="inlinecode">&quot;&quot; &quot;&quot; &quot;&quot; &quot;尼屁&quot; &quot;屁尻&quot; &quot;尼屁尻&quot;</code> のいずれかであった場合に <code class="inlinecode">endif</code> までを実行します。<br />
 これを、<code class="inlinecode">&quot;尼屁&quot; &quot;屁尻&quot; &quot;尼屁尻&quot;</code> では NG にしたい場合 ( <code class="inlinecode">&quot;&quot; &quot;&quot; &quot;&quot;</code> の場合のみ OK にしたい場合 )、<code class="inlinecode">'尼屁尻'</code>のそれぞれを <code class="inlinecode">f.objname</code> 内では現れることのない文字(や記号) で区切ることによって実現できます。<br />
 たとえば、\v という特殊な制御記号をつかって区切ると、上記の例は<br />
<br />
<code class="inlinecode">[if exp=&quot;'尼\v屁\v尻'.indexOf(f.objname)!=-1&quot;]~~[endif]</code><br />
とかくことができます ( \v は通常、f.objname 内には現れないから )。<br />
<br />
 下記例では、f.itemname 内に 'コップ' という文字列が含まれている場合に endif までを実行します。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[if&nbsp;exp=&quot;f.itemname.indexOf('コップ')!=-1&quot;]~~[endif]</code>
<br />
</dd>
<dt><a id="id238" name="id238" class="targanchor"><dfn>正規表現</dfn></a></dt>
<dd> 正規表現パターン ( / と / で囲まれた部分 ) を使って正規表現パターンによる文字列の分解や検査を行うことができます。<br />
 正規表現パターンそのものは Perl の正規表現によく似ています ( 使い方は違いますが正規表現パターンはほぼ互換です )。<br />
<br />
 文字列が目的のパターンに適合しているかどうかを調べるには <code class="inlinecode"><a id="id239" name="id239" class="targanchor"><dfn>test</dfn></a></code> を使います。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[if&nbsp;exp=&quot;/[^0-9]/.test(f.nyuryoku)&quot;]入力された文字に数字以外が混じっています[endif]</code>
<br />
<br />
 上記の例のようにして test を使います。test はパターンに合致すると真を、合致しないと偽を返す関数(正規表現オブジェクトのメソッド)です。上記の例では、<code class="inlinecode">[^0-9]</code> つまり数字以外が混じっているかどうかを検査する正規表現パターンを用いて、<code class="inlinecode">f.nyuryoku</code> に数字以外の文字が混じっているかを検査しています。<br />
<br />
 文字列を分解するには <code class="inlinecode"><a id="id240" name="id240" class="targanchor"><dfn>match</dfn></a></code> を使います。<code class="inlinecode">match</code> は配列オブジェクトを返します。パターンに合致しなかった場合は配列の要素数 ( <code class="inlinecode">count</code> ) が 0 になります。それ以外の場合、要素 0 はマッチした部分全体、要素 1 からあとはパターン中の ( ) (カッコ) に対応してマッチした部分が返されます。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[eval&nbsp;exp=&quot;f.matched&nbsp;=&nbsp;/([0-90-9]+)[--]([0-90-9]+)/.match(f.input)&quot;]<br />
[if&nbsp;exp=&quot;f.matched.count&nbsp;==&nbsp;0&quot;]「数値-数値」の形式で入力してください。[jump&nbsp;target=*input][endif]<br />
[eval&nbsp;exp=&quot;f.s1&nbsp;=&nbsp;str2num(f.matched[1]),&nbsp;f.s2&nbsp;=&nbsp;str2num(f.matched[2])&quot;]<br />
</code>
<br />
 上記の例では、<code class="inlinecode">f.input</code> が「数値-数値」の形式に合致しているかをテストして、合致していれば - (ハイフン) の前の部分の <code class="inlinecode">f.s1</code> に、後の部分を <code class="inlinecode">f.s2</code> に、数値に変換してから代入しています。</dd>
<dt><code class="inlinecode"><a id="id241" name="id241" class="targanchor"><dfn>str2num</dfn></a></code></dt>
<dd> str2num は、文字列を数値に変換します。<br />
<br />
書式 : <code class="inlinecode">str2num(<em>文字列または文字列の入った変数</em>)</code><br />
<br />
 単項の <code class="inlinecode">+</code> 演算子と違うのは、<code class="inlinecode">str2num</code> は、全角の数字であっても数値に変換できるということです。input タグのように、ユーザが全角で数値を入力してしまう可能性のある場合に使用できると思います。数値として認識できない文字列が渡された場合は 0 になります。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[input&nbsp;name=&quot;f.kazu&quot;&nbsp;prompt=&quot;数値を入力してください&quot;][emb&nbsp;exp=&quot;f.kazu=str2num(f.kazu)&quot;]</code>
<br />
</dd>
<dt><code class="inlinecode"><a id="id242" name="id242" class="targanchor"><dfn>kansuuji</dfn></a></code><code class="inlinecode"><a id="id243" name="id243" class="targanchor"><dfn>kansuuji_simple</dfn></a></code></dt>
<dd> <code class="inlinecode">kansuuji</code> は、指定された数値を漢数字表記にします。<code class="inlinecode">kansuuji_simple</code> も同様ですが、桁を表す単位をつけません。<br />
 9223372036854775807 という数値を、<code class="inlinecode">kansuuji</code> の場合は &quot;九百二十二京三千三百七十二兆三百六十八億五千四百七十七万五千八百七&quot; に、<code class="inlinecode">kansuuji_simple</code> の場合は &quot;九二二三三七二〇三六八五四七七五八〇七&quot; に変換します。<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@emb&nbsp;exp=&quot;kansuuji(f.num)&quot;<br />
</code>
<br />
 上記の例では、f.num を漢数字表記にして表示しています。<br />
</dd>
<dt><code class="inlinecode"><a id="id244" name="id244" class="targanchor"><dfn>number_format</dfn></a></code></dt>
<dd> <code class="inlinecode">number_format</code> は、指定された数値を3桁ごとに , (カンマ) で区切った表記にします。たとえば、9223372036854775807 という数値ならば &quot;9,223,372,036,854,775,807&quot; に変換されます。<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@emb&nbsp;exp=&quot;number_format(f.num)&quot;<br />
</code>
<br />
 上記の例では、f.num を 3桁ごとにカンマで区切って表示しています。<br />
</dd>
<dt><code class="inlinecode"><a id="id245" name="id245" class="targanchor"><dfn>Storages.addAutoPath</dfn></a><a id="id246" name="id246" class="targanchor"><dfn>System.exePath</dfn></a></code></dt>
<dd> Storages.addAutoPath は、自動検索パスを追加します。<br />
 System.exePath は、吉里吉里実行可能ファイルの設置されているフォルダを示します。<br />
 詳しくは吉里吉里 SDK Help を参照していただきたいのですが、これらを使うとアーカイブやフォルダに自動検索パスを設定できます。<br />
 自動検索パスは、わざわざフォルダを指定しなくても、ファイルを自動的に見つけてくるための仕組みです。標準では、system image scenario bgimage fgimage bgm sound rule others video のすべてが設定されていますが、Storages.addAutoPath で追加することができます。<br />
System.exePath は、吉里吉里実行可能ファイルのあるフォルダです。<br />
<br />
 たとえば、吉里吉里実行可能ファイルの直下に cgdata というフォルダがあって、そこの中を自動検索パスに指定したい場合は、<br />
<br />
<code class="inlinecode">[eval exp=&quot;Storages.addAutoPath(System.exePath + 'cgdata/')&quot;]</code><br />
<br />
 とします ( cgdata の後の二つの / は必ずつけてください )。<br />
<br />
 もし、吉里吉里実行可能ファイルと同じ場所に cgdata.xp3 というアーカイブファイルがあって、このアーカイブ内に自動検索パスを指定したい場合は、<br />
<br />
<code class="inlinecode">[eval exp=&quot;Storages.addAutoPath(System.exePath + 'cgdata.xp3&gt;')&quot;]</code><br />
<br />
 とします。cgdata.xp3 の後の記号は '&gt;' です。アーカイブ内に検索パスを指定する場合は &gt; で、フォルダ内に検索パスを指定する場合は / です。<br />
 アーカイブの後の記号は 吉里吉里2 2.19 beta 14 で '#' から '&gt;' に変更となりました。<br />
</dd>
<dt><code class="inlinecode"><a id="id247" name="id247" class="targanchor"><dfn>Storages.searchCD</dfn></a></code></dt>
<dd> Storages.searchCD は、引数に渡されたボリュームラベルを持つ CD が挿入されたドライブの文字を返します。<br />
 たとえば、上記 Storages.addAutoPath と組み合わせて、FOO_BAR_DISC というボリュームラベルを持つ CD-ROM 内の image というフォルダに自動検索パスを追加したい場合、<br />
<br />
<code class="inlinecode">[eval exp=&quot;Storages.addAutoPath(Storages.searchCD('FOO_BAR_DISC') + ':image/')&quot;]</code><br />
<br />
 と記述することができます。<br />
<br />
 Stotages.searchCD は、指定されたボリュームラベルを持つ CD が挿入されたドライブが見つからない場合は空文字列を返すので、たとえば指定の CD-ROM がドライブに挿入されていることを確認するために、<br />
<br />
<code class="inlinecode">[if exp=&quot;Storages.searchCD('FOO_BAR_DISC') == ''&quot;]CDが挿入されていません[endif]</code><br />
<br />
 のように記述することができます。</dd>
<dt><code class="inlinecode"><a id="id248" name="id248" class="targanchor"><dfn>System.readRegValue</dfn></a></code></dt>
<dd> System.readRegValue では、レジストリに書き込まれた値を読むことができます。たとえば、HKEY_LOCAL_MACHINE\SOFTWARE\Dee\kirikiri\installpath を f.installpath に読み込むには、<br />
<br />
<code class="inlinecode">[eval exp=&quot;f.installpath = System.readRegValue('HKEY_LOCAL_MACHINE\\SOFTWARE\\Dee\\kirikiri\\installpath')&quot;]</code><br />
 とします。'' で囲まれた中では \ は \\ と記述しなければならないことに注意してください。<br />
 文字列と数値の値のみを読むことができます。レジストリに値が存在しない場合は void になるので、<code class="inlinecode">===</code> (識別演算子) を用いて<br />
<br />
<code class="inlinecode">[if exp=&quot;f.installpath === void&quot;]インストールされていません[endif]</code><br />
<br />
 のような記述をすることができます。</dd>
<dt><code class="inlinecode"><a id="id249" name="id249" class="targanchor"><dfn>kag.clickCount</dfn></a></code></dt>
<dd> 画面上をマウスでクリックするたびに 1 が加算されます。この変数には値を代入してもかまいませんので、0 に設定しておけば、マウスがクリックされたことを、この変数が 0 以外の数値になっていることで知ることができます。</dd>
<dt><code class="inlinecode"><a id="id250" name="id250" class="targanchor"><dfn>kag.lastMouseDownX</dfn></a><a id="id251" name="id251" class="targanchor"><dfn>kag.lastMouseDownY</dfn></a></code></dt>
<dd> これらは、最後にマウスがクリックされた座標を表しています。kag.lastMouseDownX は最後にクリックされた X 座標、kag.lastMouseDownY は最後にクリックされた Y 座標です。</dd>
<dt><code class="inlinecode"><a id="id252" name="id252" class="targanchor"><dfn>kag.lastWaitTime</dfn></a></code></dt>
<dd> wait タグを mode=until で使用したとき、実際に wait タグがまとうとした時間が設定されます。すでにまとうとしていた時間が過ぎていた場合は 0 になりますので、wait タグの直後でこの変数が 0 でないかどうかを判断すれば、処理が追いついているかどうかを判断することができます。<br />
 ちなみに、クリックなどで wait が中断された場合は、この変数は正確に待っていた時間を表す訳ではありません ( 中断がなかったとした場合の時間を表しています )。</dd>
<dt><code class="inlinecode"><a id="id253" name="id253" class="targanchor"><dfn>kag.skipMode</dfn></a></code></dt>
<dd> 現在のスキップのモードを表す値が入っています。0=スキップなし, 1=クリック待ち記号まで, 2=改ページ待ち記号まで, 3=次の停止まで、となっています。<br />
 たとえば、声や効果音などをスキップ中には再生したくない場合は、<br />
<br />
<code class="inlinecode">@playse cond=&quot;kag.skipMode&lt;=1&quot; storage=&quot;hogehoeg.wav&quot;</code><br />
<br />
 のように記述することができます。</dd>
<dt><code class="inlinecode"><a id="id254" name="id254" class="targanchor"><dfn>kag.autoMode</dfn></a></code></dt>
<dd> 自動読みすすみの処理中の時に真、それ以外の時に偽になっています。<br />
 たとえば、声や効果音などの終了を、自動読みすすみの時のみに処理したい場合は、<br />
<br />
<code class="inlinecode">@ws cond=&quot;kag.autoMode&quot;</code><br />
<br />
 のように記述することができます。</dd>
<dt><code class="inlinecode"><a id="id255" name="id255" class="targanchor"><dfn>kag.getBookMarkPageName</dfn></a></code></dt>
<dd> <code class="inlinecode">kag.getBookMarkPageName</code> は、非フリーセーブモードにおいて、引数に指定された番号 ( 0 ~ ) で示された、栞の場所の名前を得ることが出来ます。<br />
 KAG のメニューからではなく、画面上で栞を示してユーザーにたどる栞を選ばせたいときに使うことが出来ます。<br />
 <code class="inlinecode">kag.restoreBookMark</code> と組み合わせて使います。<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[locate&nbsp;x=10&nbsp;y=100][link&nbsp;exp=&quot;kag.restoreBookMark(0)&quot;][emb&nbsp;exp=&quot;kag.getBookMarkPageName(0)&quot;][endlink]<br />
[locate&nbsp;x=10&nbsp;y=130][link&nbsp;exp=&quot;kag.restoreBookMark(1)&quot;][emb&nbsp;exp=&quot;kag.getBookMarkPageName(1)&quot;][endlink]<br />
(以下同様)<br />
</code>
<br />
</dd>
<dt><code class="inlinecode"><a id="id256" name="id256" class="targanchor"><dfn>mp</dfn></a></code></dt>
<dd> <code class="inlinecode">mp</code> は、マクロ中にて、マクロに渡された属性が記録された辞書配列を表します。<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@macro&nbsp;name=fimg<br />
@image&nbsp;*<br />
@eval&nbsp;exp=&quot;sf[mp.storage]=1&quot;<br />
@endmacro<br />
</code>
<br />
 上記の例では、たとえば <code class="inlinecode">@fimg layer=base page=fore storage=&quot;bg_03&quot;</code> と記述された場合、このマクロが実行されている間は <code class="inlinecode">mp.layer</code><code class="inlinecode">'base'</code><code class="inlinecode">mp.page</code><code class="inlinecode">'fore'</code><code class="inlinecode">'mp.storage'</code><code class="inlinecode">'bg_03'</code> になっています。つまり、マクロに渡された属性を <code class="inlinecode">mp.</code> の後に指定することによって、その属性の値を得ることができます。<br />
 このマクロを <code class="inlinecode">@fimg layer=base page=fore storage=&quot;bg_03&quot;</code> として使用した場合、exp タグで <code class="inlinecode">sf[mp.storage]=1</code> が実行されるため、<code class="inlinecode">sf['bg_03']</code> が 1 になります。<br />
 このマクロは、image/img タグの代わりに使うことにより、表示した画像を自動的にシステム変数に記録するマクロとして使用することができます。</dd>
<dt><code class="inlinecode"><a id="id257" name="id257" class="targanchor"><dfn>System.getKeyState</dfn></a></code></dt>
<dd> <code class="inlinecode">System.getKeyState</code> は、現在その時点で、指定されたキーが押されているかどうかを判断することができます。<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@jump&nbsp;target=*shift_key_pressed&nbsp;cond=&quot;System.getKeyState(VK_SHIFT)&quot;<br />
;&nbsp;シフトキーが押されていれば、*shift_key_pressed&nbsp;にジャンプする<br />
</code>
<br />
詳しくは吉里吉里2 SDK Help を参照してください。<br />
<br />
 KAG3はゲームパッド(ジョイスティック)からの入力を受け付けますが、ゲームバッドの上に物が乗っかっている、あるいはジョイスティックの軸の調整が不十分という場合には、正常に作品の操作をできない場合があります。<br />
 作品開始時にゲームパッドのボタンが押されていれば、ユーザに対して警告をすることができます (通常、作品開始時にゲームパッドのボタンが押されていることはなく、押されているとなれば、ユーザの意図しない理由で押されたままになっている可能性が高いため)。<br />
 USB接続のゲームパッドなどでは下記の例では「押されっぱなし」の検出がうまくいかないかもしれませんので、適宜ドキュメントなどでの補足を推奨します。<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@if&nbsp;exp=&quot;System.getKeyState(VK_PADANY)&quot;<br />
@wait&nbsp;time=500<br />
@if&nbsp;exp=&quot;System.getKeyState(VK_PADANY)&quot;<br />
;&nbsp;VK_PADANYでは、ゲームパッドのいずれかのボタンが押されている時に真を返す<br />
;&nbsp;500ms(0.5秒間)をすぎてもなお押されているようならばメッセージを表示<br />
ゲームパッド(ジョイスティック)のボタンが押されたままになっています。<br />
ゲームパッドの上に物が乗っかっていないか、あるいはジョイスティックの<br />
軸の調整がされているかを確認してください。<br />
状況が改善しない場合は、ゲームパッド(ジョイスティック)を抜いてください。<br />
それでも状況が改善しなければ、ゲームを終了し、「エンジン設定」を起動し、<br />
「入力-パッド使用可否」の設定を「使用しない」に設定してください。<br />
[s]<br />
@endif<br />
@endif<br />
</code>
<br />
</dd>
</dl>
</div></div>
<h1><a id="id258" name="id258">リンクやボタンの exp 属性などに指定するもの</a>
</h1><div class="para"><div>
<dl>
<dt><code class="inlinecode"><a id="id259" name="id259" class="targanchor"><dfn>System.shellExecute</dfn></a></code></dt>
<dd> System.shellExecute は、引数に指定されたファイルを開きます。URL を指定するとブラウザが開くので、link タグなどを使ってこの式を実行させれば、Web ページへのリンクなどを作成することが出来ます。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[link&nbsp;exp=&quot;System.shellExecute('http://www.yahoo.co.jp/')&quot;]http://www.yahoo.co.jp/[endlink]</code>
<br />
</dd>
<dt><code class="inlinecode"><a id="id260" name="id260" class="targanchor"><dfn>kag.close</dfn></a></code><code class="inlinecode"><a id="id261" name="id261" class="targanchor"><dfn>kag.shutdown</dfn></a></code></dt>
<dd> kag.close は、KAG を終了させます。終了確認を行う設定にしている場合は終了確認があります。<br />
 kag.shutdown も KAG を終了させますが、終了確認はありません。<br />
 なお、終了に System.exit() を使用すると、システム変数が保存されずに終了される場合があるので<em>使用しないでください</em>。また、これらは eval タグの exp 属性では指定しないでください (代わりに close タグを使用してください)。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[link&nbsp;exp=&quot;kag.close()&quot;]終了[endlink]<br />
[link&nbsp;exp=&quot;kag.shutdown()&quot;]終了[endlink]<br />
</code>
<br />
</dd>
<dt><code class="inlinecode"><a id="id262" name="id262" class="targanchor"><dfn>kag.restoreBookMark</dfn></a></code><code class="inlinecode"><a id="id263" name="id263" class="targanchor"><dfn>kag.storeBookMark</dfn></a></code></dt>
<dd> kag.restoreBookMark は、非フリーセーブモードにおいて、引数に指定された番号で示された栞をたどります。<br />
 同様に、kag.storeBookMark は、引数に指定された番号で示された栞を挟みます。<br />
 ただし、これを直接呼び出すと、[store] タグで栞の使用が禁止されていても栞の操作が出来てしまいます。<br />
 これらは、成功すると真を、失敗すると偽を返します。<br />
 例は kag.getBookMarkPageName の物を参照してください。</dd>
<dt><code class="inlinecode"><a id="id264" name="id264" class="targanchor"><dfn>kag.loadBookMarkFromFileWithAsk</dfn></a></code><code class="inlinecode"><a id="id265" name="id265" class="targanchor"><dfn>kag.saveBookMarkToFileWithAsk</dfn></a></code></dt>
<dd> kag.loadBookMarkFromFileWithAsk は、フリーセーブモードにおいて、ファイル選択ダイアログボックスを表示し、ユーザに栞データを選択させます。ユーザが OK ボタンを押すとその栞から再開します。<br />
 同様に、kag.saveBookMarkToFileWithAsk は、ファイル選択ダイアログボックスを表示し、栞を保存します。<br />
 これらは、成功すると真を、ユーザがキャンセルをするか、あるいは失敗すると偽を返します。<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[link&nbsp;exp=&quot;kag.loadBookMarkFromFileWithAsk()&quot;]栞をたどる[endlink]<br />
[link&nbsp;exp=&quot;kag.saveBookMarkToFileWithAsk()&quot;]栞をはさむ[endlink]<br />
</code>
<br />
</dd>
<dt><code class="inlinecode"><a id="id266" name="id266" class="targanchor"><dfn>kag.callExtraConductor</dfn></a></code></dt>
<dd> kag.callExtraConductor は、TJS の制御によって KAG のシナリオをサブルーチンとして呼び出すために用います。このメソッドでシナリオを呼び出すときは、シナリオがクリック待ちや s タグで停止中である必要があります ( kag.inStable や KAG プラグインの onStableStateChanged で知ることができます )。<br />
 kag.callExtraConductor には引数が3つあります。<br />
 最初の引数は呼び出すシナリオファイルです。次の引数は呼び出すラベルです。<br />
 3番目の引数は省略可能ですが、KAG のシナリオから戻ったときに実行する関数/メソッドを指定します。必要ない場合は指定しなくてかまいません。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[button&nbsp;graphic=&quot;showhist&quot;&nbsp;exp=&quot;kag.callExtraConductor('rclick.ks',&nbsp;'*showhist')&quot;]</code>
<br />
<br />
 これで呼び出すサブルーチンの書き方は、右クリックサブルーチンの書き方に準じます。<br />
 右クリックサブルーチン中や、すでにこの機能を使って KAG のシナリオを呼び出している最中では、この機能は使用できません。</dd>
<dt><code class="inlinecode"><a id="id267" name="id267" class="targanchor"><dfn>kag.se[n].play</dfn></a></code></dt>
<dd> 効果音バッファの play メソッドは、効果音の再生を開始します。<br />
 以下の形式で指定します。<br />
<br />
 
<br />
<code class="bq">kag.se[効果音バッファ番号].play(%[storage:&nbsp;再生する効果音のファイル名,&nbsp;loop:&nbsp;ループするか]);</code>
<br />
<br />
 これをたとえば、以下の例のように link タグの onenter 属性に指定すれば、選択肢の上にマウスカーソルが乗ったときに効果音を発音することができます。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[link&nbsp;target=*foo&nbsp;onenter=&quot;kag.se[0].play(%[storage:'select.wav',&nbsp;loop:&nbsp;false])&quot;]選択肢~[endlink]</code>
<br />
<br />
 この例では、効果音バッファ 0 番で select.wav を、ループをせずに再生します。他にも TJS の制御で効果音を鳴らしたいときに便利です。</dd></dl></div></div>
<h1><a id="id268" name="id268">配列</a>
</h1><div class="para"><div>
 吉里吉里2/KAG3 では配列を簡単に使うことができます。<br />
 配列を使う場合は、最初に <code class="inlinecode"><a id="id269" name="id269" class="targanchor"><dfn>[ ]</dfn></a></code> を使って配列を宣言しないとなりません。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[eval&nbsp;exp=&quot;f.hairetsu&nbsp;=&nbsp;[]&quot;]</code>
<br />
<br />
 上記の例では、<code class="inlinecode">f.hairetsu</code> を配列として使うことを宣言しています。もしすでに <code class="inlinecode">f.hairetsu</code> が配列だったり、他の数値とか文字列であったとすると <code class="inlinecode">f.hairetsu</code> の内容は消去されてしまいますので注意してください。<br />
 システム変数などで配列を使いたい場合は、初期状態では変数はすべて void が代入されていると見なされることを利用して、<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[eval&nbsp;exp=&quot;sf.hairetsu&nbsp;=&nbsp;[]&nbsp;if&nbsp;sf.hairetsu&nbsp;===&nbsp;void&quot;]</code>
<br />
<br />
 とすれば、初回起動時だけ配列を宣言することができます。2回目以降でも配列が消去されることはありません。<br />
<br />
 配列に値を代入するには <code class="inlinecode">[ ]</code> を使います。<code class="inlinecode">[ ]</code> 内には添え字 ( 要素番号 ) を書きます。添え字は 0 から始まります。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[eval&nbsp;exp=&quot;f.hairetsu[0]&nbsp;=&nbsp;'zero',&nbsp;f.hairetsu[1]&nbsp;=&nbsp;'one'&quot;]</code>
<br />
<br />
 上記の例では <code class="inlinecode">f.hairetsu[0]</code> に 'zero' を、<code class="inlinecode">f.hairetsu[1]</code> に 'one' を代入しています。<br />
 配列の要素数は宣言する必要はありません。必要な大きさまで自動的に拡張されます。配列の要素数を得たり設定したりするには <code class="inlinecode"><a id="id270" name="id270" class="targanchor"><dfn>count</dfn></a></code> プロパティを用いて <code class="inlinecode">f.hairetsu.count</code> などとします。 <br />
<br />
 表示も同様に行えます。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />0&nbsp;:&nbsp;[emb&nbsp;exp=&quot;f.hairetsu[0]&quot;]&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;:&nbsp;[emb&nbsp;exp=&quot;f.hairetsu[1]&quot;]</code>
<br />
<br />
 2次元配列を用いるのはすこし難しいですが、例だけ挙げておきます。<br />
<br />
<code class="bq">@iscript<br />
<span class="comment">//&nbsp;1次元目の要素数が&nbsp;5&nbsp;の2次元配列を作成する</span><br />
f.twodim&nbsp;=&nbsp;[]&nbsp;if&nbsp;f.twodim&nbsp;===&nbsp;void;&nbsp;<span class="comment">//&nbsp;twodim&nbsp;に1次元目の配列を作成</span><br />
for(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;5;&nbsp;i++)&nbsp;f.twodim[i]&nbsp;=&nbsp;[]&nbsp;if&nbsp;f.twodim[i]&nbsp;===&nbsp;void;<br />
<span class="comment">//&nbsp;この状態で&nbsp;f.twodim[0]&nbsp;&nbsp;f.twodim[4]&nbsp;がそれぞれ配列なので</span><br />
<span class="comment">//&nbsp;f.twodim[0][3]&nbsp;&nbsp;f.twodim[4][2]&nbsp;などと指定できる</span><br />
@endscript<br />
<br />
<span class="comment">//&nbsp;あるいは、単純にたとえば1次元目の要素数が5の配列を作成するならば</span><br />
f.twodim&nbsp;=&nbsp;[&nbsp;[],&nbsp;[],&nbsp;[],&nbsp;[],&nbsp;[]&nbsp;];<br />
<span class="comment">//&nbsp;(&nbsp;配列を&nbsp;[]&nbsp;で作成するときにその中に初期要素をカンマで区切って指定できるが、</span><br />
<span class="comment">//&nbsp;&nbsp;&nbsp;そのときに初期要素として配列を入れ子に指定する&nbsp;)</span><br />
</code>
<br />
</div></div>
<h1><a id="id271" name="id271">辞書配列</a>
</h1><div class="para"><div>
 吉里吉里2/KAG3 では辞書配列も使うことができます。<br />
 辞書配列 ( 連想配列とも呼びます ) とは、名前と、それに対応する値の組を覚えることのできる配列です。<br />
 辞書配列を使う場合は、配列と同じように、最初に <code class="inlinecode"><a id="id272" name="id272" class="targanchor"><dfn>%[ ]</dfn></a></code> を使って配列を宣言しないとなりません。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[eval&nbsp;exp=&quot;f.dict&nbsp;=&nbsp;%[]&quot;]</code>
<br />
<br />
 上記の例では、f.dict を辞書配列として使うことを宣言しています。もしすでに f.hairetsu が辞書配列だったりしたばあいの注意は配列と同じです。<br />
<br />
 辞書配列に値を代入するにも <code class="inlinecode">[ ]</code> を使います ( <code class="inlinecode">%[ ]</code> ではありません )。<code class="inlinecode">[ ]</code> 内には「名前」となるものを書きます。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[eval&nbsp;exp=&quot;f.dict['zero']&nbsp;=&nbsp;0,&nbsp;f.dict['one']&nbsp;=&nbsp;1&quot;]</code>
<br />
<br />
 上記の例では <code class="inlinecode">f.dict['zero']</code><code class="inlinecode">0</code> を、<code class="inlinecode">f.dict['one']</code><code class="inlinecode">1</code> を代入しています。普通の配列と違うのは文字列を <code class="inlinecode">[ ]</code> 内に指定することです。<br />
<br />
 表示も同様に行えます。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />zero&nbsp;:&nbsp;[emb&nbsp;exp=&quot;f.dict['zero']&quot;]&nbsp;&nbsp;&nbsp;&nbsp;one&nbsp;:&nbsp;[emb&nbsp;exp=&quot;f.dict['one']&quot;]</code>
<br />
<br />
 ちなみに <code class="inlinecode">[ ]</code> ではなく <code class="inlinecode">.</code> を使うこともできます。<code class="inlinecode">f.dict['zero']</code><code class="inlinecode">f.dict.zero</code><code class="inlinecode">f.dict['one']</code><code class="inlinecode">f.dict.one</code> と記述することができます ( ただし . の次には「予約語」や「変数名として使えない名前」が来ることはできません )。<br />
<br />
 実は KAG の <code class="inlinecode">f</code><code class="inlinecode">sf</code> といったもの自体も辞書配列で、<code class="inlinecode">f.dict</code> としたばあいは、辞書配列の中の <code class="inlinecode">'dict'</code> という名前のついた値にアクセスしていたことになります ( もちろん、<code class="inlinecode">f['dict']</code> でもアクセスできます )。<br />
</div></div>
<h1><a id="id273" name="id273">日付/時刻を得る</a>
</h1><div class="para"><div>
 現在の日付や時刻を得るには以下のようにします。<br />
<br />
<code class="bq">[iscript]<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;&nbsp;&nbsp;endscript&nbsp;の中を&nbsp;{&nbsp;&nbsp;}&nbsp;で囲むのは&nbsp;この中で宣言された変数を</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;ローカル変数にするため&nbsp;(&nbsp;そうしないとグローバル変数になる&nbsp;)</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;d&nbsp;=&nbsp;new&nbsp;Date();&nbsp;<span class="comment">//&nbsp;Date&nbsp;クラスのオブジェクトを作成</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;Date&nbsp;クラスのオブジェクトは、作成時に引数に何も指定しなければ</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;作成時点の現在時刻を保持している</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;f.year&nbsp;=&nbsp;d.getYear();&nbsp;&nbsp;<span class="comment">//&nbsp;f.year&nbsp;&nbsp;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;f.month&nbsp;=&nbsp;d.getMonth()&nbsp;+&nbsp;1;&nbsp;<span class="comment">//&nbsp;f.month&nbsp;&nbsp;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;f.date&nbsp;=&nbsp;d.getDate();&nbsp;<span class="comment">//&nbsp;f.date&nbsp;&nbsp;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;f.hours&nbsp;=&nbsp;d.getHours();&nbsp;<span class="comment">//&nbsp;f.hours&nbsp;&nbsp;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;f.minutes&nbsp;=&nbsp;d.getMinutes();&nbsp;<span class="comment">//&nbsp;f.minutes&nbsp;&nbsp;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;f.seconds&nbsp;=&nbsp;d.getSeconds();&nbsp;<span class="comment">//&nbsp;f.seconds&nbsp;&nbsp;</span><br />
}<br />
[endscript]<br />
</code>
<br />
</div></div>
<h1><a id="id274" name="id274">process</a>
</h1><div class="para"><div>
 <code class="inlinecode">kag.process</code> は、シナリオを指定した位置から実行します。<br />
 最初の引数は読み込むシナリオファイル名です。空文字列を指定すると現在のシナリオファイルが使用されます。<br />
 2番目の引数は、実行を開始するラベルです。空文字列を指定するとシナリオファイルの先頭から実行します。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />kag.process('',&nbsp;'*label2')<br />
kag.process('scenario4.ks',&nbsp;'*label5')<br />
</code>
<br />
<br />
 たとえシナリオが実行中であろうとも、強制的にそのラベルに飛ぶので注意してください。<br />
</div></div>
<h1><a id="id275" name="id275">leftClickHook, rightClickHook, keyDownHook</a>
</h1><div class="para"><div>
 KAG は、左クリックされたとき、右クリックされたとき、キーが押されたときのそれぞれの場合に、登録した関数を呼び出す機能があり、フックと呼んでいます。<br />
 フックは、複数の関数を登録できるように配列になっています。それぞれ <code class="inlinecode">kag.leftClickHook</code><code class="inlinecode">kag.rightClickHook</code><code class="inlinecode">kag.keyDownHook</code> でアクセスできるようになっています。<br />
 これらに登録した関数で true が返されると、KAG はもともとその機能に割り当てられていた機能を実行しません。たとえば、R キーが押されたとき、keyDownHook に登録された関数が true を返すと、元々の機能である「メッセージ履歴を表示する」の機能は実行されなくなります。<br />
<br />
 leftClickHook と rightClickHook には、呼び出される関数に引数はありません。<br />
 leftClickHook は、Enter キーや Space キー等でも発生します。また、マウスで選択肢などをクリックしたときには発生しません。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@iscript<br />
function&nbsp;myLeftClickHook()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;kag.process('',&nbsp;'*label');<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;<br />
}<br />
@endscript<br />
@eval&nbsp;exp=&quot;kag.leftClickHook.add(myLeftClickHook)&quot;<br />
@s<br />
<br />
*label<br />
@eval&nbsp;exp=&quot;kag.leftClickHook.remove(myLeftClickHook)&quot;<br />
やあー。<br />
@s<br />
</code>
<br />
<br />
 上記の例では、クリックされると *label が実行されます。<br />
 強制的に実行が *label に移るので注意してください。トランジションや自動移動を実行中等の場合は stoptrans や stopmove タグで実行を停止したほうが安全です。<br />
<br />
 keyDownHook は、呼び出される関数には2つ引数が渡されて、一つ目は押されたキーの仮想キーコード、二つ目はそのキーが押されていたときに同時に押されていたシフト系のキーの状態です。詳しくは吉里吉里2 SDK Help を参照してください。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@iscript<br />
function&nbsp;myKeyDownHook(key,&nbsp;shift)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(key&nbsp;==&nbsp;#'R')<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;R&nbsp;のキーが押されたら</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;kag.process('',&nbsp;'*label');<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
@endscript<br />
@eval&nbsp;exp=&quot;kag.keyDownHook.add(myKeyDownHook)&quot;<br />
@s<br />
<br />
*label<br />
@eval&nbsp;exp=&quot;kag.keyDownHook.remove(myKeyDownHook)&quot;<br />
やあー。<br />
@s<br />
</code>
<br />
</div></div>
<h1><a id="id276" name="id276">touchImages</a>
</h1><div class="para"><div>
 <code class="inlinecode">System.touchImages</code> は、画像をキャッシュに読み込みます。<br />
 詳しくは 吉里吉里2ドキュメントの System.touchImages をご覧ください。このメソッドは、たとえばなにかのウェイトで時間があいたときを利用して、画像を先読みしておく用途に使えます。<br />
 KAG で使う場合は、前景、背景画像 ( ただし key 属性を指定しないものに限る ) に対して有効です。image や img タグの storage 属性に指定するものと同じ物を storages 引数に配列にして指定してください。<br />
 第2引数は -2*1024*1024 あたりを指定しておくと良いようです。<br />
 第3引数には、待つ時間 - 200ms あたりを指定しておくと良いようです。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@resetwait<br />
@eval&nbsp;exp=&quot;System.touchImages(['24_5',&nbsp;'24_4',&nbsp;'uni',&nbsp;'24'],&nbsp;-2*1024*1024,&nbsp;800)&quot;<br />
@wait&nbsp;mode=until&nbsp;time=1000<br />
</code>
<br />
<br />
 ただし、このメソッドは、画像がキャッシュに入るということは保証しないという、不確定的なものです。ですから、絶対に画像を先に読んでおかなければいけない用途には使うべきではありません。そのような用途には後述の assignImages の項で説明する方法を使う方が確実です。<br />
</div></div>
<h1><a id="id277" name="id277">assignImages</a>
</h1><div class="para"><div>
 <code class="inlinecode">assignImages</code> は、レイヤの画像を他のレイヤにコピーします。<br />
 たとえば、<br />
<br />
<code class="inlinecode">@eval exp=&quot;kag.fore.base.assignImages(kag.fore.layers[0])&quot;</code><br />
<br />
 とすれば、表前景レイヤ 0 に読み込まれている画像を表背景レイヤにコピーすることができます。<br />
 assignImages は実際には画像のデータをコピーはせず、「コピー元とコピー先の画像が同じになった」という印を付けるだけなので高速です。デモシーンなどで、シーンの途中で画像を読み込むときのタイムロスが問題になるような場合に、あらかじめ画像を非表示の前景レイヤなどに読み込んでおいてから、必要なときに背景レイヤなどにコピーする用途に使えます。<br />
</div></div>
<h1><a id="id278" name="id278">hact タグの応用</a>
</h1><div class="para"><div>
 hact タグはメッセージ履歴をクリックしたときに任意の TJS 式を実行できるようにするもので、音声履歴 ( 声つきのゲームなどでメッセージ履歴をクリックしたときにそのメッセージに対応する音声を再生できるようにするもの ) を実装することができます。<br />
 以下は、それを実現するための例で、音声を再生するためのマクロ pv と、音声を停止するためのマクロ sv を定義するものです。<br />
<br />
<code class="bq"><span class="weak">例:</span><br />@iscript<br />
function&nbsp;stopAllVoices()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;2&nbsp;&nbsp;6&nbsp;のすべての効果音を停止する</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;for(var&nbsp;i&nbsp;=&nbsp;2;&nbsp;i&nbsp;&lt;=&nbsp;6;&nbsp;i++)&nbsp;kag.se[i].stop();<br />
}<br />
function&nbsp;playVoice(buf,&nbsp;storage)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;効果音バッファ&nbsp;buf&nbsp;にて&nbsp;storage&nbsp;を再生する</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;KAG&nbsp;がスキップ処理中の場合は処理を行わない</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;if(!kag.skipMode)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stopAllVoices();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;kag.se[buf].play(%[&nbsp;storage&nbsp;:&nbsp;storage&nbsp;]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
function&nbsp;createHistoryActionExp(buf,&nbsp;storage)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;メッセージ履歴をクリックしたときに実行する&nbsp;TJS&nbsp;式を生成する</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&quot;stopAllVoices(),&nbsp;kag.se[&quot;&nbsp;+&nbsp;buf&nbsp;&nbsp;+&quot;].play(%[&nbsp;storage&nbsp;:&nbsp;'&quot;&nbsp;+&nbsp;storage&nbsp;+&nbsp;&quot;'&nbsp;])&quot;;<br />
}<br />
@endscript<br />
@macro&nbsp;name=pv<br />
@hact&nbsp;exp=&quot;&amp;createHistoryActionExp(mp.b,&nbsp;mp.s)&quot;<br />
@eval&nbsp;exp=&quot;playVoice(mp.b,&nbsp;mp.s)&quot;<br />
@endmacro<br />
@macro&nbsp;name=waitvoices<br />
@ws&nbsp;buf=2<br />
@ws&nbsp;buf=3<br />
@ws&nbsp;buf=4<br />
@ws&nbsp;buf=5<br />
@ws&nbsp;buf=6<br />
@endmacro<br />
@macro&nbsp;name=sv<br />
@endhact<br />
@waitvoices&nbsp;cond=&quot;kag.autoMode&quot;<br />
@eval&nbsp;exp=&quot;stopAllVoices()&quot;<br />
@endmacro<br />
</code>
<br />
<br />
 createHistoryActionExp 関数では、hact タグの exp 属性に渡すための TJS 式を生成しています。ここで生成した TJS 式が実行されることになります。<br />
<br />
 このマクロを使った例は以下のようになります。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />[pv&nbsp;b=2&nbsp;s=hoge.ogg]ほげ[l][sv][r]<br />
[pv&nbsp;b=3&nbsp;s=hogera.ogg]ほげら[l][sv][r]<br />
[pv&nbsp;b=4&nbsp;s=hogemoge.ogg]ほげもげ[p][sv]<br />
</code>
<br />
</div></div>
<h1><a id="id279" name="id279">初期化時に実行されるスクリプト</a>
</h1><div class="para"><div>
 KAG はシステムのカスタマイズのために、初期化のいくつかの段階において 任意の TJS スクリプトを実行する機能があります。現バージョンでは以下の方法が用意されています。<br />
<br />
<dl>
<dt><a id="id280" name="id280" class="targanchor"><dfn>Override.tjs</dfn></a></dt>
<dd> このファイルは MainWindow.tjs が読み込まれた後に、もし存在すれば実行されます。初期状態ではこのファイルは存在しないので、新しく作成してください。</dd>
<dt><a id="id281" name="id281" class="targanchor"><dfn>AfterInit.tjs</dfn></a></dt>
<dd> すべての初期化が終わり、 first.ks が実行される直前に実行されます。このファイルも初期状態では存在しないので、新しく作成してください。</dd>
<dt><a id="id282" name="id282" class="targanchor"><dfn>追加の設定</dfn></a></dt>
<dd> Config.tjs 内には、いくつか「◆ ウィンドウや動作の追加の設定」など、「追加の設定」を記述できるところがあります。そこに記述した内容は Config.tjs の実行される各段階で実行されます。</dd></dl></div></div>
<h1><a id="id283" name="id283">メニューのカスタマイズ</a>
</h1><div class="para"><div>
 メニュー項目に、たとえば、単純な on/off だけの設定項目を追加するには、AfterInit.tjs に以下のような内容を書きます。<br />
<br />
<br />
<code class="bq"><span class="weak">例:</span><br />kag.menu.insert(kag.optionsMenu&nbsp;=<br />
&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;KAGMenuItem(this,&nbsp;&quot;効果(&amp;G)&quot;,&nbsp;0,&nbsp;void,&nbsp;false),&nbsp;2);<br />
kag.optionsMenu.stopRecur&nbsp;=&nbsp;true;<br />
<br />
kag.optionsMenu.add(<br />
&nbsp;&nbsp;&nbsp;&nbsp;kag.doTransMenuItem&nbsp;=&nbsp;new&nbsp;KAGMenuItem(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;画面切り替えを行う(&amp;T)&quot;,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function(sender)&nbsp;{&nbsp;sf.dotrans&nbsp;=&nbsp;sender.checked&nbsp;=&nbsp;!sf.dotrans;&nbsp;},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false));<br />
<br />
if(sf.dotrans&nbsp;===&nbsp;void)&nbsp;sf.dotrans&nbsp;=&nbsp;true;<br />
kag.doTransMenuItem.checked&nbsp;=&nbsp;sf.dotrans;<br />
<br />
kag.optionsMenu.add(<br />
&nbsp;&nbsp;&nbsp;&nbsp;kag.playSEItem&nbsp;=&nbsp;new&nbsp;KAGMenuItem(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;効果音を再生する(&amp;S)&quot;,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function(sender)&nbsp;{&nbsp;sf.playse&nbsp;=&nbsp;sender.checked&nbsp;=&nbsp;!sf.playse;&nbsp;},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false));<br />
<br />
if(sf.playse&nbsp;===&nbsp;void)&nbsp;sf.playse&nbsp;=&nbsp;true;<br />
kag.playSEItem.checked&nbsp;=&nbsp;sf.playse;<br />
</code>
<br />
<br />
 <code class="inlinecode">kag.menu.insert(kag.optionsMenu = new KAGMenuItem(this, &quot;効果(&amp;G)&quot;, 0, void, false), 2);</code> では、KAG のメニューバーに「効果」メニューを挿入しています。kag.optionMenu がその「効果」メニューのオブジェクトになります。insert メソッドの第2引数は、メニュー項目を挿入する位置です。<br />
 次の行ではそのオブジェクトの stopRecur を true に設定していますが、これは kag.internalSetMenuAccessibleAll で不必要なメニューアイテムの検索を行わないようにするためです。<br />
<br />
 その kag.optioneMenu に、add メソッドで子のメニュー項目を作成しています。<br />
<br />
 KAGMenuItem の第4引数は、メニューアイテムがクリックされたときに実行する式を指定します。<br />
<br />
 <code class="inlinecode">if(sf.dotrans === void) sf.dotrans = true;</code> では、sf.dotrans が void ( つまり、何も値が無い状態 ) の時に、初期値を入れています。<code class="inlinecode">kag.doTransMenuItem.checked = sf.dotrans;</code> では、メニューアイテムのチェックの初期状態を設定しています。システム変数に記録しているため、プログラムを終了しても次回に設定が引き継がれます。<br />
<br />
 あとは sf.dotrans や sf.playse に現在のメニューの状態が記録されているので、<br />
<br />
<code class="inlinecode">@playse storage=&quot;kon.wav&quot; cond=&quot;sf.playse&quot;</code><br />
 のようにして使用することができます。<br />
<br />
 応用でいろいろできると思います。<br />
</div></div>
<h1><a id="id284" name="id284">KAG用プラグインを書く</a>
</h1><div class="para"><div>
 <a id="id285" name="id285" class="targanchor"><dfn>KAGPlugin クラス</dfn></a> のサブクラスを作り、KAG に登録することで KAG の機能を拡張するプラグインを作ることができます。<br />
 サンプルが KAG の配布ファイルとともに配布されていると思うので参照してみてください。<br />
</div></div>
<script type="text/javascript" charset="UTF-8" src="documentid.js" ></script>
<script type="text/javascript" charset="UTF-8" src="postcontent.js" ></script>
</body>
</html>