2007/04/10(火)

文字描画レイヤ

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 23:18:30

ようやくお披露目、前からちょくちょく話に出してた文字描画レイヤです。
KAGのMessageLayerは非常によく出来ているのですが、いくつか痒い所に手が届かない部分があったので、それなら自分で作ってしまえと。
……のはずだったんですが、シナリオ側の記述で結構フレキシブルに使えるんですよねMessageLayer。^^;
例えば、リファレンスを鵜呑みにして複数文字にルビを振ろうとすればこういう感じになるんですが……

[ruby text="ひ"]向[ruby text="まわ"]日[ruby text="り"]葵

実際はこんなやり方で均等にルビを配置する事が可能なわけで。
あと、KAGはベタテキストを1文字ずつに分解してchタグとして解釈するので、袋文字を利用している場合に罫線『──』のような、2文字以上がひと続きとなる文字が現れると、2文字目の縁取り部分が前の文字に重なってしまい、文字が途切れてしまうという問題があったんですが(Fateで顕著だった気がする)、これも[ch text="──"]と書いてやる事で簡単に回避できちゃうんですよねー。

というわけで、今回紹介する文字描画レイヤのアドバンテージは、FontクラスのプロパティやdrawText()の引数が全てシナリオファイル側の記述で制御できる、という点くらいに……。
このレイヤクラスは、chなどで文字が送られてきてもすぐに描画するわけではなく、一旦partsと呼ばれるバッファに溜め込み、描画したいタイミング(クリック待ちの直前など)でprint()メソッドを呼び出して一気に描画する、という方法を取っています。
エロゲをインストールしたら即効で文字速度を最速に設定してしまう人用。^^;
まあ、KAGParserがテキストを1文字ごとに分解して吐き出すので、タグハンドラの書き方次第で1文字ごとの描画も全然いけますが。

(続きを読む…)

2007/04/07(土)

KAGで複数文字に渡るルビを振る

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 23:52:23

ああなんて事。
KAGでこれが出来ると判ってたら、一からシステム作ろうとは思わなかったかも……。

KAGシステムのrubyタグは、タグが現れた次の1文字に対してルビが振られる、……とリファレンスには書かれています。
まあ間違いでは無いんですが。KAGParserはベタテキストを1文字ずつに分解してchタグとして解釈するので。
でも実際は、内部的には次の1文字ではなく、次に現れるchタグに対してルビが振られる、という挙動を採っています。
なので、こういう風に書いてやると……

[ruby text="ひ ま わ り"][ch text="向日葵"]

あはは……ほら……3文字に渡ってルビが振られるじゃん……。
マクロ化するとこう。

;マクロ定義
@macro name=mruby
@ruby text=%r
@ch text=%text
@endmacro

;使用例
[mruby r="ひ ま わ り" text="向日葵"]

ルビの文字間隔は半角スペースや全角スペースなどで調節する必要がありますが、これで少なくとも文字間隔が不揃いになるという事はなくなります。はぁ……。
近いうちにKAYの作った文字描画レイヤ紹介します。
複 数 文 字 に 渡 る ル ビ を 振 る こ と が 可 能
なやつ。

2007/03/25(日)

正規表現リテラルの罠

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 01:49:49

文法的に間違っていないにも拘らず、syntax errorが投げられてしまう例。

//2.28 stableにて確認
var regexp = //正規表現オブジェクト
    /[a-z]+/;

どうやら、行コメントを書いて、改行後すぐに正規表現リテラルが来ると例外が発生するようです。
前回のエントリと合わせて、公式の掲示板あたりに報告した方がよさそうかな?

(2007/03/28追記)

報告済み。修正済み。安定版は時期リリース版で対応かな?
http://kikyou.info/tvp/bbs/bbs.cgi?mode=&action=treeall&num=10082

2007/03/21(水)

プライマリレイヤにltAddAlphaを指定すると……

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 02:46:39

