关于如何用tjs建立可以应付trans的手工模块

 

该教程为水螅制作,未经允许,请勿转载

 

因为前段时间做夜雾山写那个敌人的class的时候走了不少弯路,重写了三四次……||||||||于是就在这里总结一下,免得以后的同学走上和我一样的弯路……

由于kag的部分很方便,所以我写游戏一般会把kag和tjs插着写,完全只用tjs这种事只会在范例里做……而且一般也都直接继承kag的类在kag的窗口里写……抛弃kag完全用tjs写是件麻烦的事情,因为要自己建立窗口,自己建立基础层,还有很多kag写好的function就不能直接用了……尤其是自己写sl……真是很烦的事情……

该篇说明针对受众是稍微了解tjs基础语法不过对怎么用并没有啥概念的同学们,所以我就说的详细一点。

在窗口里new一个Layer,设定它的visible=true,loadImages图片,设定好层的大小位置,就可以在窗口中看见它了,Layer是krkr的基础类,就是说和kag无关,是在krkr.exe里被定义的类,这种基础类的具体参数和函数都可以在kr2doc这个说明文件里看到,我就不一一列出了。

在new这个层的时候,必须写上父层,一个窗口里没有父层的层只能有一个,已经有一个没有父层的基础层的情况下,如果再定义没有父层的层就会报错。在kag这个窗口里的基础层是kag.fore.base,在父层的位置填上它的话,图片将能够直接被看到。

当放置了这个layer后trans,你就会发现这个新层和其他layer一样被trans没了,如果trans完再次trans,就又能看到他被trans出来,因为改变了父层的可见就能改变所有子层的可见,而kag.fore.base就是这样,被trans时就隐藏,然后和kag.back.base交换名字和信息,也就是说每trans一次,kag.back.base就变成了kag.fore.base,而kag.fore.base就变成了kag.back.base,而不管何时,kag.back.base是不可见的。用过kag的同学应该对此很熟悉了。

所以如果希望一个图片一直在面前晃悠而不会被trans弄走,就需要同时定义两个层,一个的父层是kag.fore.base(假设它的名字为picfore),一个的层是kag.back.base(假设它的名字为picback)。然后给他们设定同样的位置大小载入图片,这样不管怎么trans就都可以看到他们了。

但是这里又出了一个问题,如果我希望只修改它的fore层或者只修改它的back层来达成trans改变图像的画面效果,就会发现,因为使用中trans的次数是不定的,也就是说会不知道当想要设定时,哪个层是出于back状态,哪个层是出于fore状态。

因此,必须要像kag里的其他层一样,在trans时将他们的名字和信息互换,这样才能够无论何时操作picfore就是在操作fore状态的那个层,操作picback就是在操作back状态的那个层。

如何在trans时交换他们的信息——有一个KAGPlugin类提供这个函数…………

使用KAGPlugin类的最直接的范例就是snow.ks这个插件(当然rain.ks也是……)

KAGPlugin类不是kr的基础类,所以我一开始不知道trans时要用它而走了弯路,这个是在kag里的plugin.tjs里定义的,主要特征是用继承这个类然后把实体注册到kagPlugins这个数组里的话在sl的时候这个class能够被sl,以及具有onCopyLayer和onExchangeForeBack这两个函数,就如字面意思一样,这两个函数当用kag的[backlay]和[trans]时就会生效……

说到这里已近没啥好说的了,明白了的同学可以不用继续看下去自己去写自己的class了,还不明白的同学可以跟着我把snow.ks再捋一遍。

拉到snow.ks最下边,可以看到这么一句

kag.addPlugin(global.snow_object = new SnowPlugin(kag));

addPlugin是kag的一个函数,其内容就是把括号里传过来的那东西加入到kagPlugins这个数组里,这样在sl的时候程序会检查kagPlugins这个数组,来对里边的内容进行存取。

这里传入给addPlugin的就是括号里的global.snow_object,global是指全局变量,snow_object就是这个实体的名字,这句话的意思就是建立一个叫做snow_object的SnowPlugin这个类的实体,然后把它添加到kagPlugins这个数组里。

再往下看就可以看到

