krkr进阶教程4
继承了kaglayer的AnimationLayer
该教程为水螅制作,未经允许,请勿转载
打开AnimationLayer.tjs,前边大段注释是asd动画的解释,有兴趣的人可以详细看看
再往后是一个叫做AnimationConductor的class定义,这个暂且按下,等到用到了再说,直接看class AnimationLayer
前边是var了几个参数,接下来是构造函数function AnimationLayer(win, par),里边除了super外还有几个赋值,重要的是这个
Anim_segments[0] = new AnimationConductor(this); // デフォルトのコンダクタ
Anim_segments[0].number = 0;
建立了一个AnimationConductor的实体。这个AnimationConductor就是用来实现asd动画的东西,具体怎么用呢,我们回到mainwindow……查找image :的话就可以看到这么一段
image : function(elm)
{
// 画像読み込み
updateBeforeCh = 1;
var start = System.getTickCount();
getLayerFromElm(elm).loadImages(elm);
dm(elm.storage + " 的读取花费了 " + (System.getTickCount() - start) + "ms。");
return 0;
} incontextof this,
那些dm用的东西不用管,具体载入图片时实现的那一句就是getLayerFromElm(elm).loadImages(elm);,getLayerFromElm是mainwindow里的一个函数用来取得elm里传入的图层名的,这句话的意思就是用loadImages来载入图片。
顺便一提,比如在kag里写了[image layer=1 storage=aa page=fore left=12 top=14],就是调用了mainwindow的image函数,那些参数就全部都放在了这个传入字典elm里,比如elm.top就是14……
如果是基础的layer类,loadImages就是直接载入静态图片,但是让我们再看一遍这个结构图
Layer ( 吉里吉里ネイティヴクラス )
|
+-- KAGLayer ( このファイル )
|
+-- AnimationLayer ( AnimationLayer.tjs )
| |
| +-- ClickGlyphLayer ( AnimationLayer.tjs )
| |
| +-- GraphicLayer ( GraphicLayer.tjs )
| |
| +-- BaseLayer ( GraphicLayer.tjs )
| |
| +-- CharacterLayer ( GraphicLayer.tjs )
|
+-- MessageLayer ( MessageLayer.tjs )
|
+-- ButtonLayer ( ButtonLayer.tjs )
| |
| +-- LinkButtonLayer ( MessageLayer.tjs )
| |
| +-- LButtonLayer ( HistoryLayer.tjs )
|
+-- EditLayer ( EditLayer.tjs )
| |
| +-- LinkEditLayer ( MessageLayer.tjs )
|
+-- CheckBoxLayer ( CheckBoxLayer.tjs )
|
+-- LinkCheckBoxLayer ( MessageLayer.tjs )
平时kag中用的layer除了base层是baselayer类外,其他层都是CharacterLayer类,而这两个类都是继承了GraphicLayer类,GraphicLayer类继承的是AnimationLayer类……所以AnimationLayer里重定义了loadImages的话,这些类在执行loadImages的时候也是执行的他所重定义的内容(当然如果子类又进行了重定义那就是另外一回事了,但是目前我们在讲AnimationLayer类,于是先无视子类的情况)
AnimationLayer类里的loadImages是下边这样的……因为太长了我就把解释直接写在注释里了……
function loadImages(elm)
{
// loadImages オーバーライド
// elm は読み込み情報
if(elm === void)
//如果什么都没传入就直接释放图片,然后结束操作返回
{
freeImage();
return;
}
Anim_loadParams = %[];
(Dictionary.assign incontextof Anim_loadParams)(elm);
// 将传入的字典复制给Anim_loadParams
clearAnim();
//清除图层上的动画,因为重新载入图片了,原来上边的内容就要被清掉,clearAnim()的具体内容自己看吧……我就不一个一个讲了不然会没完没了的……||||||||||
Anim_partialImageInfo = void;
//这里也是清除原来的信息
var taginfo = super.loadImages(elm.storage, elm.key);
//读入图片,同时把返回值赋给临时变量taginfo,layer类的loadImages本身是会返回一个字典的,内容大致是画面情报位置之类的
if(taginfo)
{
(Dictionary.assign incontextof taginfo)(elm, false);
elm = taginfo;
}
//把传入的那个字典参数elm合并到taginfo里,再赋值给elm(就是说现在elm里和taginfo里都是原来两个字典的合并)
var ud, lr;
if(elm.flipud !== void && +elm.flipud)
{
// 如果elm里flipud参数不是空的就进行flipUD(),这个函数用来翻转图片,具体内容也请直接自己看……
//这个所谓的flipud参数不是空的的意思就是,你在kag里写了[image storage=xxx layer=xx flipud=true]……
flipUD();
ud = true;
}
else
{
ud = false;
}
if(elm.fliplr !== void && +elm.fliplr)
{
// 左右翻转
flipLR();
lr = true;
}
else
{
lr = false;
}
if(elm.clipleft !== void)
{
// 指定了clip的情况,这里可以看出必须要填clipleft,不然只填其他几个clip不填clipleft会被程序无视……
// 顺便说一下,认真看过layer类的说明的人就会知道,layer是有image大小和图层大小两个概念的,如下图所示
//就像是走马灯一样,我们可以看到前边的木框,后边的图片却可以所以移动来改变我们可以看到的部分,注意imageleft,imagetop的坐标是以显示出来的区域的左上角为0,0的相对坐标。另外不可以让image层没有的部分在显示出来的区域露出来,那样会报错……
//所以所谓的clip就是把图片load出来之后根据你填写的参数设定了显示出来的区域的大小和位置,而所谓asd动画……他就是走马灯……
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 = ltAlpha;
//这边是图像模式的赋值
if(elm.mode !== void)
{
var layertypeinfo = imageTagLayerType[elm.mode];
if(layertypeinfo !== void)
mode = layertypeinfo.type;
}
type = mode;
}
// 色補正
face = dfAuto;
applyColorCorrection(this, elm);
// 可视、位置、不透明度、层位置(index)
if ( elm !== void && elm.pos !== void ) {
// 如果在image里写了pos这个参数(写了left、right、center这类的),就是用那个位置作为底面中心,这个是给立绘用的,具体这几个参数对应的坐标是放在scPositionX这个字典里的,我记得config里有对他的设定
left= window.scPositionX[elm.pos] - width 2;
top = window.scHeight - height;
}
else
//如果没设定pos就用设定的left和top来放图的位置
{
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;
// 最后这段就是载入asd动画了
Anim_storageName =
Storages.getPlacedPath(
Storages.chopStorageExt(elm.storage) + ".asd");
//首先是寻找有没有图片同名的asd文件
if(Anim_storageName != ')
{
//如果有的话就执行loadAnimInfo
loadAnimInfo(0, ');
}
}
那么,就来看看loadAnimInfo是什么……
function loadAnimInfo(segment, label)
{
if(Anim_storageName == ')
throw new Exception(
("对于" + Anim_loadParams !== void ? Anim_loadParams.storage : "") +
"没有动画信息");
//如果不存在asd文件就抛出错误
var seg;
if(Anim_segments[segment] === void)
{
//segment刚才传入的值是0,Anim_segments[0]在构造函数里已经被定义为了AnimationConductor类的实体……如果只用kag的话,是不存在出现使用Anim_segments[1]之类的情况的,在kag里一个层也就会用到Anim_segments[0]这一个AnimationConductor,对于kag来说这个步骤其实没太大意义,不过如果用tjs写的话,就可以随意了
Anim_segments[segment] = seg = new AnimationConductor(this);
seg.number = segment;
}
else
{
// 已经被定义过的情况下执行停止动画
(seg = Anim_segments[segment]).stop();
}
//接下来对这个AnimationConductor类进行各种赋值
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);
}
最后执行了这个AnimationConductor的startProcess,那么,现在我们可以来看看AnimationConductor类到底都能做些什么了……
AnimationConductor继承的是BaseConductor,BaseConductor继承的是KAGParser……KAGParser的方法列表如下
- コンストラクタ
- KAGParser
- メソッド
- assign ( KAGParser オブジェクトのコピー )
callLabel ( 現在位置をスタックに積んでの、指定ラベルへの移動 )
clear ( オブジェクトのクリア )
clearCallStack ( call タグ呼び出しスタックのクリア )
getNextTag ( 次のタグを得る )
goToLabel ( 指定ラベルへの移動 )
interrupt ( interrupted 状態にする )
loadScenario ( シナリオの読み込み )
resetInterrupt ( interrupted 状態の解除 )
restore ( 辞書配列からオブジェクトの状態を復元する )
store ( オブジェクトの状態を辞書配列に書き出す ) - プロパティ
- callStackDepth ( call タグ呼び出しスタックの深さ )
curLabel ( 現在のラベル )
curLine ( 現在行の行数 )
curLineStr ( 現在行の文字列 )
curPos ( 現在行における文字の位置 )
curStorage ( 現在のストレージ )
debugLevel ( デバッグレベル )
ignoreCR ( 改行を無視するかどうか )
macroParams ( 現在実行されているマクロの引数 )
macros ( マクロの入った辞書配列 ) - イベント
- onAfterReturn ( return タグで復帰した )
onCall ( call タグが呼ばれた )
onJump ( jump タグが呼ばれた )
onLabel ( ラベルを通過した )
onReturn ( return タグが呼ばれた )
onScenarioLoad ( シナリオ読み込みが開始した )
onScenarioLoaded ( シナリオ読み込みが終了した )
onScript ( iscript ブロックを通過した )
startProcess是BaseConductor的函数,其他那些参数和方法就都是KAGParser的了(BaseConductor有进行重定义不过基本还是super的)所以具体内容可以直接查阅kr2doc……所以其实asd脚本和ks脚本写起来也没太大区别了,可以用标签可以用变量可以用macro可以用条件判断……
这样,AnimationLayer就到此为止……
Created by Hydrozoa.2011
不支持IE7以下浏览器
凯恩插件程序:Hydrozoa 美术:Hydrozoa,红渊