2.28安定版での話です。
とりあえず、以下のテストスクリプトを実行してみて下さい。

class TestWindow extends Window {
    var timer;
    var primary;
    var counter = 0; 

    //コンストラクタ
    function TestWindow() {
        super.Window();
        borderStyle = bsSingle;
        innerSunken = false;
        setInnerSize(300, 300);
        visible = true; 

        timer = new Timer(createLayer, "");
        timer.capacity = 1;
        timer.interval = 50;
        add(timer); 

        primary = new Layer(this, null);
        primary.setPos(0, 0);
        primary.setSize(300, 300);
        primary.fillRect(0, 0, 300, 300, 0xffffffff);
        primary.type = ltAddAlpha;          //●
        primary.visible = true;
        add(primary);
    } 

    //デストラクタ
    function finalize() {
        super.finalize();
    } 

    function createLayer() {
        if(++counter > 100) {
            timer.enabled = false;
            return;
        }
        var layer = new Layer(this, primary);
        layer.setPos(0, 0);
        layer.setSize(150, 300);
        layer.visible = true;
        add(layer);
    }
} 

var win = new TestWindow();
win.timer.enabled = true;

↓こちらからダウンロードできます。
startup.tjs

50msごとにウィンドウの左半分にレイヤを1枚ずつ重ねていき、100枚になったら停止する、というだけのものです。
これは……バグなのかなあ。仕様? まあ、プライマリレイヤなんだから完全不透明なレイヤタイプを使えという事ですかね。

(2007/03/28追記)

公式の掲示板でW.Deeさんよりご回答いただきました。

http://kikyou.info/tvp/bbs/bbs.cgi?mode=&action=treeall&num=10082

というわけで、演算誤差が原因との事でした。まあ、プライマリレイヤはltOpaqueで十分だと思うので、特に問題はない、かな?
プライマリ以外は……どうだろう。多分大丈夫だと思うけど。

2007/03/13(火)

外部からスーパークラスのプロパティを参照する

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 02:31:22

以下のような感じで、外部からオブジェクトのスーパークラスのプロパティにアクセスする事が可能です。
TJS2おもろい。

//例えば、Layerクラスを継承したSubLayerというクラスからインスタンスを生成する
var layer = new SubLayer(window, parent);   

*(&Layer.width incontextof layer) = 100;                 //setterを呼び出す
System.inform(*(&Layer.absolute incontextof layer));     //getterを呼び出す

メソッドなんかだと、Dictionaryクラスのメソッドを呼び出すのにincontextof演算子はほぼ必須ですので、見慣れたもんですが、プロパティの方はあまりこういう呼び出し方はしないのではないでしょうか。
先に紹介した縦書きレイヤクラスなんかで威力を発揮すると思います。
実際に運用する際に、それが縦書きレイヤなのかそうじゃないのかわからない状態でオーバーライドしてしまったプロパティ(widthやheightなど)を参照したい場合。
スタンダードに行くなら、instanceof演算子を使って処理を分けるのが普通でしょうが、似たような処理を2回も書くのはめんどくさいですもんねえ。^^;

2007/03/08(木)

Layerクラスのオブジェクト生成直後のプロパティ一覧

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 19:49:57

値が不定のものもあるので、ぴったりこの通りというわけではないです。まあ、参考程度に。
2.28 stableにて書き出しました。

(続きを読む…)

2007/03/04(日)

Fontクラスのプロパティをオーバーライドしてみる

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 02:45:13

吉里吉里のFontクラスは特殊な位置付けで、ユーザが任意にnewする事が出来ません。
ただし、Layerクラスのfontプロパティとしてぶら下がっているFontオブジェクトのメンバに対しては、上書きが可能のようです。
これを利用して、こんな珍妙なLayerクラスが作れます。

(続きを読む…)

2007/03/01(木)

メンバの有無の確認方法

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 21:27:00

TJS2で、Dictionaryクラスのオブジェクト(辞書配列)にメンバが存在するかどうかは