@macro name="snowinit"
@eval exp="mp.num=17" cond=(mp.num===void)
@eval exp="snow_object.init(+mp.num, mp)"
@endmacro

这样的kag代码,macro是啥怎么用mp是啥我应该不用讲了,这个macro的意思就是当使用他时调用snow_object的init函数。

因为在建立一个新的SnowPlugin实体时,执行的是

var snows = []; // 雪粒
var timer; // タイマ
var window; // ウィンドウへの参照
var foreVisible = true; // 表画面が表示状態かどうか
var backVisible = true; // 裏画面が表示状態かどうか

function SnowPlugin(window)
{
   super.KAGPlugin();
   this.window = window;
}

这部分,如上所示,没啥可以看得见的部分

一直到写了snow_object.init(+mp.num, mp)开始执行这个实体的这部分

function init(num, options)
{
   // num 個の雪粒を出現させる
   if(timer !== void) return; // すでに雪粒はでている

   // 雪粒を作成
   for(var i = 0; i < num; i++)
   {
    var n = intrandom(0, 4); // 雪粒の大きさ ( ランダム )
    snows[i] = new SnowGrain(window, n, this);
   }
   snows[0].spawn(); // 最初の雪粒だけは最初から表示

   // タイマーを作成
   timer = new Timer(onTimer, ');
   timer.interval = 80;
   timer.enabled = true;

   foreVisible = true;
   backVisible = true;
   setOptions(options); // オプションを設定
}

才会跟着timer开始出现雪花。

牢骚一下,我以前写的时候,是在建立实体这一步就做成了全部图层……结果后来发现要为了trans换用KAGPlugin类时全部重写了远目……

当然也不是非得另外写一个函数来启动它,这个都是根据需要的……

继续说重点,这个SnowPlugin继承的KAGPlugin类,所以他有onCopyLayer和onExchangeForeBack这两个函数

当遇到kag里使用[backlay]时,它执行的代码是

function onCopyLayer(toback)
{
   // レイヤの表←→裏情報のコピー
   // このプラグインではコピーすべき情報は表示?非表示の情報だけ
   if(toback)
   {
    // 表→裏
    backVisible = foreVisible;
   }
   else
   {
    // 裏→表
    foreVisible = backVisible;
   }
   resetVisibleState();
}

这里要说的是因为他的雪花是前后层完全一样的,所以他只是复制了visible信息,而没有像kag的layers一样复制整个图层画面,当然自己写模块的时候就要根据实际上自己的需要来写,并不只是传递下visible信息……

当遇到trans时,他执行的代码是

function onExchangeForeBack()
{
   // 裏と表の管理情報を交換
   var snowcount = snows.count;
   for(var i = 0; i < snowcount; i++)
    snows[i].exchangeForeBack(); // exchangeForeBack メソッドを呼び出す
}

数组snows是雪花的指针数组,在init的时候就可以看到

   for(var i = 0; i < num; i++)
   {
    var n = intrandom(0, 4); // 雪粒の大きさ ( ランダム )
    snows[i] = new SnowGrain(window, n, this);
   }

就是说snows的每个成员都是一个SnowGrain的类的实体。

SnowGrain类的定义就在snow.ks的上边部分,基本内容就是每个实体建立fore和back一对图层以及图层的移动计算和设定fore、back的visible情况

而SnowPlugin类的内容就是建立一个叫做snows的数组,里边每个数组都是一个SnowGrain实体,然后SnowPlugin在自己内部的timer里每次ontimer就执行一遍snows每个成员的移动

回到原来的话题,当snow_object遇到trans时,他执行他的onExchangeForeBack函数,而这个函数的内容是,将他的snows数组里的每个成员的exchangeForeBack函数执行一遍,这个exchangeForeBack函数的内容就是

function exchangeForeBack()
{
   // 表と裏の管理情報を交換する
   var tmp = fore;
   fore = back;
   back = tmp;
}

如上,就是这样更换了前后两个层的指针,来确保不管何时操作fore就是操作fore状态的层,操作back就是操作back状态的层。

以上。用tjs写可以应付trans的块就是这么回事……



TOP

访客数: 3128261
aa