スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

カテゴリ : スポンサー広告

KAGEXバグ修正まとめ

現バージョンのKAGEXで自分が見つけた限りのバグ。
とりあえず自分で直しておくことを推奨。
※明らかなバグ以外の修正も含んでます。一部バグじゃないかも。

3/28 MainWindow.tjsの修正追加
- 以下2012年 -
12/14 KAGEnvSe.tjsの修正追加
7/25 KAGEnvLevelLayer.tjsの修正追加
7/24 Initialize.tjs, Conductor.tjs, MainWindow.tjsの修正追加
5/10 KAGEnvImage.tjsの修正追加
3/5 AffineLayer.tjsの修正追加
- 以下2011年 -
12/24 TransLayer.tjsの修正追加
12//22 KAGEnvImage.tjsの修正追加
12/21 KAGEnvImage.tjsの修正追加
8/26 MainWindow.tjsの修正追加
8/21 GFX_Movie.tjsの修正追加
7/27 world.tjsの修正追加
6/28 KAGEnvImage.tjsの修正追加
5/25 kag3ex3に対応
4/22 MainWindow.tjsの修正追加
2/19 EditLayer.tjsの修正追加
2/11 MapSelectLayer.tjsの修正追加
2/3 ButtonLayer.tjsの修正追加
2/3 MessageLayer.tjsの修正追加
2/3 SliderLayer.tjsの修正追加
1/30 EditLayer.tjsの修正追加
1/30 GraphicLayer.tjsの修正追加
1/20 MainWindow.tjsの修正追加
1/16 UILoader.tjsの修正追加
1/13 SelectLayer.tjs再修正