var dic = %[];
if(dic.hoge === void) {
    System.inform("無いよっ");
}

このようにvoidとの比較で出来ますが、これと同じ事を他のオブジェクトでやると例外が出ます。

var obj = new Date();
if(obj.hoge === void) {     //この行で例外が発生する。
    System.inform("無いってば!");
}

じゃあ辞書配列以外のオブジェクトでメンバの有無はどうやって確認するんだという話ですが、typeof演算子を使います。

var obj = new Date();
if(typeof obj.hoge == "undefined") {        //これならOK。
    System.inform("無いってば!");
}

この仕様は結構はまりやすそう(というかはまった)なので、気を付けましょう。
typeof演算子による比較は辞書配列でも使えますので、はまりそうだなという人は、比較の際は必ずtypeof演算子を使う、という風に決めておいた方がいいかも。

というお話。

2007/02/24(土)

ゴミ箱クラス

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 08:40:21

作ってみた。オブジェクトの処理に困ったらとりあえずここにポイ。
う~ん、あんまり使わないか?

(続きを読む…)

2007/02/20(火)

超簡単なAnimationLayer

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 19:55:33

アニメーションGIF的な簡素なAnimationLayerを作ってみました。

(続きを読む…)

2007/02/18(日)

KAGで文字参照

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 18:29:33

珍しくKAGネタ。
かなり需要のある内容だと思うし、それでなくてもKAG周りは色んなサイトでしゃぶりつくされてると思うんで、探せば同じ内容のTIPSなんか簡単に見つかるのかも知れませんが……一応、俺様用メモという事で。^^;

つーわけで、KAGで©や♡などの特殊な文字を表示させる方法です。こんな感じ。

ひぐらしのなく[ch text="&'\\x2661'"]頃に[r]
ぶっちゃけJASRA[emb exp="'\\xa9'"]って、法律に守られてる分893より性質悪いよね。

@chと@embのどちらでも可ですが、個人的には@embの方が冗長さが少なくてスマートかなと思います。
内側のアポストロフィまでがTJS2側のリテラルとして解釈されて、その結果が返されるという感じですね。

2007/02/12(月)

真・TJS2で辞書配列のforeach

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 19:24:19

その後、色々試してたんですが、TJS2のArray.assignメソッドってオブジェクト型ならなんでも食っちゃえるみたいですね。
つーわけで、さらに改良してみました。

(続きを読む…)

2007/02/08(木)

吉里吉里用EventDispatcherクラス

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 08:54:10

吉里吉里のイベント周りを一括で管理できるクラスを作ってみました。

(続きを読む…)

2007/02/07(水)

吉里吉里から警告が!

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 06:06:26

KAYはよくjavascriptとかで

a == 1 && (b = 2);     //もしaが1ならbに2を代入

みたいな事をやるんですが、これを吉里吉里でやるとこんな警告が出るんですねえ。

05:51:48 警告: 論理値が求められている場所で = 演算子が使用されています(== 演算子の間違いですか?代入した上でゼロと値を比較したい場合は、(A=B) != 0 の形式を使うことをお勧めします) at event_dispatcher.tjs line 70

まあ、スクリプトの動作に影響は無い(?)みたいですが……。
普通にif文使えば事足りる話だし、あんまり変な書き方すなという事ですかね。^^;

2007/02/06(火)

TJS2で辞書配列のforeach(改)

カテゴリー: ゲーム制作, 吉里吉里 — KAY @ 21:22:58

前回のエントリで書いたforeachですが、ちょっと意図したとおりには動かないみたいですねー。
クロージャが生きてると思ったのは、単にグローバルのメンバを参照してただけみたいです……。

普段javascriptばかり書いてるので、もうすっかりこういうもんだと思ってました。^^;
てなわけで、少々不恰好ですが、やはり明示的に変数を渡す仕様に変えてみました。

(続きを読む…)

次ページへ »