// AnimationLayer.tjs - アニメーションを行うレイヤ // Copyright (C)2001-2003, W.Dee 改変・配布は自由です /* -- 2つのアニメーションの種類 ---------------------------------------------  KAGにアニメーションをさせるためには2つの種類があります。  一つは「セル画像」を用いるセルを基本としたアニメーションで、この場合、 「ベース画像」の上に「セル画像」の各部分を切り取って順次貼り付けるような感 じでアニメーションを行います。  もう一つは、KAG 3.05 beta 3 から使用可能になった クリッピングを基本とした アニメーション方法で、この場合はセル画像は必要ありません。  image タグに clipleft, cliptop, clipwidth, clipheight の4つの属性があり ますが、(概念的には)これを順次変えてやることで、大きな画像の一部分を順次表 示するようなアニメーションを行います。表示する画像を何枚も横に並べ、それを 順次表示するような用途に向いています。  負荷はクリッピングを基本としたアニメーション方式のほうが軽いです。デモ シーンにおいて、レイヤの全域を書き換えるようなアニメーションを行う場合はク リッピング方式のアニメーションのほうが良いでしょう。  逆に、目パチ、口パクのような用途にはセル方式のアニメーションの方が小回り が利いて使いやすいでしょう。 -- セル方式のアニメーションの記述の仕方 -----------------------------------  まず、アニメーションを行わせるためには、「ベース画像」と「セル画像」が必 要になります。ベース画像はアニメーションの下地となる画像です。セル画像はア ニメーションの「部品」が並べてある画像です。ベース画像の上にアニメーション 画像を部分的にコピーして重ねていくという方法を用います。  ベース画像は image タグで読み込まれます (ここで用いるベースとは、KAGの背 景レイヤの base とは違う意味です )。セル画像は、アニメーション定義ファイル 内の loadcell タグで読み込みま。  アニメーション定義ファイルは、ベース画像とファイルが同じで、拡張子が asd のテキストファイルです。  アニメーション定義ファイルは KAG の文法で記述しますが、タグ体系は KAG の ものとは異なります。  アニメーションセグメントを用いない、簡単なアニメーションならば、KAG の System フォルダにある LineBreak や PageBreak が参考になると思います。  アニメーションセグメントを用いたサンプルは現在の所、吉里吉里ソースの中の environ/win32/kag3/scenario/animtest.ks にあります。 -- セグメント -------------------------------------------------------------  セグメントは、一組のベース画像、セル画像、asdファイルで、複数のアニメー ションを同時進行させるための仕組みです。  セグメントにはレイヤごとに 0 番から始まる番号がついています。  セグメント 0 は特殊なセグメントでデフォルトセグメントと呼ばれ、画像の読 み込みとともに実行が自動的に始まるセグメントです。system フォルダにある LineBreak や PageBreak はこのデフォルトセグメントのみを使用しています。簡 単なアニメーションならばこれだけで十分だと思います。  口パクや目パチなどを一つの画像で行いたい場合、複数のセグメントを扱わなけ ればなりません。たとえば、目パチはデフォルトセグメントで常時アニメーション させておき、口パクはシナリオの制御によって開始させたり、停止させたりする、 という用途です。  セグメントに対するアニメーションのスタートは KAG の通常のシナリオの animstart で行います。animstart は任意の ( デフォルトセグメント以外の ) セ グメントでアニメーションを開始します。  animstart タグの loop 属性が true のとき、このアニメーションはループして いないといけません。自動的にループするわけではないので、ループするように記 述しなければなりません。  ループしていなくてもエラーになるわけではありませんが、栞を保存して読み込 んだときに正しく画像が再現されない可能性があります。 また、栞が読み込まれるときは、loop=true を指定した場合のみにアニメーション が再開されますが、かならず animstart で指定したasdファイルのラベルの最初か ら実行が始まります。  loop=false の時は、アニメーションはしますが、最終的に s タグで停止しなけ ればなりません。また、[s] タグで停止したときには、ベース画像と同じ状態に戻っ てなければなりません。単発のアニメーションを行わせたいときはこれを使います。  animstop はアニメーションを停止させますが、停止を待ちません。実際はアニメー ションが停止するためには @home タグを通過する必要があります。  wa は任意のセグメントのアニメーションの終了を待ちます。デフォルトセグメン トのアニメーションもまつことができます。animstart で loop=falseを指定したと きや、animstop でアニメーションを停止させた時のみ有効です。他の場合で wa を 指定した場合は永遠に待つことになってしまいます。  栞に保存される情報は、アニメーションがどのセグメントでどの開始ラベルから 始まったかという情報のみで、どのコマ位置まで進んでいるか、は記録されません。  また、ループ中のアニメーションのみが、栞を読み込んだときにアニメーション が再開されます。 -- クリッピング方式のアニメーションの記述の仕方 ---------------------------  クリッピング方式でアニメーションを行う場合は、セル方式で行うときと異なり、 コマ画像が横並びになった画像を一枚用意します。  たとえば、320x240 の画面で8枚の画像でアニメーションを行うならば、 2560×240 の画像を用意します ( 2560 = 320 * 8 )。  画像を読み込むときは、最初のコマが表示されるように image タグを記述します。  たとえば、 @image storage=anim page=fore layer=0 mode=rect clipleft=0 cliptop=0 clipwidth=320 clipheight=240  となります。  asd ファイルには、横に並んだ各コマ画像が順次表示されるように記述します。 セル画像は用いないので、loadcell タグを記述する必要はありません。  たとえば、 @wait time=80 @clip left=320 top=0 @wait time=80 @clip left=640 top=0 @wait time=80 @clip left=960 top=0 @wait time=80 @clip left=1280 top=0 @wait time=80 @clip left=1600 top=0 @wait time=80 @clip left=1920 top=0 @wait time=80 @clip left=2240 top=0 @wait time=80 @s  見てお気づきかとは思いますが、実際は横に並んでいる必要はありません。  縦に並んでいても良いですが、png などで圧縮するときは横並びになっていた方 が高い圧縮率を得られます。  クリッピング方式のアニメーションでは、栞には、そのレイヤがどのようにアニ メーションを行っていたかの情報が保存されません。次の「栞を保存可能なラベル」 を通過するまでには、そのレイヤに別の画像を読み込むなどして、クリッピング方 式のアニメーションの情報を無効にしてください。 -- asdファイル中タグの説明 ------------------------------------------------ ■ loadcell ・属性 storage (省略可) 読み込むセル画像ファイル名を指定します ・説明  このタグはセル方式のアニメーションを行うときのみに使用します。  loadcell タグはアニメーションのセル画像を読み込みます。セル画像を読み込ま なければアニメーションができないので、asd ファイルの先頭には必ず記述します。 storage 属性が省略された場合は、ベース画像のファイル名に _a を付加した画像 が読み込まれます。  asd ファイルの先頭に記述しさえすれば OK で、セグメントの開始ラベルの次に 記述する必要はありません。 ■ loop ・属性 (なし) ・説明  このタグはセル方式のアニメーションを行うときのみに使用します。  loop タグは、データがループを行うことを宣言するためのタグです。  このタグを宣言したからと言って自動的にデータがループするわけではありませ ん。ループするように記述してください。  このタグは、各セグメントでのループの開始を行う場合の、セグメントの入り口 のラベルの次あたりに記述してください。最初のデフォルトセグメントの場合は loadcell の次あたりで OK です。 ■ copy ・属性 dx 転送先x座標 dy 転送先y座標 sx 転送元x座標 sy 転送元y座標 sw 幅 sh 高さ ・説明  このタグはセル方式のアニメーションを行うときのみに使用します。  セル画像からベース画像にコピーを行います。 ■ wait ・属性 time 待ち時間(ms) ・説明  指定時間ウェイトをとります。  通常は、copy タグと wait タグの繰り返しになります。 ■ jump, if/endif, eval, iscript/endscript  KAG のシナリオと同様です。  ただし、複数が並列して実行される物なので、変数を操作する場合は使用する変 数が重ならないようにするなど、注意してください。 ■ s ・属性 (なし) ・説明  通常の KAG と同じように、そこで実行を停止します。  アニメーションがループしない場合は、loop タグを書かずに、このタグで 停止させてください。  画像が読み込まれた時点ではアニメーションをしたくないのならば、loadcell タ グの直後に s タグを書いて停止させてください。 ■ home ・属性 (なし) ・説明  このタグはセル方式のアニメーションを行うときのみに使用します。  animstop タグを指定した場合に停止する場所です。これを書かないと animstop では停止できません。animstop タグを使う場合は、ループの途中に必ず一カ所以上 記述してください。 ■ clip ・属性 left クリッピングを行う左端位置 top クリッピングを行う上端位置  このタグはクリッピング方式のアニメーションを行うときのみに使用します。  image タグにおける clipleft と cliptop 属性の値の効果と同じで、クリッピン グを行う位置を指定します。  クリッピングの幅と高さは変更できませんので、image タグで指定した幅と高さ を変えることはできません。 */ class AnimationConductor extends BaseConductor { var owner; var number; // このコンダクタの番号 var looping = false; var startLabel = ""; var stopping = false; // ストップを待っている状態か var running = false; // 実行中か function AnimationConductor(owner) { super.BaseConductor(); // スーパークラスのコンストラクタを呼ぶ ignoreCR = true; // CR は無視 debugLevel = tkdlNone; // debugLevel = tkdlVerbose; this.owner = owner; } function finalize() { owner = void; // owner への参照を切る super.finalize(...); } function onStop() { // 実行停止 var elm = %[]; elm.context = this; owner.s(elm); // s タグを呼ぶ } function onTag(obj) { // タグが実行されるとき var func = owner[obj.tagname]; if(func == void) { dm(Storages.extractFileName(curStorage) + " : 未知のタグ : " + obj.tagname); return 0; } obj.context = this; return func(obj); } function onScript(script) { // iscript が実行されるとき try { Scripts.exec(script, scriptname, lineofs); } catch(e) { throw new Exception(scriptname + " の 行 " + lineofs + " から始まる" " iscript ブロックでエラーが発生しました。" "\n( 詳細はコンソールを参照してください )\n" + e.message); } return true; } function assign(src) { // src の状態をこのオブジェクトにコピー super.assign(src); looping = src.looping; startLabel = src.startLabel; stopping = src.stopping; running = src.running; } } class AnimationLayer extends KAGLayer { var Anim_cellLayer; // セルレイヤ var Anim_segments = []; // セグメントごとのコンダクタ var Anim_storageName; // アニメーションデータファイル名 var Anim_loadParams = void; // 読み込み時に指定されたパラメータ var Anim_partialImageInfo = void; // 画像の部分追加読み込みのパラメータ var Anim_interrupted = false;// 中断中か var Anim_defaultFontInfo = %[]; function AnimationLayer(win, par) { // AnimationLayer コンストラクタ super.KAGLayer(...); // スーパークラスのコンストラクタを呼ぶ Anim_defaultFontInfo.face = font.face; // デフォルトのフォント Anim_defaultFontInfo.height = font.height; // デフォルトのフォントサイズ Anim_segments[0] = new AnimationConductor(this); // デフォルトのコンダクタ Anim_segments[0].number = 0; } function finalize() { clearAnim(); // アニメーション情報のクリア invalidate Anim_segments[0]; // デフォルトのコンダクタを無効化 Anim_loadParams = void; Anim_partialImageInfo = void; super.finalize(...); } function clearImage(process = true) { // 表示を不可視(不可視にできれば)にし、 // レイヤをクリアする // 必要に応じてオーバーライドすること if(process) { visible = false; setSize(32, 32); setImageSize(32, 32); face = dfBoth; fillRect(0, 0, 32, 32, 0); type = ltCoverRect; } } function freeImage() { // 画像を解放 clearAnim(); clearImage(); Anim_loadParams = void; Anim_partialImageInfo = void; } function clearAnim() { // アニメーション情報のクリア // アニメーションセグメントのクリア // 各セグメント(デフォルトをのぞく)の削除 for(var i = Anim_segments.count -1; i>=1; i--) { var seg = Anim_segments[i]; invalidate Anim_segments[i] if seg !== void; } Anim_segments.count = 1; // デフォルトのセグメントの停止 Anim_segments[0].stop(); // アニメーションセルレイヤの破棄 invalidate Anim_cellLayer if Anim_cellLayer !== void; Anim_cellLayer = void; } function loadAnimInfo(segment, label) { // アニメーション情報を指定セグメントに読み込み、実行開始 // segment=セグメント番号 label=開始ラベル(空文字列ならば最初から) // Anim_storageName に入っているファイル名のファイルを読み込む if(Anim_storageName == '') throw new Exception( (Anim_loadParams !== void ? Anim_loadParams.storage + "に対する" : "") + "アニメーション情報がありません"); var seg; if(Anim_segments[segment] === void) { Anim_segments[segment] = seg = new AnimationConductor(this); seg.number = segment; // 新しいセグメント用にコンダクタを作成 } else { // セグメントは停止 (seg = Anim_segments[segment]).stop(); } seg.startLabel = label; seg.stopping = false; seg.running = true; seg.clearCallStack(); seg.interrupted = Anim_interrupted; seg.loadScenario(Anim_storageName); if(label != '') seg.goToLabel(label); seg.startProcess(true); } function startAnim(elm) { // elm に従ってアニメーションを開始する loadAnimInfo(+elm.seg, elm.target); } function stopAnim(segment) { // segment で行われているアニメーションを停止する var seg = Anim_segments[segment]; if(seg === void) return; // 停止できない seg.stopping = true; } function canWaitAnimStop(segment) { // segment のアニメーションの終了を待てるかどうか var seg = Anim_segments[segment]; if(seg === void) return false; // まてない if(!seg.running) return false; // 実行中でないので待てない if(seg.looping && !seg.stopping) return false; // ループ指定されていてかつストップ待ちでないのでまてない return true; } function loadImages(elm) { // loadImages オーバーライド // elm は読み込み情報 if(elm === void) { freeImage(); return; } Anim_loadParams = %[]; (Dictionary.assign incontextof Anim_loadParams)(elm); // パラメータを待避 // アニメーション情報をクリア clearAnim(); // 追加画像読み込みの情報をクリア Anim_partialImageInfo = void; // 画像を読み込む super.loadImages(elm.storage, elm.key); // 色補正 applyColorCorrection(this, elm); // フリップ var ud, lr; if(elm.flipud !== void && +elm.flipud) { // 上下反転 flipUD(); ud = true; } else { ud = false; } if(elm.fliplr !== void && +elm.fliplr) { // 左右反転 flipLR(); lr = true; } else { lr = false; } // クリッピング if(elm.clipleft !== void) { // クリッピングが指定されている width = +elm.clipwidth; height = +elm.clipheight; var cl = elm.clipleft; if(lr) cl = imageWidth - cl - width; var ct = elm.cliptop; if(ud) ct = imageHeight - ct - height; imageLeft = -cl; imageTop = -ct; } else { setSizeToImageSize(); } // レイヤモード { var mode = ltTransparent; if(elm.mode !== void) { if(elm.mode == "rect") mode = ltCoverRect; else if(elm.mode == "add") mode = ltAdditive; else if(elm.mode == "sub") mode = ltSubtractive; else if(elm.mode == "mul") mode = ltMultiplicative; else if(elm.mode == "dodge") mode = ltDodge; else if(elm.mode == "darken") mode = ltDarken; else if(elm.mode == "lighten") mode = ltLighten; else if(elm.mode == "screen") mode = ltScreen; } type = mode; } // 可視不可視、位置、不透明度、インデックス if ( elm !== void && elm.pos !== void ) { // ポジションに従って位置を決定 left= window.scPositionX[elm.pos] - width \ 2; top = window.scHeight - height; } else { if(elm.left !== void) left = +elm.left; if(elm.top !== void) top = +elm.top; } if(elm.visible !== void) visible = +elm.visible; if(elm.opacity !== void) opacity = +elm.opacity; absolute = +elm.index if elm.index !== void; // アニメーション情報があれば、読み込む Anim_storageName = Storages.getPlacedPath( Storages.chopStorageExt(elm.storage) + ".asd"); if(Anim_storageName != '') { // アニメーション情報があった! // アニメーション情報をデフォルトのコンダクタに読み込む loadAnimInfo(0, ''); // ついでにアニメーション開始(もし開始できれば) } } function loadPartialImage(elm) { // 部分追加読み込みを行う // この読み込みメソッドは レイヤそれ自体の // 色調補正、フリップなどの設定に従う // (従って pimage タグ自体には色調補正や // フリップ関連の属性はない ) // pimage タグでは、時間をずらして順次部分画像を読み込み、 // アニメーションを行っていくような用途には向いていない // ( そのような場合はアニメーション機能を使うべき ) if(elm.tagname === void) elm.tagname = "pimage"; // カラーキーの決定 var key; if(elm.key !== void) { // key 指定がある key = elm.key; } else { // key 指定がない if(Anim_loadParams !== void) key = Anim_loadParams.key; // loadParams の方の key を使う else key = void; } // 一時使用用のレイヤを得る var temp = window.temporaryLayer; // 一時レイヤに画像を読み込む temp.loadImages(elm.storage, key); var lr = false, ud = false; if(Anim_loadParams !== void) { // 一時レイヤに対して色調補正 if(elm.mode === void || elm.mode == 'pile' || elm.mode == 'copy') { applyColorCorrection(temp, Anim_loadParams); } // フリップ if(Anim_loadParams.flipud !== void && +Anim_loadParams.flipud) { // 上下反転 temp.flipUD(); ud = true; } if(Anim_loadParams.fliplr !== void && +Anim_loadParams.fliplr) { // 左右反転 temp.flipLR(); lr = true; } } var dx = +elm.dx; var dy = +elm.dy; var sx = +elm.sx; var sy = +elm.sy; var sw = elm.sw === void ? temp.imageWidth : +elm.sw; var sh = elm.sh === void ? temp.imageHeight : +elm.sh; if(ud) { // 上下反転 dy = imageHeight - dy - sh; sy = temp.imageHeight - sy - sh; } if(lr) { // 左右反転 dx = imageWidth - dx - sw; sx = temp.imageWidth - sx - sw; } if(elm.mode !== void && elm.mode == "copy") { // コピー face = dfBoth; copyRect(dx, dy, temp, sx, sy, sw, sh); } else { // 重ね合わせ var orgface = face; var opa = elm.opacity === void ? 255 : +elm.opacity; switch(elm.mode) { case 'add': face = dfMain; operateRect(dx, dy, temp, sx, sy, sw, sh, omAdditive, opa, true); break; case 'sub': face = dfMain; operateRect(dx, dy, temp, sx, sy, sw, sh, omSubtractive, opa, true); break; case 'mul': face = dfMain; operateRect(dx, dy, temp, sx, sy, sw, sh, omMultiplicative, opa, true); break; case 'dodge': face = dfMain; operateRect(dx, dy, temp, sx, sy, sw, sh, omDodge, opa, true); break; case 'darken': face = dfMain; operateRect(dx, dy, temp, sx, sy, sw, sh, omDarken, opa, true); break; case 'lighten': face = dfMain; operateRect(dx, dy, temp, sx, sy, sw, sh, omLighten, opa, true); break; case 'screen': face = dfMain; operateRect(dx, dy, temp, sx, sy, sw, sh, omScreen, opa, true); break; case 'pile': default: face = (type == ltTransparent) ? dfBoth : dfMain; pileRect(dx, dy, temp, sx, sy, sw, sh, opa); break; } face = orgface; } // Anim_partialImageInfo に情報を追加 if(Anim_partialImageInfo === void) Anim_partialImageInfo = []; var info = %[]; (Dictionary.assign incontextof info)(elm); Anim_partialImageInfo.add(info); return 0; } function drawReconstructibleText(elm) { // (ロード時に)再現可能な形式でテキストを描画する // x, y = 座標 // text = 描画する文字列 // face = フォント, 省略時は デフォルトフォント名 // size = フォントサイズ, 省略時はデフォルトフォントサイズ // color = 色 (デフォルト=0xffffff) // italic = 斜体かどうか (デフォルト=false) // shadow = 影つきかどうか (デフォルト=true) // edge = 縁取りかどうか (デフォルト=false) // shadowcolor = 影の色 (デフォルト=0) // edgecolor = 縁取りの色 (デフォルト=0) // bold = 太字にするかどうか (デフォルト=0) // vertical = 縦書きかどうか (デフォルト=false) // antialiased = アンチエイリアスするか (デフォルト=true) // angle = 描画角度 (デフォルト=縦書きならば2700, そうでなければ0) if(elm.tagname === void) elm.tagname = "ptext"; var vertical = elm.vertical === void ? false : +elm.vertical; with(font) { var face = elm.face === void ? Anim_defaultFontInfo.face : elm.face; if(vertical) face = '@' + face; .face = face; .height = elm.size === void ? Anim_defaultFontInfo.height : +elm.size; .angle = elm.angle === void ? vertical ? 2700:0 : +elm.angle; .italic = elm.italic === void ? false : +elm.italic; .bold = elm.bold === void ? false: +elm.bold; } var edge = elm.edge === void ? false : +elm.edge; var shadow = elm.shadow === void ? true : +elm.shadow; var color = elm.color === void ? 0xffffff : +elm.color; var antialiased = elm.antialiased === void ? true : +elm.antialiased; var orgface = face; face = (type == ltTransparent) ? dfBoth : dfMain; var x = +elm.x; var y = +elm.y; if(edge) { var bcolor = elm.edgecolor === void ? 0 : +elm.edgecolor; drawText(x, y, elm.text, color, 255, antialiased, 512, bcolor, 1, 0, 0); } else if(shadow) { var bcolor = elm.shadowcolor === void ? 0 : +elm.shadowcolor; drawText(x, y, elm.text, color, 255, antialiased, 255, bcolor, 0, 2, 2); } else { drawText(x, y, elm.text, color, 255, antialiased); // 文字 } face = orgface; // Anim_partialImageInfo に情報を追加 if(Anim_partialImageInfo === void) Anim_partialImageInfo = []; var info = %[]; (Dictionary.assign incontextof info)(elm); Anim_partialImageInfo.add(info); return 0; } function applyColorCorrection(layer, param) { // layer に対して色補正を行う if(param.grayscale !== void && +param.grayscale) layer.doGrayScale(); layer.adjustGamma( param.rgamma, param.rfloor, param.rceil, param.ggamma, param.gfloor, param.gceil, param.bgamma, param.bfloor, param.bceil); if(param.mcolor !== void) { // 色重ね合わせ var orgface = layer.face; layer.face = dfMain; layer.colorRect(0, 0, layer.imageWidth, layer.imageHeight, +param.mcolor, +param.mopacity); layer.face = orgface; } } property interrupted { // すべてのセグメントに interrupted を設定する getter() { return Anim_interrupted; } setter(x) { if(Anim_interrupted != x) { for(var i = Anim_segments.count -1; i>=0; i--) { Anim_segments[i].interrupted = x; } Anim_interrupted = x; } } } function assign(src) { // レイヤの情報をコピー // ただし 位置、透明度、サイズ、レイヤ内画像位置はコピーしない // (コピーしたい場合は KAGLayer.assignVisibleState を呼ぶこと) super.assignImages(src); // アニメーションセルレイヤのコピー if(src.Anim_cellLayer !== void) { if(Anim_cellLayer === void) Anim_cellLayer = new global.KAGLayer(window, this); Anim_cellLayer.assignImages(src.Anim_cellLayer); } else { invalidate Anim_cellLayer if Anim_cellLayer !== void; Anim_cellLayer = void; } // 画像読み込み情報のコピー if(src.Anim_loadParams !== void) { Anim_loadParams = %[]; (Dictionary.assign incontextof Anim_loadParams)(src.Anim_loadParams); } else { Anim_loadParams = void; } // 部分追加読み込みの情報のコピー if(src.Anim_partialImageInfo !== void) { var destinfo; Anim_partialImageInfo = destinfo = []; var srcinfo = src.Anim_partialImageInfo; var count = srcinfo.count; for(var i = 0; i < count; i++) { var info = %[]; (Dictionary.assign incontextof info)(srcinfo[i]); destinfo.add(info); } } else { Anim_partialImageInfo = void; } // アニメーションセグメント情報のコピー // いったん現在のセグメントをクリア for(var i = Anim_segments.count -1; i>=0; i--) { var seg = Anim_segments[i]; invalidate Anim_segments[i] if seg !== void; } var srcanimseg = src.Anim_segments; // エイリアス var src_animseg_count = srcanimseg.count; var animseg = Anim_segments; // エイリアス for(var i = src_animseg_count-1; i>=0; i--) { var seg = srcanimseg[i]; animseg[i] = void; if(seg !== void) { animseg[i] = new AnimationConductor(this); animseg[i].number = i; animseg[i].assign(seg); // アサイン } } animseg.count = src_animseg_count; // その他 Anim_interrupted = src.Anim_interrupted; Anim_storageName = src.Anim_storageName; } function store() { // 情報を辞書配列に記録 var dic = super.store(); // 読み込みパラメータ if(Anim_loadParams !== void) { dic.loadParams = %[]; (Dictionary.assign incontextof dic.loadParams)(Anim_loadParams); } else { dic.loadParams = void; } // 部分追加読み込みの情報 if(Anim_partialImageInfo !== void) { var dest; dic.partialImageInfo = dest = []; var src = Anim_partialImageInfo; var count = src.count; for(var i = 0; i < count; i++) { var info = %[]; (Dictionary.assign incontextof info)(src[i]); dest.add(info); } } else { dic.partialImageInfo = void; } // アニメーションセグメントの情報を記録 dic.segments = []; var animseg = Anim_segments; // エイリアス var animsegcount = animseg.count; for(var i = 1; i