world.tjsの308行目
                if (valueBase !== void && value.charAt(-1) == '%') {
 ↓修正
                if (valueBase !== void && value.charAt(value.length-1) == '%') {
「-1」の部分を「value.length-1」に。
314行目も全く同じです。
※kag3ex3で修正済みです。


SelectLayer.tjsの642行目
        playSE(closese, closesebuf) if (visible);
 ↓修正
//      playSE(closese, closesebuf) if (visible);
コメントアウトします。

SelectLayer.tjsの631行目
        window.insertTag("doneselect", elm !== void ? elm : %[]);
        if (setVisibleTime(false, fadeTime)) {
 ↓修正
        window.insertTag("doneselect", elm !== void ? elm : %[]);
        window.insertTag("se", %[storage:closese, buf:closesebuf]);
        if (setVisibleTime(false, fadeTime)) {
「window.insertTag("se", %[storage:closese, buf:closesebuf]);」をはさみます。


KAGEnvCharacter.tjsの619行目
            emotion.nowait = elm.nowait if elm.nowqait !== void;
 ↓修正
            emotion.nowait = elm.nowait if elm.nowait !== void;
「nowqait」→「nowait」
※kag3ex3で修正済みです。



KAGEnvCharacter.tjsの975行目
                    var operateMode = omPsNormal;
 ↓修正
                    var operateMode = omAuto;
「omPsNormal」を「omAuto」に。

UILoader.tjsの6行目
if (global.CSVParser === void) {
 ↓修正
if (typeof global.CSVParser === "undefined") {
「typeof」を追加。「void」→「"undefined"」
※kag3ex3で対応済み。



MainWindow.tjsの8544行目
            if (typeof target == "Object" && target instanceof "AffineLayer") {
                return waitLayerTransition(target, elm.canskip, +elm.wait);
            } else {
 ↓修正
            if (typeof target == "Object" && target instanceof "AffineLayer") {
                return waitLayerMotion(target, elm.canskip, +elm.wait);
            } else {
「waitLayerTransition」を「waitLayerMotion」に
※kag3ex3で削除



GraphicLayer.tjsの717行目
                    if (elm.width !== void || elm.height !== void) {
                        layer.setSize(elm.width !== void ? +elm.width : width,
                                      elm.height !== void ? +elm.height : height);
                    }
 ↓ 修正
                    if (elm.width !== void || elm.height !== void) {
                        setSize(elm.width !== void ? +elm.width : width,
                                      elm.height !== void ? +elm.height : height);
                    }
「layer.」を消去。


EditLayer.tjsの154行目
        if(Edit_vertical)
        {
            Edit_caretLayer.top = xpos;
            Edit_caretLayer.left = imageWidth - 3 - Edit_caretLayer.imageWidth;
            setAttentionPos(imageWidth - 3 , Edit_caretLayer.top);
        }
        else
        {
            Edit_caretLayer.top = 3;
            Edit_caretLayer.left = xpos;
            setAttentionPos(xpos, 3);
        }
 ↓ 修正
        if(Edit_vertical)
        {
            Edit_caretLayer.top = xpos + Edit_textOffsetY;
            Edit_caretLayer.left = imageWidth - 3 - Edit_caretLayer.imageWidth + Edit_textOffsetX;
            setAttentionPos(imageWidth - 3 , Edit_caretLayer.top);
        }
        else
        {
            Edit_caretLayer.top = 3 + Edit_textOffsetY;
            Edit_caretLayer.left = xpos + Edit_textOffsetX;
            setAttentionPos(xpos, 3);
        }
「 + Edit_textOffsetX」と「 + Edit_textOffsetY」をそれぞれ2箇所ずつ追加。


SliderLayer.tjsの132行目
                if (Slider_mouseOn) {
                    colorRect(0x_htabw, imw, tabh, clHighlight, 64);
                }
 ↓ 修正
                if (Slider_mouseOn) {
                    colorRect(0x_htabh, imw, tabh, clHighlight, 64);
                }
「x_htabw」→「x_htabh」


MessageLayer.tjsの3291行目
            object.position = +elm.position if elm.position !== void;
 ↓ 修正
            object.position = elm.position !== void ? +elm.position : 0;
「+elm.position if elm.position !== void」→「elm.position !== void ? +elm.position : 0」

MessageLayer.tjsの3044行目
            if (elm.trigger || elm.group) {
                object.loadButtons(elm.on, over, on, focus, elm.animcount, elm.animtime, true);
                object.groupName = elm.group;
            }
 ↓ 修正
            if (elm.trigger || elm.group != "") {
                object.loadButtons(on, over, on, focus, elm.animcount, elm.animtime, true);
                object.groupName = elm.group;
            }
「elm.group」→「elm.group != ""」
「elm.on」→「on」
3055行目も全く同じです。


ButtonLayer.tjsの240行目
        fillRect(00, imageWidth, imageHeight, 0);
↓ 修正
        fillRect(00, imageWidth, imageHeight, 0if !toggle;
「if !toggle」を追加。


MapSelectLayer.tjsの202行目
        buttonWidth  = elm.buttonwidth if elm.btnwidth !== void;
 ↓ 修正
        buttonWidth  = elm.buttonwidth if elm.buttonwidth !== void;
「elm.btnwidth」→「elm.buttonwidth」


EditLayer.tjsの209行目
        // クリックされた位置を割り出す
        x -= 3;
 ↓ 修正
        // クリックされた位置を割り出す
        x -= 3 + (Edit_vertical ? Edit_textOffsetY : Edit_textOffsetX);
「+ (Edit_vertical ? Edit_textOffsetY : Edit_textOffsetX)」を追加

EditLayer.tjsの593行目
                    // 背景を塗る
                    fillRect(xy, h, chw, highlightbg);
 ↓ 修正
                    // 背景を塗る
                    fillRect(x - h + Edit_textOffsetXy + Edit_textOffsetY, h, chw, highlightbg);
「x」→「x - h + Edit_textOffsetX」
「y」→「y + Edit_textOffsetY」

EditLayer.tjsの617行目
                    // 背景を塗る
                    fillRect(xy, chw, h, highlightbg);
 ↓ 修正
                    // 背景を塗る
                    fillRect(x + Edit_textOffsetXy + Edit_textOffsetY, chw, h, highlightbg);
「x」→「x + Edit_textOffsetX」
「y」→「y + Edit_textOffsetY」


MainWindow.tjsの1837行目
    function onMouseMove(x, y) {
        if (pseudoFullScreened && y == 0 && menuBarEnable && menuBarState) trackPseudoMenu();
        else if (trackTempMenuShowing) checkMenuBarHideTrackPseudoMenu();
        var hook = mouseMoveHook;
        if (hook.count > 0with (primaryLayer) callHook(hook, .cursorX, .cursorY);
        return super.onMouseMove(...);
    }
 ↓ 修正
    function onMouseMove(x, y) {
        if (pseudoFullScreened && y == 0 && menuBarEnable && menuBarState) trackPseudoMenu();
        else if (trackTempMenuShowing) checkMenuBarHideTrackPseudoMenu();
        if (isvalid this) {
            var hook = mouseMoveHook;
            if (hook.count > 0with (primaryLayer) callHook(hook, .cursorX, .cursorY);
        }
        return super.onMouseMove(...);
    }
「if (isvalid this) {」と「}」を追加。


KAGEnvImage.tjsの2533行目
        if (rgamma != void || ggamma != void || bgamma != void) {
            layer.adjustGamma(rgamma == void ? 1.0 : rgamma, 0255,
                              ggamma == void ? 1.0 : ggamma, 0255,
                              bgamma == void ? 1.0 : bgamma, 0255);
        }
 ↓ 修正
        if (rgamma !== void || ggamma !== void || bgamma !== void) {
            layer.adjustGamma(rgamma === void ? 1.0 : rgamma, 0255,
                              ggamma === void ? 1.0 : ggamma, 0255,
                              bgamma === void ? 1.0 : bgamma, 0255);
        }
3つの「!=」と「==」をそれぞれ「!==」と「===」に


world.tjsの580行目
    // 全アクション・トランジション終了時コールバック
    function onAllActionTransitionCompleted() {
        destroyTrigger.trigger();
    }
 ↓ 修正
    // 全アクション・トランジション終了時コールバック
    function onAllActionTransitionCompleted() {
        if(destroyTrigger isvalid) {
            destroyTrigger.trigger();
        }
    }
「if(destroyTrigger isvalid) {」と「}」を追加


GFX_Movie.tjsの52行目
        open(fn);
    }
 ↓ 修正
        open(fn);
        with (global.kag) {
            audioVolume = (.waveenable && .movieAudioEnable) ?
                (.wavevolume *  .movieAudioVolume) * 10 : 0;
        }

        play();
    }
「with (global.kag) { ~ }」を追加


MainWindow.tjsの10664行目
        // メッセージ窓だけ表から裏にコピー
        var messages = fore.messages;
 ↓ 修正
        // メッセージ窓だけ表から裏にコピー
        var messages = back.messages;
「fore」→「back」

KAGEnvImage.tjsの688行目
  function setRotate(param, elm) {
    rotateFrom = calcRelative(rotate, getFrom(param), 360);
    rotate     = calcRelative(rotate, getTo(param), 360);
    rotateTime = +elm.time;
    rotateAccel = +elm.accel;
    rotateNowait = elm.nowait;
  }
 ↓ 修正
  function setRotate(param, elm) {
    rotateFrom = calcRelative(rotate, getFrom(param), 360);
    rotate     = calcRelative(rotate, getTo(param), 360);
    rotateTime = elm.time;
    rotateAccel = elm.accel;
    rotateNowait = elm.nowait;
  }
「+elm.accel」の「+」を削除

KAGEnvImage.tjsの1408行目
    if (elm.slanty === voidslantx = 0;
 ↓ 修正
    if (elm.slanty === voidslanty = 0;
「slantx」→「slanty」

    if (doSlanty) {
      if (slantyFrom !== void) {
        layer.slanty = slantyFrom;
        slantyFrom = void;
      }
      if (slantxTime == 0) {
        layer.slanty = slanty;
      } else {
        layer.setSlantYTime(slanty, slantyTime, slantyAccel, slantyNowait);
      }
      doSlanty = false;
    }
 ↓ 修正
    if (doSlanty) {
      if (slantyFrom !== void) {
        layer.slanty = slantyFrom;
        slantyFrom = void;
      }
      if (slantyTime == 0) {
        layer.slanty = slanty;
      } else {
        layer.setSlantYTime(slanty, slantyTime, slantyAccel, slantyNowait);
      }
      doSlanty = false;
    }
「slantxTime」→「slantyTime」

TransLayer.tjsの215行目
  function stop() {
    done();
    layer.visible = false;
  }
 ↓ 修正
  function stop() {
    done();
    layer.visible = false;
    tlayer.visible = false;
  }
「tlayer.visible = false;」を追加。


AffineLayer.tjsの1795行目
  function setZoom(zx, zy=void) {
    //Debug.message("setZoom:" + zx + ":" + zy);
    if (zy == void) {
      zy = zx;
    }
    _zoomx = zx / 100.0;
    _zoomy = zy / 100.0;
    calcAffine();
  }
↓ 修正
  function setZoom(zx, zy=void) {
    //Debug.message("setZoom:" + zx + ":" + zy);
    if (zy === void) {
      zy = zx;
    }
    _zoomx = zx / 100.0;
    _zoomy = zy / 100.0;
    calcAffine();
  }
「zy == void」→「zy === void」


KAGEnvImage.tjsの378行目
          action.delay  = +elm.delay  if elm.time !== void;
↓ 修正
          action.delay  = +elm.delay  if elm.delay !== void;
「elm.time」→「elm.delay」


Initialize.tjsの437行目
var mp_dummy = %[], mp_target;
property mp {
  getter {
    var macroParams = mp_target ? mp_target.macroParams : void;
    return macroParams  ? /*dict*/macroParams : /*null or void*/mp_dummy;
  }
}
↓ 修正
//var mp_dummy = %[], mp_target;
//property mp {
//  getter {
//    var macroParams = mp_target ? mp_target.macroParams : void;
//    return macroParams  ? /*dict*/macroParams : /*null or void*/mp_dummy;
//  }
//}
全てコメントアウト

Conductor.tjsの202行目
    mp_target = this;
↓ 修正
    //mp_target = this;
コメントアウト

Conductor.tjsの420行目
    mp_target = void;
↓ 修正
    //mp_target = void;
コメントアウト。458行目も同じ

MainWindow.tjsの11277行目
  eval : function(elm)
  {
    // 式の評価
    Scripts.eval(elm.exp);
    return 0;
  } incontextof this,
↓ 修正
  eval : function(elm)
  {
    // 式の評価
    Scripts.eval(elm.exp,,,this);
    return 0;
  }/* incontextof this*/,
「Scripts.eval(elm.exp);」→「Scripts.eval(elm.exp,,,this);」
incontextof thisをコメントアウト

KAGEnvLevelLayer.tjsの145行目
    f.name  = name if initDisp;
↓ 修正
    f.name  = name/* if initDisp*/;
「if initDisp」をコメントアウト

KAGEnvSe.tjsの115行目
  var secommands = %[
  tagname : null
  taglist : null
  storage : setPlay incontextof this,
  play : setPlay incontextof this,
  stop : setStop incontextof this,
  fade : setFade incontextof this,
  loop : null,
  time : null,
  start : null,
  canskip : null,
  buf : null,
  filename : null,
  nosync : null,
  sync : null,
  wait : null,
  delayrun : null,
  ];
 ↓ 修正
  var secommands = %[
  tagname : null
  taglist : null
  storage : setPlay incontextof this,
  play : setPlay incontextof this,
  stop : setStop incontextof this,
  fade : setFade incontextof this,
  loop : null,
  time : null,
  start : null,
  canskip : null,
  buf : null,
  filename : null,
  nosync : null,
  sync : null,
  wait : null,
  delayrun : null,
  name : null,
  ];
「name : null,」を追加

MainWindow.tjsの3626行目
  function captureSnapshot(layer = snapshotLayer, w = scWidth, h = scHeight, hide = snapshotHideMessage) {
    with (layer) {
      .setImageSize(w, h);
      .face = dfAlpha;
      if (hide && !messageLayerHiding) setMessageLayerHiddenState(true);
      else hide = false;
      .piledCopy(00, fore.base, 00, w, h);
      if (hide) setMessageLayerHiddenState(false);
    }
  }
 ↓ 修正
  function captureSnapshot(layer = snapshotLayer, w = scWidth, h = scHeight, hide = snapshotHideMessage) {
    with (layer) {
      .setImageSize(w, h);
      .face = dfAlpha;
      if (hide && !messageLayerHiding) setMessageLayerHiddenState(true);
      else hide = false;
      setBaseLayerPos(00);
      .piledCopy(00, fore.base, 00, w, h);
      if (hide) setMessageLayerHiddenState(false);
    }
  }
「setBaseLayerPos(0, 0);」を追加

続きを閉じる▲

タグ : 吉里吉里 KAGEX

カテゴリ : KAGEX

KAGEXの文字描画について - layerExDraw.dll

KAGEXでは文字の描画方法が3種類存在します。
知らないと特定の場合に困ることになります。


1つ目は吉里吉里の機能を使った描画です。
KAGの文字描画は全てこれです。
※TJSで表現するとLayer.drawText()で描画させるやつです。
KAGEXでも基本的にはこちらが使われます。


2つ目はlayerExDraw.dllの機能を使った描画です。
「メッセージレイヤへの文字描画、名前レイヤへの文字描画、選択肢への文字描画のいずれかの場合」で、「横書き」かつ「縁取りあり」かつ「アンチエイリアスあり」の時にこちらが使用されます。

↓微妙に違う文字描画(上が吉里吉里による描画、下がlayerExDrawを使った描画、フォントはMS 明朝)
fontcmp.png
layerExDrawによる描画だと、縁取りと影を同時に描画できたり、取り消し線をひけるなど色々と便利な点もあるのですが、困る場合もあります。

それはレンダリング済みフォントが使えないということです。
↓文字化けしてしまいます
exdraw_prerend.png
簡単な解決方法としてはlayerExDraw.dllによる描画を使わないようにすればいいです。
pluginフォルダに入っているlayerExDraw.dllを削除してしまいましょう。
使っているという自覚がなければ他の箇所でも使われていないはずなので消してしまって問題ありません。
※layerExDraw.dllでインストールされていないフォントを使う方法もあるのですがここでは紹介しません。


3つ目はビットマップフォントを使った描画ですがデフォルトでは使われないので気にしなくて構いません。


ついでにTJS的な解説。
メッセージレイヤなどへの文字の描画はMessageLayer.tjsの2429行目あたりで定義されている「MessageLayerクラスのdrawTextToLayer関数」が使われます。
以下該当の関数をコピペ。
00:  function drawTextToLayer(lay, x, y, text, color) {
01:      var win = lay.window;
02:      if (typeof   win.bitmapFont == "Object" && win.bitmapFont) {
03:          var dt = win.bitmapFont.drawTextToLayer;
04:          // ビットマップフォント指定による強制描画
05:          dt(lay, x+shadowOffsetX, y+shadowOffsetY, text, shadowColor) if (shadow);
06:          dt(lay, x, y, text, color);
07:          return;
08:      }
09:      var dt = lay.drawText;
10:      if (!vertical && edge && antialiased && typeof lay.drawPathString != "undefined") {
11:          // layerExDraw拡張
12:          var tag = "__gdiplusfontapp";
13:          lay[tag] = new global.MessageLayer.GdiPlusFontApp() if (typeof lay[tag] == "undefined");
14:          lay[tag].drawText(this, lay, x, y, text, color);
15:      }
16:      else if(edge)   dt(x, y, text, color, 255, antialiased, edgeEmphasis, edgeColor, edgeExtent, 00);
17:      else if(shadow) dt(x, y, text, color, 255, antialiased, 255, shadowColor, shadowWidth, shadowOffsetX, shadowOffsetY);
18:      else            dt(x, y, text, color, 255, antialiased);
19:  }
第1引数layには文字を描画する対象となるレイヤオブジェクトがわたされます。
第2引数xは文字を描画するx座標、第3引数yがy座標です。
第4引数textは描画する文字列、第5引数colorは文字の色です。

1行目、レイヤの親ウィンドウはKAGEXのウィンドウのはずです。
2行目でウィンドウにbitmapFontが存在するか確かめていますが、自分で作らない限り存在することはありません。
※KAGEX側で勝手に作られることはありません。
なので3行目から7行目は無視されます。
8行目、レイヤのdrawText関数のショートカットを作成します。
以下dt()でレイヤのdrawText関数が使えるようになりました。
9行目、上の解説でも触れた「横書き」かつ「縁取りあり」かつ「アンチエイリアスあり」の条件をチェックしています。
verticalは縦書きの時にtrue,edgeは縁取りありの時にtrue,antialiasedはアンチエイリアスありの時にtrueになります。
※それぞれMessageLayerクラスのメンバ変数です。後述のedgeEmphasisなども同様。
最後の「typeof lay.drawPathString != "undefined"」ですが、drawPathStringとはlayerExDraw.dllを読み込んだときに定義される関数です。
「typeof lay.drawPathString != "undefined"のとき」つまり「drawPathStringが存在しているとき」にはlayerExDraw.dllが読み込まれていないと判断できます。
11行目から14行目でlayerExDrawによる描画を行っているのですが、面倒な部分なのでまた今度に回します。
16行目は10行目の条件が満たされないときに縁取りありで描画します。
edgeEmphasisが縁取りの濃さ、edgeColorが縁取りの色、edgeExtentが縁取りの厚さとなっています。
影を文字と同じ位置に描画することで縁取りのように見せかけています。
17行目は縁取りなし、影ありのときの描画です。
shadowColorは影色、shadowWidthが影の幅、shadowOffsetXが影の位置のxオフセット、shadowOffsetYが影の位置のyオフセットとなっています。
drawTextの機能をそのまま使っているだけです。
18行目は縁取りも影もなしでシンプルにdrawTextで文字を描画しています。
※余談ですがMessageLayer.tjsでは「縁取り」と「袋文字」が同じ意味で使われています。
※自分で読むときにはちょっと気をつけてください。

続きを閉じる▲

タグ : 吉里吉里 KAGEX TJS

カテゴリ : KAGEX

KAGEX講座(25) - 選択肢設定([selopt])

前回 KAGEX講座(24) - 選択肢表示([select], [seladd])
選択肢の設定を色々変えてみます。

選択肢の設定には[selopt]タグを使います。
このタグには様々な属性があります。
[selopt]の設定は設定を変えるまで何度選択肢を表示しても有効です。

ボタン設定
@道路
@selopt selectwidth=400 selectheight=80 selectbasecolor=0xFF0000 selectcolor=0x00FF00

*START
@cm
選択肢を表示します。[p][r]

@seladd text=選択肢1 target=*SELECTED
@seladd text=選択肢2 target=*SELECTED
@seladd text=選択肢3 target=*SELECTED
@select

*SELECTED
@cm
戻ります。[p][r]
@jump target=*START
selectwidthで選択肢ボタンの幅、selectheightで選択肢ボタンの高さ、selectcolorで選択肢の文字色、selectbasecolorで選択肢ボタンの色が設定できます。
selopt_1.png

領域設定
前回も言いましたが、KAGEXの選択肢はメッセージレイヤ上にではなく専用のレイヤ上に配置されます。
その専用のレイヤ(以下、領域レイヤ)の位置や大きさも設定できます。
領域レイヤは透明で見えませんが、デフォルトでは画面と同じ大きさになっています。
@道路
@selopt left=120 top=80 width=400 height=320 selectwidth=300 selectheight=50

*START
@cm
選択肢を表示します。[p][r]

@seladd text=選択肢1 target=*SELECTED
@seladd text=選択肢2 target=*SELECTED
@seladd text=選択肢3 target=*SELECTED
@select

*SELECTED
@cm
戻ります。[p][r]
@jump target=*START
leftで領域レイヤの左端、topで上端、widthで幅、heightで高さを設定します。
この画像ではわかりやすいように選択肢領域レイヤの範囲を緑色で塗っています。
selopt_2.png
領域レイヤは選択肢ボタンの表示する範囲になります。
選択肢ボタンはその数に合わせて領域レイヤの中で中央寄せされて配置されます。
選択肢ボタンの位置を1つずつ指定する必要はなく、選択肢を表示する範囲を指定するだけで勝手に配置してくれるわけです。

画像を使う
選択肢ボタンに画像を使うこともできます。
今回は↓の画像を「selopt_button.png」として使います。
「通常の状態」「ボタンが押された状態」「ボタンの上にマウスカーソルがある状態」が並んだボタン用の画像です。
selopt_button.png
@道路
@selopt graphic=selopt_button
*START
@cm
選択肢を表示します。[p][r]

@seladd text=選択肢1 target=*SELECTED
@seladd text=選択肢2 target=*SELECTED
@seladd text=選択肢3 target=*SELECTED
@select

*SELECTED
@cm
戻ります。[p][r]
@jump target=*START
画像ファイルをgraphic属性に指定します。
選択肢の文字は画像の中央に表示されます。
selopt_3.png

graphic属性以外の属性でも画像を指定できます。
↓の三枚をそれぞれ「selopt_button_normal」「selopt_button_on」「selopt_button_over」として使います。
先ほどのボタン画像を三枚に分割しただけです。
selopt_button_normal.png
selopt_button_on.png
selopt_button_over.png
@道路
@selopt normal=selopt_button_normal over=selopt_button_over on=selopt_button_on
*START
@cm
選択肢を表示します。[p][r]

@seladd text=選択肢1 target=*SELECTED
@seladd text=選択肢2 target=*SELECTED
@seladd text=選択肢3 target=*SELECTED
@select

*SELECTED
@cm
戻ります。[p][r]
@jump target=*START
normal属性に通常時の画像、over属性にマウスオーバー時の画像、on属性にボタンが押されたときの画像を指定します。
graphic属性とは異なり一枚ずつ別々に指定できるので便利です。
動作画面はgraphicの例と全く同じになります。

その他にも様々な属性があるのですが、それはまた別の場で紹介します。

次回 KAGEX講座(26) - メッセージ操作([eraftername])

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(24) - 選択肢表示([select], [seladd])

前回 KAGEX講座(23) - レイヤの拡大、縮小(zoom)
今回はKAGEXの機能を使って選択肢を表示してみます。

envinit.tjsは前回までとおなじです。
選択肢を表示するには[seladd]タグと[select]タグを使います。
@道路
@しおり show

*START
@cm
選択肢を表示します。[p][r]

@seladd text=選択肢1 storage=first.ks target=*sel1
@seladd text=選択肢2 storage=first.ks target=*sel2
@seladd text=選択肢3 storage=first.ks target=*sel3
@select

*sel1
@cm
選択肢1が選択されました[p][r]
@jump target=*START

*sel2
@cm
選択肢2が選択されました。[p][r]
@jump target=*START

*sel3
@cm
選択肢3が選択されました。[p][r]
@jump target=*START

↓実行画面
select_1.png

[seladd]タグでそれぞれの選択肢の内容を指定します。
各属性の意味は以下の通り
text選択肢に表示するテキスト
storage選択された時の飛び先ファイル名を指定します。
target選択されたときの飛び先ラベル名を指定します。
expこの選択肢が選択されたときに実行されるtjs式を指定します。
eval選択肢を表示する条件を指定します。
trueの時表示、falseの時非表示になります。
onceflag表示判定フラグを指定します。
指定した変数がfalseの時に表示、trueの時非表示になります。
この変数には選択されたときに自動的にtrueが代入されます。
※evalとonceflagを同時に指定することはできません。
※exp, eval, onceflagはこのサンプルでは未使用。

[select]タグを使うと[seladd]で指定された選択肢を表示できます。
[select]タグでは[s]タグと同じようにシナリオ進行が止まります。
このタグにもいくつか属性があります。
msgoff選択肢表示時にメッセージウィンドウを隠します。
msgon選択肢表示時にメッセージウィンドウを表示します。
storage[seldone]タグで合流する先のファイル名を指定します。
target[seldone]タグで合流する先のラベル名を指定します。
※[seldone]タグの説明はいつか気が向いたらするかもしれません。

KAGとは違い、選択肢は専用のレイヤ上に表示されます。
メッセージレイヤに配置されるボタンとは別物です。

ついでにサンプルもう一つ。
@道路
@しおり show

*START
@cm
選択肢を表示します。[p][r]

; ▼expを使ったサンプル。選択された選択肢名をf.selTextに代入します
@seladd text=選択肢1     target=*sel exp="f.selText='選択肢1'"
@seladd text=選択肢2     target=*sel exp="f.selText='選択肢2'"
; ▼選択肢3はonceflagを使ったサンプル。選択肢3は一度選択されると以後表示されません
@seladd text=選択肢3     target=*sel exp="f.selText='選択肢3'" onceflag=f.selFlag
@seladd text=フラグクリア target=*sel exp="f.selText='フラグクリア'"
; ▼msgoffを指定するとメッセージレイヤが隠されます
@select msgoff



*sel
@cm
; ▼msgoffで隠されたメッセージレイヤを[msgon]タグで表示
@msgon

[emb exp=f.selText]が選択されました。[p][r]

; ▼「フラグクリア」が選ばれたときにはf.selFlagにfalseを代入する
; ▼ こうすると選択肢3が再び表示されます
@if exp="f.selText == 'フラグクリア'"
    @eval exp="f.selFlag=false"
@endif

@jump target=*START
※[seladd]タグのstorage属性は同じファイル内なので省略しています。

細かい設定の仕方はまた次回。
次回 KAGEX講座(25) - 選択肢設定([selopt])

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(23) - レイヤの拡大、縮小(zoom)

前回 KAGEX講座(22) - アクション定義(連続アクション)
今回は画像を拡大、縮小して表示させてみます。

拡大、縮小にはzoomコマンドを使います。
考えかたはレイヤの回転とおなじです。
つまり回転原点の位置がずれないように拡大、縮小されます。
キャラクタの回転原点は中央下でした。
とりあえず使ってみます。
@道路
@しおり show
キャラクタ表示[l][r]

@しおり zoom=200
2倍に拡大[l][r]

@しおり zoom=50
半分に縮小
zoomが100のときに画像サイズそのままです。
200のときに200/100=2倍、50のときに50/100=0.5倍のサイズとなります。
zoom.png
黄色の点が回転原点、赤い線が透明部分も含めた画像サイズ、緑の線が画像の中心です。

もう一個例としてレイヤ位置をずらしてみます。
@道路
@しおり show
キャラクタ表示[l][r]

@しおり xpos=100 ypos=100
キャラクタの位置をずらす[l][r]

@しおり zoom=150
1.5倍に拡大[l][r]

@しおり zoom=80
0.8倍に縮小
zoomはパーセントで指定すると言うこともできます。
translate_zoom.png

次回 KAGEX講座(24) - 選択肢表示([select], [seladd])

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(22) - アクション定義(連続アクション)

前回 KAGEX講座(21) - アクション定義(相対アクション)
今回は連続アクションを紹介します。

連続アクションはその名のとおり、連続して実行されるアクションです。
さっそくenvinit.tjsのactionsに追加してみます。
        回転拡縮 : [
            %[
                zoom : %[
                    handler : "MoveAction",
                    value : 200,
                    time : 1000,
                ],
                rotate : %[
                    handler : "MoveAction",
                    value : 360,
                    time : 1000,
                ],
            ],
            %[
                zoom : %[
                    handler : "MoveAction",
                    value : 100,
                    time : 1000,
                ],
                rotate : %[
                    handler : "MoveAction",
                    value : 0,
                    time : 1000,
                ],
            ],
        ],
連続アクションは配列として定義します。
その配列の中に今まで書いてきたようなアクションを書けばそれが順番に実行されます。
今回は「回転拡縮」として2つのアクションを連続して実行する連続アクションを定義しています。
※もちろん3個以上連続させることもできます。
この「回転拡縮」では、1つ目のアクションで1000msかけて2倍まで拡大しながら反時計回りに1回転、それが終わると2つ目のアクションで1000msかけて等倍まで縮小しながら時計回りに1回転します。
※zoomを紹介してなかったので次回紹介予定。100の時画像の大きさそのまま、200で2倍の大きさに拡大されます。

とりあえず実行してみます。
@道路
@newlay name=カード
@カード file=card show
カード表示[l][r]
@カード 回転拡縮
連続アクション
環境レイヤでアクションを使っています。
seqAction.png

連続アクションの配列の中には、他に定義してあるアクションを書くこともできます。
たとえば第20回で定義した「回転」と「移動」を連続で実行するアクションは以下のようになります。
        回転移動 : [
            "回転",
            "移動",
        ],
「回転」アクションと「移動」アクションを連続で実行する「回転移動」アクションです。
※「回転」と「移動」のアクションがactionsの中にちゃんとあるか注意

@道路
@newlay name=カード
@カード file=card show
カード表示[l][r]
@カード 回転移動
連続アクション
これを実行するとカードが回転したあとに移動します。

連続アクションの中に連続アクションを書く、というようなことはできません。
次回 KAGEX講座(23) - レイヤの拡大、縮小(zoom)

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(21) - アクション定義(相対アクション)

前回 KAGEX講座(20) - アクション定義(絶対アクション)
今回は相対アクションを紹介します。

アクションには「絶対アクション」と「相対アクション」の二種類があります。
前回まで使ってきたアクションはすべて絶対アクションです。

「絶対アクション」では、アクション終了時に対象のプロパティの値が変化します。
例えば「@しおり xpos=100 time=100」と書くとxposの値は100に変化します。

一方の「相対アクション」ではアクションさせてもプロパティの値は変化しません。

とりあえず使ってみます。
前回書いたenvinit.tjsのactionsに↓のアクションを追加します。
        横ぶるぶる : %[
            left : %[
                handler : "RandomAction",
                vibration : 10,
                waittime : 50,
                time : 1000,
            ],
        ],
handlerに指定した"RandomAction"は相対アクションの一つです。
"RandomAction"では、「waittime」に指定した時間ごとに「vibration」の範囲でランダムに振動します。
この「横ぶるぶる」だと1000msのあいだ、10msごとにleftが-10~+10の範囲で変化します。
※アクションではxposではなくleftで指定するので注意。

@道路
@しおり show
キャラクタ表示[l][r]
@しおり 横ぶるぶる
相対アクション
@s
これを実行するとキャラクタが横に振動します。
相対アクションなので、1000msのあいだ振動してアクションが終わると元の位置に戻ります。

time指定を省略すると自分で止めるまでアクションしつづけるようになります。
        ぶるぶる : %[
            left : %[
                handler : "RandomAction",
                vibration : 10,
                waittime : 50,
            ],
            top : %[
                handler : "RandomAction",
                vibration : 10,
                waittime : 50,
            ],
        ],
ついでにtopのほうも振動させるようにしました。
time属性は書いていません。
@道路
@しおり show
キャラクタ表示[l][r]
@しおり ぶるぶる
相対アクション[l][r]
@しおり stopaction
アクションをキャンセル
stopactionを使ってキャンセルするか、改ページがあるまでアクションしつづけます。
※nowait属性をつけないと改ページでアクションはキャンセルされます。

ついでなのでnowaitをつけたアクションも定義してみます。
        縦ぶるぶる : %[
            top : %[
                handler : "RandomAction",
                vibration : 10,
                waittime : 50,
            ],
            nowait : true,
        ],
縦に振動するアクションです。
「nowait : true」でnowait指定します。
※前回は使いませんでしたが絶対アクションでも同じです。
@道路
@しおり show
キャラクタ表示[l][r]
@しおり 縦ぶるぶる
相対アクション[p][cm]

改ページでもアクションしつづけます[p][cm]

ぶるぶるぶるぶる[p][cm]

@しおり stopaction
アクションをキャンセル

次回 KAGEX講座(22) - アクション定義(連続アクション)

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(20) - アクション定義(絶対アクション)

前回 KAGEX講座(19) - イベントレイヤ(events)
今回はアクションの定義の仕方を紹介します。

とりあえずenvinit.tjs。
%[
    // 中略
    actions : %[
        回転 : %[
            rotate : %[
                handler : "MoveAction",
                value : 90,
                time : 1000,
            ],
        ],
        移動 : %[
            left : %[
                handler : "MoveAction",
                value : 100,
                time : 1000,
            ],
            top : %[
                handler : "MoveAction",
                value : 100,
                time : 1000,
            ],
        ],
    ],
];
前回までのenvinit.tjsにactionsの部分を追加しておいてください。
アクションは「actions」の中に定義します。
アクションとしてここでは「回転」と「移動」を定義しています。

定義の中にはアクションで動かしたいパラメータ名(ここでは「rotate」「left」「top」)に対してその動き方をそれぞれ定義します。

「handler」にはアクションハンドラを指定します。
アクションハンドラを変えることでアクションの種類を変えることができます。
ハンドラに"MoveAction"を指定すると、「value」で指定した値まで直線的に変化します。
「回転」アクションの場合はrotateの値が90まで変化します。
「移動」アクションの場合はleftとtopの値が100まで変化します。
※アクション定義ではxpos,yposではなくleft,topを使います。
※それぞれの意味はxpos,yposと同じです。
「time」にはアクションの時間をms単位で指定します。
ここでは1000msとしています。

使い方は↓のようになります。
@道路
@しおり show
キャラクタ表示[l][r]
@しおり 回転
回転アクション[l][r]
@しおり rotate=0
rotateを戻す。[l][r]
@しおり 移動
移動アクション


アクションハンドラには"PathAction"というのもあります。
これは"MoveAction"に似ていますが、valueに複数の値を指定することができます。
「移動」の定義の次に連続回転を定義してみます。
        連続回転 : %[
            rotate : %[
                handler : "PathAction",
                value : "90,-90,0",
                time : 2000,
            ],
        ],
値には「,(コンマ)」で値を区切って指定します。
この「連続回転」ではrotateの値が2000msかけて90→-90→0と変化します。

使い方は↓のようになります。
@道路
@しおり show
キャラクタ表示[l][r]
@しおり 連続回転
回転アクション

次回 KAGEX講座(21) - アクション定義(相対アクション)

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(19) - イベントレイヤ(events)

前回 KAGEX講座(18) - 環境レイヤ(newlay, dellay)
今回はイベントレイヤを紹介します。
その名のとおりイベント絵(一枚絵/スチル/イベントCG)を表示するのに使います。

ev01.png
使う画像は↑(ev01.png)
※今回は簡単なので準備するまでもないかも。

イベントレイヤを使うにはenvinit.tjsに登録しておく必要があります。
%[
    // 中略
    events : %[
        イベント絵 : %[
            image : "ev01",
        ],
    ],
];
envinit.tjsの最後にeventsをつけ加えておきます。
イベント画像は背景とおなじように定義します。
stagesではなくeventsになっているだけです。
ただし背景の定義で使った「TIME」は使えないので注意してください。
ここでは「イベント絵」の画像として「ev01」を定義しています。

イベントレイヤを操作するには[event]タグを使います。
@道路
背景表示[l][r]
@event イベント絵
イベント絵表示[l][r]
@event hide
イベント絵消去
「event」の後に定義名を書けばそのイベント絵が表示されます。
かくすときにはhideを使います。

省略記法も使えます。
@道路
背景表示[l][r]
@イベント絵
; @event イベント絵 と同じ
イベント絵表示[l][r]
@event hide
; @イベント絵 hide と書きたいところだが何故か駄目
イベント絵消去
[イベント絵 hide]だと消えたり消えなかったりします。
明らかにバグですが直し方は知りません。
[event hide]を使っていれば困ることはないと思います。

ちなみにイベント絵は背景を更新すると勝手に消えてくれます。
@道路
背景表示[l][r]
@イベント絵
イベント絵表示[l][r]
@道路
; 背景を更新するとイベントレイヤは消える
イベント絵消去


前回の環境レイヤとおなじく、今まで紹介してきたその他のコマンドも使えます。
@道路
背景表示[l][r]
@イベント絵 fade=1000
イベント絵フェード表示[l][r]
@イベント絵 rotate=360 time=1000
イベント絵回転[l][r]
@イベント絵 xpos=100 ypos=100 time=1000
イベント絵移動[l][r]
@event hide fade=1000
イベント絵フェード消去[l][r]


これで第三回でだしたワールド拡張のレイヤは全て紹介したことになります。
随分おそくなってしまいましたが……。

次回 KAGEX講座(20) - アクション定義(絶対アクション)

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(18) - 環境レイヤ(newlay, dellay)

前回 KAGEX講座(17) - キャラクタ表示(顔分離立ち絵)
今回は環境レイヤについて紹介します。
キャラクタ以外の画像を表示させるときに使います。

card.png
表示する画像は↑を使います(card.png)。
※画像の著作権はsakanoにあります。好きに使ってもらって構いません。

環境レイヤを使うにはまずはレイヤを作る必要があります。
@newlay name=カード
@カード file=card show
カードを表示しました。

@dellay name=カード
レイヤを消去しました。
環境レイヤを作るには[newlay]タグを使います。
「name」属性に指定した文字列がそのレイヤの名前になります。
レイヤを作ったあとはキャラクタレイヤと同じように名前で操作することができるようになります。
ここでは「カード」がレイヤの名前になっています。

作ったレイヤは[dellay]タグを使うことで削除することができます。

環境レイヤのデフォルトの回転原点は画像中央、表示原点はウィンドウ中央となっています。
つまり画像中央とウィンドウ中央が重なるので、環境レイヤはウィンドウ中央に表示されます。

環境レイヤで使えるコマンドをいくつか紹介します。
file:表示する画像を指定します。
width:レイヤの幅を指定します。
height:レイヤの高さを指定します。
color:レイヤの塗りつぶす色を指定します。
tile:表示する画像を指定しますが、画像は指定されたサイズ(width,height)でしきつめられます。

スクリプト例
@newlay name=カード
@カード file=card show
カードを表示しました。[l][r]

@カード tile=card width=640 height=480
画面いっぱいにカードをしきつめます。[l][r]

@カード color=0xFFFF0000 width=640 height=480
レイヤを不透明度FF(255)、色FF0000(赤)でぬりつぶします。[l][r]

@dellay name=カード
レイヤを消去しました。
これを実行すると以下のようになります。
envlayer.png

「color」属性には0xAARRGGBB形式で色を指定するので注意してください。
AAの部分に塗りつぶす際の不透明度を指定します。
RRGGBBの部分はKAGで色を指定する際と同じように指定します。
AAがFF(10進数で255)ならRRGGBBに指定した色そのままで塗りつぶされます。
AAの数値を低くするとその分薄く色が塗られます。
@道路
背景表示[l][r]

@newlay name=カード
@カード color=0x66FFF0000 width=640 height=480 show
レイヤを不透明度66(102)、色FF0000(赤)でぬりつぶします。[l][r]

@dellay name=カード
レイヤを消去しました。
不透明度66(10進数で102)で塗りつぶすと、背景が透けて見えています。↓
envlayopcolor.png

今まで紹介してきた、キャラクタレイヤで使えていたコマンドは環境レイヤでも大体使えます。
@newlay name=カード
@カード file=card show
レイヤを表示しました。[l][r]

@カード rotate=360 time=2000
レイヤ回転[l][r]

@カード xpos=100 ypos=100 time=1000
レイヤ移動[l][r]

@カード opacity=128 time=1000
レイヤ半透明[l][r]

@カード hide fade=1000
レイヤトランジション[l][r]

@dellay name=カード
レイヤを消去しました。


次回 KAGEX講座(19) - イベントレイヤ(events)

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(17) - キャラクタ表示(顔分離立ち絵)

前回 KAGEX講座(16) - レイヤの回転(rotate)
ワールド拡張の立ち絵には「顔分離型立ち絵」と「顔合成型立ち絵」の2種類があります。
今回は顔分離型立ち絵の定義の仕方を紹介します。
顔合成型立ち絵については第5回を参照。

※付属リファレンス(world_inst.txt)だと「表情合成方式」と「表情統合方式」になっていました。
※顔とポーズで画像2枚 = 顔分離型立ち絵 = 表情合成方式
※顔とポーズで画像1枚 = 顔合成型立ち絵 = 表情統合方式
※わかりづらいですがまあ名前なんてどうでもいいです。

とりあえず今回使用する画像↓をダウンロードしてfgimageフォルダにでも入れておいてください。
http://www.mediafire.com/?bryar6c3g37djyq
のっぺらぼうの画像4枚と顔の画像4枚が入っています。
内部的にはのっぺらぼうの画像を土台としてその上に顔の画像をのせることとなります。

画像の名前の規則は以下のようにしています。

土台の画像:CHAR_POSE_DRESS_LEVEL.png
CHARの部分にキャラクタの名前を入れます。
ここではしおり1キャラしかいないのでsiori固定です。
POSEの部分にポーズごとの文字を入れます。
ここではn(通常)とs(直立)の2種類のポーズがあります。
DRESSの部分に服装ごとの文字を入れます。
ここではs(夏制服)とw(冬制服)です。
LEVELの部分に表示レベルごとの数字を入れます。
ワールド拡張における表示レベルについてはまだ解説していないので0固定にしておきます。
※具体的には以下の4つのファイルが入っています。
※siori_n_s_0.png(しおり/通常/夏制服/レベル0)
※siori_n_w_0.png(しおり/通常/冬制服/レベル0)
※siori_s_s_0.png(しおり/直立/夏制服/レベル0)
※siori_s_w_0.png(しおり/直立/冬制服/レベル0)

顔の画像:CHAR_POSE_FACE_LEVEL.png
CHAR,POSE,LEVELは土台の画像のそれとおなじです。
FACEの部分には表情ごとの文字を入れます。
ここではk(喜)とd(怒)の2種類の表情があります
※具体的には以下の4つのファイルが入っています。
※siori_n_k_0.png(しおり/通常/喜/レベル0)
※siori_n_d_0.png(しおり/通常/怒/レベル0)
※siori_s_k_0.png(しおり/直立/喜/レベル0)
※siori_s_d_0.png(しおり/直立/怒/レベル0)
今回はポーズが違っても表情を使いまわせるのでおなじ画像が2枚入っていたりしますが、一般的にはポーズごとに表情の画像もかえる必要があるはずなので敢えてわけています。
表情の画像のサイズはその土台の画像のサイズとおなじにする必要があります。

以上の規則をenvinit.tjsで表現すると以下のようになります。
    characters : %[
        しおり : %[
            poses : %[
                通常 : %[
                    image : "siori_n_DRESS_0",
                    faceImage : "siori_n_FACE_0",
                    dresses : %[
                        夏制服 : "s",
                        冬制服 : "w",
                    ],
                    defaultDress : "s",
                    faces : %[
                         : "k",
                         : "d",
                    ],
                    defaultFace : "k",
                ],
                直立 : %[
                    image : "siori_s_DRESS_0",
                    faceImage : "siori_s_FACE_0",
                    dresses : %[
                        夏制服 : "s",
                        冬制服 : "w",
                    ],
                    defaultDress : "s",
                    faces : %[
                         : "k",
                         : "d",
                    ],
                    defaultFace : "k",
                ],
            ],
            defaultPose : "通常",
        ],
    ],
charactersの部分のみ抜粋です。
その他の部分はyoffsetも含めておなじなので前回までのenvinit.tjsのcharactersの部分を書きかえてください。

顔合成型とちがう部分としては、imageに土台の画像、faceImageに顔の画像のファイル名を定義します。
※faceImageのIは大文字なので気をつけてください。大文字と小文字は区別されます。
※内部的にはfaceImageが定義されていると顔分離型、定義されていないと顔合成型として処理されます。
imageのDRESSの部分が夏制服のときは「s」、冬制服の時は「w」に置きかえられます。
faceImageのFACEの部分が喜のときは「k」、怒の時は「d」に置きかえられます。
顔合成型の時とおなじなので詳しくは解説しません。

表示のさせ方は顔合成型と全くおなじです。
実際にksファイルを書くときには顔合成型や顔分離型を意識せずにすむようになっています。
@道路
@しおり show
キャラクタ表示[l][r]

@しおり  tr_face
表情変更[l][r]
@しおり 直立 tr_pose
ポーズ変更[l][r]
@しおり  tr_face
もっかい表情変更[l][r]

@しおり 冬制服
服装変更[l][r]
@しおり 通常 tr_pose
ポーズ変更
※ついでにトランジションもつけてますが、なくてももちろん大丈夫です。

もしかしたら表示が少しおかしくなっているかもしれません。
KAGEXを一部修正しておくことを推奨します。
systemフォルダに入っている「KAGEnvCharacter.tjs」の943行目付近
                    var operateMode = omPsNormal;
※検索してさがしてください。
これを以下のように変更します。
                    var operateMode = omAuto;
omPsNormalをomAutoにして上書き保存するだけです。
※厳密にチェックしてませんが自分は変更しても今のところ大丈夫な感じ……。
次回 KAGEX講座(18) - 環境レイヤ(newlay, dellay)

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(16) - レイヤの回転(rotate)

前回 KAGEX講座(15) - アクション機能を使ってみる
今回はrotate属性の説明をします。
rotate属性を使うと画像を回転させることができます。

さっそくスクリプト↓
@道路
@しおり show
キャラクタ表示[l][r]
@しおり ypos=240
わかりやすいように位置調整[l][r]

@しおり rotate=90
反時計まわりに90度回転[l][r]
@しおり rotate=0
角度を戻す[l][r]
@しおり rotate=-90
時計まわりに90度回転[l][r]
rotate属性には、回転角度を度数法の度の数値で指定します。
360度で1回転のあれです。当然ですが回転していない状態が0度です。
プラスの値を指定すると反時計まわり、マイナスの値を指定すると時計まわりの角度になります。
また、回転する際には回転原点の位置がずれないように回転します。
キャラクタレイヤのデフォルトの回転原点の位置はレイヤ中央下でした(下の画像の黄色の点)。
rotate1.png

せっかくなので回転原点位置をかえて回転させてみます。
@道路
@しおり show
キャラクタ表示[l][r]

@しおり afx=center afy=center

回転原点を中央にする[l][r]
@しおり ypos=240
わかりやすいように位置調整[l][r]

@しおり rotate=90
回転原点をレイヤ中央にして時計まわり90度回転

回転原点を中央にするとレイヤの表示位置もずれます。(「@しおり afx=center afy=center」のところ
rotate2.png

240px上にずらします。(「@しおり ypos=240」のところ
rotate3.png

時計まわりに90度回転させます。(「@しおり rotate=90」のところ
rotate4.png

もちろん背景についても使えます。
@道路
@しおり show
キャラクタ表示[l][r]

@道路 rotate=180
背景を反時計まわりに180度回転

前回説明せずに使いましたがアクションも使えます。
@道路
@しおり show
キャラクタ表示[l][r]

@しおり rotate=360 time=2000
2000msかけて反時計まわり360度まで回転[l][r]
@しおり rotate=-360 time=4000
4000msかけて時計まわり360度まで回転
2度目の回転「@しおり rotate=-360 time=4000」は時計周りに2回転するので気をつけてください。
反時計まわり360度の角度から時計まわり360度の角度になるには720度回転する必要があるからです。
rotate5.png
次回 KAGEX講座(17) - キャラクタ表示(顔分離立ち絵)

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(15) - アクション機能を使ってみる

前回 KAGEX講座(14) - カメラ機能
KAGEXではアクション機能が使えます。
アクション機能を使うと簡単に画像を動かしたりまわしたりいろいろできます。
今回はとりあえず使ってみます。

@道路
@しおり show
キャラクタを表示しました。[l][r]

@しおり xpos=-100 time=1000
1000msかけて-100まで移動。
time属性で指定した時間をかけて指定位置まで移動します。

sync, nosync属性も使えます。
@道路
@しおり show
キャラクタを表示しました。[l][r]

@しおり xpos=-100 time=1000 sync
1000msかけて-100まで同期アクション。[l][r]

@しおり xpos=0 time=1000 nosync
1000msかけて0まで非同期アクション。[l][r]
デフォルトでは非同期動作(nosync)となっています。

非同期動作でも改ページ([p]タグ)ではキャンセルされてしまいます。
@道路
@しおり show
キャラクタを表示しました。[l][r]

@しおり xpos=-300 time=10000 nowait
10秒かけて移動。[p][cm]
アクション終了前に改ページされるとキャンセルされます。

これを防ぐにはnowait属性を使います。
@道路
@しおり show
キャラクタを表示しました。[l][r]

@しおり xpos=-300 time=10000 nowait
10秒かけて移動。[p]
[cm]
nowait属性をつけると大丈夫です。

アクションをキャンセルしたい場合にはstopaction属性を使用します。
@道路
@しおり show
キャラクタを表示しました。[l][r]

@しおり xpos=-300 time=10000
10秒かけて移動。[l][r]

@しおり stopaction
アクションをキャンセルしました。
stopactionではnowait属性が使われているアクションもキャンセルできます。

time属性はxpos以外の属性にも使えます。
@道路
@しおり show
キャラクタを表示しました。[l][r]

@しおり xpos=100 ypos=100 time=1000
1000msかけて移動。[l][r]

@しおり opacity=128 time=1000
1000msかけて半透明にする。[l][r]

@しおり rotate=360 time=1000
ぶん回してみる。[l][r]

@しおり xpos=0 ypos=0 opacity=255 rotate=-360 time=1000
いろいろ変えてみる。
opacity属性は説明してませんが透明度を指定する属性です(0~255)。
KAGで設定できるものと同じなので説明しません。
rotate属性も説明してませんが画像を回転させるのにつかいます。
こちらはそのうち説明します。

アクションが終わる前に同じ属性に対してアクションさせようとすると、前のアクションは途中で止まってしまいます。
@道路
@しおり show
キャラクタを表示しました。[l][r]

@しおり xpos=350 time=10000
10秒かけてxpos変化[l][r]

@しおり xpos=0 time=10000
移動途中に再びxposを変化させてみる
アクションがキャンセルされるわけではありません。
「キャンセル」という場合にはアクション終了時の値になります。
ここではアクションの途中の値でアクションが「止まって」しまいます。
↓の例と比較すると違いがわかると思います。
@道路
@しおり show
キャラクタを表示しました。[l][r]

@しおり xpos=350 time=10000
10秒かけてxpos変化[l][r]

@しおり stopaction
@しおり xpos=0 time=10000
キャンセルしてからxposを変化させてみる
アクションが途中で止まるような作りにはしないほうがいいと思います。

ちなみに背景に対しても使えます。
@道路
@しおり show
キャラクタを表示しました。[l][r]

@道路 xpos=100 ypos=100 time=1000
背景のアクション。

次回 KAGEX講座(16) - レイヤの回転(rotate)

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

KAGEX講座(14) - カメラ機能

前回 KAGEX講座(13) - レイヤ表示位置(xpos, ypos)
今回はカメラ機能について解説します。

camerax, cameray
前回説明したxpos, yposでは個別のレイヤの表示位置をずらすことが出来ました。
camerax, camerayを使うと画面を見るカメラの位置をずらすことができます。
※もちろん実際にカメラがあるわけではありませんがそのような効果が得られます。
@道路
@しおり show 
キャラクタを表示[l][r]

@env camerax=100 cameray=100
カメラ位置を右に100、上に100ずらしました。
camerax、cameray属性は[env]タグで使います。
cameraxにマイナスの値を指定すると左、プラスの値を指定すると右にカメラ位置がずれます。
camerayにマイナスの値を指定すると下、プラスの値を指定すると上にカメラ位置がずれます。

camerazoom
camerazoom属性ではカメラをズームすることができます。
@道路
@しおり show 
キャラクタを表示[l][r]

@env camerazoom=200
カメラを2倍ズームにしました。
camerazoom=100で等倍(変化なし)です。
200を指定すれば2倍にズームアップされ、50を指定すれば1/2にズームバックされます。

camerazoomで拡大または縮小表示するときには、画面中央がずれないように拡大又は縮小されます。
あくまでカメラを操作していると思ってください。
↓camerazoom=500(5倍にズーム)してみる図
camerazoom_a.png

当然ですがcamerax,cameray属性でカメラ位置がずれたときにも同じです。
@道路
@しおり show 
キャラクタを表示[l][r]

@env camerax=100 cameray=100
カメラ位置を右に100、上に100ずらしました。[l][r]

@env camerazoom=500
カメラを5倍ズームにしました。
これを実行すると以下のようになります。
camerazoom_b.png

※カメラを動かしているというのが何だかわかり辛いのでもう1個サンプルおいておきます。
※time属性についてはまだ説明してませんがそのうちします。
※とりあえずコピペして実行してみてください。
@道路
@しおり show 
キャラクタを表示[l][r]

@env camerax=100 cameray=100 time=1000
カメラ位置を右に100、上に100ずらしました。[l][r]

@env camerazoom=500 time=1000
カメラを5倍ズームにしました。[l][r]

@env camerax=0 cameray=0 time=1000
カメラ位置をもとに戻しました。

次回 KAGEX講座(15) - アクション機能を使ってみる

続きを閉じる▲

タグ : 吉里吉里 KAGEX 講座

カテゴリ : KAGEX

HistoryLayer差し替えメモ

KAGEXのHistoryLayerを差し替えるためのメモ。
もっとKAGWindowとずぶずぶだと思ってたけど割と分離してた。
頑張って書き換えより最初から作った方が早いんじゃないか。

必須メンバ変数
外部から参照されていて、ないとエラーになるもの。
*name
レイヤの名前。書き込みのみ。
KAGWindowのコンストラクタで生成直後に書き込まれる。
HistoryLayerのコンストラクタでも書き込んでる。謎。
KAGWindowのほう要らん。

*visible
履歴が表示されているか。読み込みのみ。
何でこっち見てんだ。historyShowingの方見ろや。
これもKAGWindowの方書き換えた方がよさげ。

※kag3ex3でhistoryShowing見るように修正

*parent
履歴レイヤの親レイヤ。書き込みのみ。
履歴表示直前にkag.fore.baseに書き換えられる。
KAGEXのプライマリレイヤの方にしとけば必要なす。

*absolute
履歴レイヤの絶対位置。書き込みのみ。
履歴表示直前とreorderLayersで書き換えられる。
これもいらん気がする。

*storeState
履歴を栞に保存するか。読み込みのみ。
true固定でええがな。

*everypage
ページ単位での履歴表示を行うか。読み込みのみ。
internalRestoreFlagsの中で動作分岐してる。
やるならHistoryLayerの中で分けるべき。
そもそもstoreStateがtrue固定なら要らんっぽい。

必須メンバ関数
外部から呼び出されていて、ないとエラーになるもの。
*コンストラクタ(win, par)
KAGWindowのコンストラクタで生成される。

*store(ch)
渡された文字列chを履歴に記録する。

*reline()
改行を履歴に記録する。

*repage()
改ページを履歴に記録する。

*save()
保存すべきデータを返す。(storeStateがtrueの時のみ)
あとは勝手にKAGWindowが保存してくれる。

*load(dic)
dicにsave()で返したデータが渡される。
それを使って履歴の状態を復帰。(storeStateがtrueの時のみ)

*clear()
履歴の内容をクリア。
[clearhistory]タグで呼ばれる。

*setOptions(elm)
elmには[history]タグの属性が渡される。
履歴のオプションを設定。
output、enabled属性はKAGWindowの方で処理されるので必要なし。

*dispInit()
履歴を表示する。

*dispUninit()
履歴を非表示にする。

*beginIndent()
インデントを設定。
[indent]タグで呼ばれる。

*endIndent()
インデントを解除。
[endindent]タグで呼ばれる。

*setNewAction(action)
履歴アクションを登録。
[hact]タグから呼ばれる。
ワールド拡張の[dispname]タグ、[dispnameVoice]タグからも呼ばれる。

*clearAction()
履歴アクションの登録を終了(クリア)。
[endhact]タグなどから呼ばれる。
ワールド拡張の[afterline][afterpage]タグからも呼ばれる。

*windowMouseWheel(shift, delta, x, y)
履歴表示中にホイールが回転した場合KAGWindowから呼ばれる。

オプションメンバ関数
定義されている場合のみ呼ばれる。
*fontUpdate(hs)
hs : 履歴表示中か
kag.chDefaultAntialiasedかkag.chDefaultFaceが変更されたときに呼ばれる。

*autoReline()
メッセージレイヤにおいて自動改行があった場合に、store()の直前に呼ばれる。

*preIndent()
セリフ部分の自動インデントがあるときに呼ばれる。

*storeName()
ワールド拡張で名前が描画されたときにstore()の代わりに呼ばれる。

↓デフォルトのKAGEXで差し替えてもエラーが出ないヒストリーレイヤもどき
/*
 *  HistoryLayerの最少構成的な何か
 *  ・履歴の内容はtargetLayerに表示
 *  ・最大で9行分までてきとーに表示。
 *  ・最後に描画された行は履歴には描画されない。
 *  ・インデント/履歴アクション非対応
 *  ・ホイール回転で履歴を隠す。
 */

class MyHistoryLayer {
    property parent {
        setter(par) {
            targetLayer.parent = par;
        }
    }
    property visible {
        getter() {
            return targetLayer.visible;
        }
    }
    property absolute {
        setter(abs) {
            targetLayer.abs = abs;
        }
    }
    property name {
        setter(name) {
            targetLayer.name = name;
        }
    }
    property storeState {
        getter() {
            return true// 常にtrue
        }
    }
    property everypage {
        getter() { // 呼ばれることはないはず
            System.inform("everypageが呼ばれました");
            return false// 常にfalse
        }
    }
    
    var targetLayer; // 履歴を表示するレイヤオブジェクト
    var data = []; // 履歴データ(改行ごとに記録、リングバッファ)
    var curLine = 0// 現在の行(履歴データの最後尾)
    var maxLine = 10// 履歴に一度に表示できる行数(履歴データの大きさ)
    
    function MyHistoryLayer(win, par) {
        // コンストラクタ
        with (targetLayer = new Layer(win, par)) {
            // ターゲットレイヤの設定
            .setImageSize(par.width, par.height);
            .setSizeToImageSize();
        }
    }    
    function finalize() {
        // デストラクタ
        invalidate targetLayer if targetLayer !== void;
    }
    
    function store(ch) {
        // 文字列chを履歴に記録。
        data[curLine] += ch;
    }    
    function reline() {
        // 改行を履歴に記録。
        curLine = (curLine+1)%maxLine; // curLineを1つ進める。
        data[curLine] = "";
    }    
    function repage() {
        // 改ページを履歴に記録。
        reline(), reline(); // 改行を2回入れる
    }
    
    function save() {
        // 保存するデータを返す。
        if (!storeState) { return void; } // storeStateは常にtrue。一応
        else {
            var dic = %[];
            (dic.data = []).assignStruct(data);
            dic.curLine = curLine;
            return dic;
        }
    }    
    function load(dic) {
        // 履歴の状態の復帰
        if (!storeState) { return; } // storeStateは常にtrue。一応
        else if (dic !== void) {
            data.assignStruct(dic.data);
            curLine = dic.curLine;
        }
    }
    
    function clear() {
        // 履歴の内容をクリア。
        with (targetLayer) { .fillRect(00, .width, .height, 0x99000000); } // 塗りつぶし
        data.clear();
        curLine = 0;
    }
    
    function dispInit() {
        // 履歴を表示する
        with (targetLayer) {
            // 履歴の内容を描画
            .fillRect(00, .width, .height, 0x99000000); // 塗りつぶし
            var h = 20// 文字描画高さ
            for (var i = curLine+1; i != curLine; i = (i+1)%maxLine) {
                .drawText(20, h, data[i], 0xFFFFFF); // 文字描画
                h += .font.getTextHeight(data[i]) + 2// 次の行の描画高さを計算
            }
            // 履歴表示
            .visible = true;
        }
    }    
    function dispUninit() {
        // 履歴を非表示にする
        targetLayer.visible = false;
    }
    
    function setOptions(elm) {
        // 履歴のオプションを設定
    }
    
    function beginIndent() {
        // インデントを設定
    }
    function endIndent() {
        // インデントを解除
    }
    
    function setNewAction(action) {
        // 履歴アクションを登録
    }    
    function clearAction() {
        // 履歴アクションの登録おわり
    }
    
    function windowMouseWheel(shift, delta, x, y) {
        // 表示中にホイールが回転した
        kag.hideHistory(); // 履歴を非表示にする
    }
}

続きを閉じる▲

タグ : 吉里吉里 KAGEX TJS

カテゴリ : KAGEX

最新記事
カテゴリ

openclose

記事一覧
Twitter
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。