网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
01月01日漏签0天
吉里吉里吧 关注:51,261贴子:70,947
  • 看贴

  • 图片

  • 吧主推荐

  • 视频

  • 游戏

  • 1 2 下一页 尾页
  • 34回复贴,共2页
  • ,跳到 页  
<<返回吉里吉里吧
>0< 加载中...

【随笔/简单进阶】tjs里的一些玩法和坑.碰到啥写啥...

  • 只看楼主
  • 收藏

  • 回复
  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
没错,这是个一定会坑掉的坑


  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
因为我之前已经丢过tjs和krzdoc的简单入门了,所以我不会再逐一介绍哪个函数在哪哪个函数到底是干啥的......
与kagsystem完全无关,想改造kag的话,估计这东西对你0帮助...
千万注意这个使用的exe版本是z,因为已经不会再用2这个版本了...所以如果有一些函数在2上动作不正常或找不到该项属于正常情况


2026-01-01 05:46:40
广告
不感兴趣
开通SVIP免广告
  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
基础知识
z没有控制台
z的Startup.tjs需要UTF-8( 没法用中文 ),而其他的文件如果你想使用中文则需要Unicode
global是个字典.默认的执行上下文是global
自动路径只会返回搜索到的第一个同名文件
kr的继承保存的是字符串,也就是你extends后面的东西哪怕是在一个字典里也必须要写完整访问路径...
在传值时的匿名函数是xxx( function(){} )不需要=function时最后的;
Rect实际上传入的是x1 , y1 , x2 , y2,最终使用的是它们中间的区域........也即x1 , x2 , x2-x1 , y2-y1...
匹配模式实际上是Text.replace( new RegExp( Sign , Mode ) , ChangeText ),//只是个语法糖.但要注意这东西是会转义的.例如$( 如果不做处理会出现indexOf能找到但匹配失败的情况... )
你kr的解锁基本没什么用.想要完全不影响还不如直接copyRect
Array.assgin可以获取到Dictionary的键值列表.但无法保证顺序.插入方式是 Key(0), Value(1)
ImageFunction有些函数以自身为参数操作获取一个结果给自身无效.
将一个属性添加到当前物件中在2使用&,在z使用eval
如果你试图通过xxx/xxx访问一个文件,但是这个文件在一个xp3中,直接爆炸
xp3只有在打包xp3的那个层级需要xxx.xp3>,里面的如果不是xp3则不需要,手动路径处理最烦人的地方
transition在トランジションについて,别再问了
kr的消息处理并不是多线程.timer和asyncTrigger实际上最终还是压到消息泵去处理.....
kr的WaveSoundBuffer如果你不play的话,获取totalTime会报错
至于字体之类的....没什么好说的了


  • wzhydd1
  • 小吧主
    12
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
好散


  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
那么为了应对上面说过的路径问题,就需要自己写一些函数了,比如路径
function isExistentXP3( ThisPath , ThisPackage ){
var CheckStorage = ThisPath + ThisPackage + ".xp3";
return isExistentStorage( CheckStorage ) ? CheckStorage + ">" : ThisPath + ThisPackage + "/";
}
那么首先,为了检测到这个路径到底是不是一个xp3包.....封一个函数
然后需要一个可以拆出每一级路径的函数,不过我这里写的是
// 获取匹配符号中间所有的字符串[ missing|get|get|get|missing ]
function getSignMiddleAnyString( Text , Sign , StartPosition = 0 , OverPosition = Text.length ){
var TempString = [];
var TempSingPosition = getSignPosition( Text , Sign , StartPosition , OverPosition );
for( var i = 0 ; i < TempSingPosition.count - 1 ; i++ ){
TempString.add( getPositionMiddleString( Text , TempSingPosition[i] , TempSingPosition[ i + 1 ] ) );
}
return TempString;
}
那么这里就又出来了getSignPosition,这个函数是
// 获取字符串中所有对应符号的位置
function getSignPosition( Text , Sign , StartPosition = 0 , OverPosition = Text.length ){
var SignPosition = [];
var TempPosition = StartPosition;
while( true ){
TempPosition = Text.indexOf( Sign , TempPosition );
if( TempPosition == -1 ){ break; }
if( TempPosition > OverPosition ){ break; }
SignPosition.add( TempPosition ); TempPosition++;
if( TempPosition == Text.length ){ break; }
}
return SignPosition;
}
而另外一个函数getPositionMiddleString是
// 获取某个索引到某个索引中间的字符串.用于获取分隔符两段的字符[ |get| ]
function getPositionMiddleString( Text , StartPosition , OverPosition ){ return Text.substring( StartPosition + 1 , OverPosition - StartPosition - 1 ); }
也就是为了应对之前说的老要去算那个长度的问题...
那么现在开始封装一个真正用于处理路径的函数
function evalPath( Path ){
// 如果前两位不是..代表绝对路径
if( Path.trim().substring( 0 , 2 ) != ".." ){
return Path;
}
var PathList = getSignMiddleAnyString( "/" + Path + "/" , "/" );
var XP3 = 0;
Path = global.System.exePath;
for( var i = 1 ; i < PathList.count - 1 ; i++ ){
if( isExistentXP3( Path , PathList[i] ) ){
// 修改为xp3访问路径
Path += PathList[i] + ".xp3>";
}else{
// 尝试处理为普通路径
Path += PathList[i] + "/";
}
}
return Path + PathList[ PathList.count - 1 ];
}
那么通过判定前2位..可以确定是绝对路径或相对路径
相对路径就拆分/符号,然后一级一级判定是不是xp3.是就返回xp3访问路径.不是就普通路径


  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
这个不想说啥......
// 为了应对Rect的各种坐标问题.缓存一个额外的rect来进行判定操作.
// 直接使用的这个是x , y , w , h.额外缓存的是x , y , x+w , y+h.
// 这个东西会重写Rect的所有事件.请注意动作变更
class GlobalRect extends Rect{
// 全局可用的rect.但是自己用着血妈难受mmp
// 一切的判定之类的操作全部丢给这东西
var globalRect;
function GlobalRect( X = 0 , Y = 0 , W = 10 , H = 10 ){
Rect( X , Y , W , H );
globalRect = new global.Rect( X , Y , X + W , Y + H );
}
function addOffset( X , Y ){
global.Rect.addOffset(...);
globalRect.setOffset(...);
}
var setOffset = addOffset;
function clear(){
global.Rect.clear();
globalRect.clear();
}
function clip(r){
global.Rect.clip(r);
if( Scripts.getClassNames(r)[0] == "Rect" ){
globalRect.clip( new global.Rect( r.left , r.top , r.left + r.right , r.top + r.bottom ) );
}else{
globalRect.clip( r.globalRect );
}
}
function included(r){
if( Scripts.getClassNames(r)[0] == "Rect" ){
return globalRect.included( new global.Rect( r.left , r.top , r.left + r.right , r.top + r.bottom ) );
}else{
return globalRect.included(...);
}
}
function includedPos( X , Y ){
return globalRect.includedPos(...);
}
function intersects(r){
if( Scripts.getClassNames(r)[0] == "Rect" ){
return globalRect.intersects( new global.Rect( r.left , r.top , r.left + r.right , r.top + r.bottom ) );
}else{
return globalRect.intersects(...);
}
}
function isEmpty(){
return globalRect.isEmpty();
}
function set( X , Y , W , H ){
global.Rect.set(...);
globalRect.set( X , Y , X + W , Y + H );
}
function setSize( W , H ){
global.Rect.setSize(...);
globalRect.setSize( globalRect.left + W , globalRect.top + H );
}
function union(r){
global.Rect.union(r);
if( Scripts.getClassNames(r)[0] == "Rect" ){
return globalRect.union( new global.Rect( r.left , r.top , r.left + r.right , r.top + r.bottom ) );
}else{
return globalRect.union( r.globalRect );
}
}
}


  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
在用kag的时候老是要用一个透明按钮盖着然后去挂asd( 某个ex貌似直接可以.. ),所以现在也不按钮了,直接挂热区
需要了解的是.除了Layer以外,Window也可以用于监测事件.少的那几个事件基本无关紧要
那么为了用Win来监测区域的话,就需要一些额外的准备,没错上面那个也是其中之一
因为我搞了一堆的依赖所以我就直接挂出来了
// 基类Object
class Object{
var name;
var enabled = 1;
property Enabled{ getter{ return enabled; }
setter( Value ){ if( enabled != Value ){ enabled = Value; enabled ? onActivate() : onDeactivate(); } } }
function Object( Init* ){ name = getClassID(); Awake(); Start(...); }
function Awake(){}
function Start( Init ){}
// 向当前物件添加一个成员
function addSymbol( Symbol , ObjectInit , Enum_Type = "property" ){
if( typeof Symbol != "void" ){
switch( Enum_Type ){
case "property":
Scripts.exec( "property " + Symbol + "{ setter( Value ){ " + ObjectInit[0] + " } getter{ var Return; " + ObjectInit[1] + " return Return; } }" ,,, this );
break;
case "eval":
this[ Symbol ] = Parse.eval( ObjectInit );
break;
case "base":
default:
this[ Symbol ] = ObjectInit;
break;
}
}
}
// 在当前物件中删除一个成员( 可以删除不存在的成员 )
function removeSymbol( Symbol , Array = 0 ){
if( typeof Symbol != "undefined" ){
if( Array ){ for( var i = 0 ; i < Symbol.count ; i++ ){ delete this[ Symbol[i] ]; } }
else{ delete this[ Symbol ]; }
}
}
// 对比两个物件是否相同.需要重写
function equals( AnyObject ){ return -1; }
// 对比两个物件是否来自同一个类的实例化
function referenceEquals( AnyObject ){
if( typeof AllObject[ "getClassID" ] == "Object" ){
if( getClassID() == AllObject.getClassID() ){ return 1; }
return 0;
}
}
// 返回当前类名
function getClassID(){ return Parse.getClassNames(this)[0]; }
// 查询当前类是否为某个类的子类
function findSuperClassID( ClassID ){ if( Parse.getClassNames(this).find(...) != -1 ){ return true; }return false; }
function toString(){ return getClassID(); }
// UnLoad函数会被用作资源管理之一.如果读取资源的物件的话.这里务必要写释放函数
function unLoad(){}
// 当物件被激活和停用时
function onActivate(){}
function onDeactivate(){}
}
// 事件列表
class EventObject{
// Event %[ "Type" => [ Bool , Event ] ]
var eventList = %[];
function addEvent( Type , Func ){ if( eventList[ Type ] != void ){ eventList[ Type ].add( Func ); } }
function removeEvent( Type , Index = 0 ){
if( eventList[ Type ] != void ){
if( Index == 0 ){ delete eventList[ Type ]; }
else{ eventList[ Type ].erase( Index ); }
}
}
// 添加一个类型到事件列表
function addEventToList( Event ){ if( eventList[ Event ] == void ){ eventList[ Event ] = [1]; } }
// 添加一个类型到当前物件.供HandlerEvent调用
function addEventToObject( Event ){
if( eventList[ Event ] == void ){ eventList[ Event ] = [1]; }
this[ Event ] = global.Parse.eval( "function( Init* ){
if( eventList[ '" + Event + "' ][0] ){ handlerEvent( '" + Event + "', Init* ); }
}" );
}
function handlerEvent( Event , InitList* ){
if( eventList[ Event ] != void ){
for( var i = 1 ; i < eventList[ Event ].count ; i++ ){
eventList[ Event ][i]( InitList* );
}
}
}
}
这俩玩应我已经懒得动了,也不打算解释...反正这级别的玩应看懂应该不难,但要注意的是,global.Parse是我自己维护的一个类,这个东西需要你自己去处理....【或者等我填完坑(不可能的


  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
所以
class EventBOX extends GlobalRect, EventObject, Object{}
不过这个东西暂时先放在这
class TempWindow extends Window, EventObject{}
Window = new TempWindow();
Scripts.execStorage( ThisPath + "WindowManager.tjs" ,, Window );
需要注意的是,2会直接执行错误
那么现在建立一个WindowManager.tjs这么个东西.至于你要怎么设置这个窗口实例之类的,那与我无关.....
// 全局事件.这一类事件并不交给被监控区域.只是单纯的调用一次
var addGlobalEventToObject = addEventToObject;
// 窗口被聚焦 onActivate()
// 窗口失去焦点 onDeactivate()
addGlobalEventToObject( "onActivate" );
addGlobalEventToObject( "onDeactivate" );
// 窗口被关闭 onCloseQuery() 参数关闭子窗口被弃用
addGlobalEventToObject( "onCloseQuery" );
addEvent( "onCloseQuery" , function(){ global.System.exit(); } );
// 窗口获取到了文件 onFileDrop( FilePath )
addGlobalEventToObject( "onFileDrop" );
// 输入文字 onKeyPress( Key )
addGlobalEventToObject( "onKeyPress" );
// 弹出窗口关闭 onPopupHide()
addGlobalEventToObject( "onPopupHide" );
// 窗口尺寸变化 onResize()
addGlobalEventToObject( "onResize" );
// 鼠标进入 onMouseEnter()
addGlobalEventToObject( "onMouseEnter" );
// 鼠标移出 onMouseLeave()
addGlobalEventToObject( "onMouseLeave" );
这部分看不懂我在干啥的去看EventObject,eval真的是一个很滑稽的东西
这部分事件是全局事件.也即被监测的子区域不会直接获取到的事件,所以后面就是准备一些需要传给子区域的东西了
// 区域监测及事件.这类事件的第一个参数会传入调用的位置.
// 具体的逻辑是 调用全局事件(前) 调用监测区域事件 调用全局事件(后)
function addRectEventToObject( Event , BeforeEventFunc , BackEventFunc ){
if( eventList[ Event ] == void ){ eventList[ Event ] = [1]; }
this[ Event ] = global.Parse.eval( "function( Init* ){
" + BeforeEventFunc + "
if( eventList[ '" + Event + "' ][0] ){ handlerEvent( '" + Event + "' , 'before' , Init* ); }
for( var i = 0 ; i < thisCheckRect.count ; i++ ){
if( typeof( thisCheckRect[i][ '" + Event + "' ] ) == 'Object' ){
thisCheckRect[i][ '" + Event + "' ]( Init* );
}
}
if( eventList[ '" + Event + "' ][0] ){ handlerEvent( '" + Event + "' , 'back' , Init* ); }
" + BackEventFunc + "
}" );
}
// 鼠标坐标
var mouseX;
var mouseY;
var lastMouseDownX;
var lastMouseDownY;
// 键状态表
var keyMap = %[];
// 被监测区域. [ Enable , Rect , Index , Penetration , Target ]
// Target
var checkBOXRect = [];
// 鼠标已经进入该范围的区域.要改变这个列表必定要调用事件
var thisCheckRect = [];
// 上次移动还在范围内的区域.这个列表无论怎么变都不会进行事件调用
var lastCheckRect = [];
// 被监测物件.被监测范围.范围所在高度.该范围是否可以被穿透.在初步加入时默认是不激活的.因为可能需要其他的初始化操作
// 该函数会返回加入后的那个坐标位置的数组.你需要保存并直接操作它.在删除时同样删这个数组
function addCheckBOX( Target ){ return checkBOXRect.add(...); }
// 如果在削除时在当前范围列表中存在的话.那就需要删掉了
// 如果你需要在删除这个的时候直接来挂一次的话.掉move然后传最后一次x.y还有keymap的那几个就完了
function removeCheckBOX( Target ){
var Index = thisCheckRect.find( Target );
if( Index != -1 ){ thisCheckRect.erase( Index ); }
Index = checkBOXRect.find( Target );
checkBOXRect.erase( Index );
}
注释够了吧应该....


2026-01-01 05:40:40
广告
不感兴趣
开通SVIP免广告
  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
然后就是.........................
// 鼠标移动 onMouseMove( X , Y , Shift )
// 鼠标移动用来获取监测区域.而其他的只对现有的检测区域下事件
addEventToList( "onMouseMove" );
function onMouseMove( Init* ){
mouseX = Init[0]; mouseY = Init[1];
if( eventList[ "onMouseMove" ][0] ){ handlerEvent( "onMouseMove" , "before" , Init* ); }
// 记录当前的范围内列表.然后对这个列表进行编辑
lastCheckRect = [];
lastCheckRect.assign( thisCheckRect );
// 对记录的列表进行操作编辑
for( var i = 0 ; i < checkBOXRect.count ; i++ ){
if( checkBOXRect[i].includedPos( Init[0] , Init[1] ) ){
// 当前区域不支持检测
if( !checkBOXRect[i].checkBOX ){ continue; }
// 列表里啥也没有
if( lastCheckRect.count == 0 ){ lastCheckRect.add( checkBOXRect[i] ); continue; }
// 列表里已经存在
if( lastCheckRect.find( checkBOXRect[i] ) != -1 ){ continue; }
for( var r = 0 ; r < lastCheckRect.count ; r++ ){
// 如果当前绝对高度要小于列表那个
if( checkBOXRect[i].absolute < lastCheckRect[r].absolute ){
// 如果那东西不允许穿透退出当前循环
if( lastCheckRect[r].penetration == 0 ){ break; }
// 允许穿透检测后方是否存在.如果不存在就挂上去.如果存在就结束本次循环
else{
if( r + 1 == lastCheckRect.count ){
lastCheckRect.add( checkBOXRect[i] );
break;
}
continue;
}
}
// 如果当前绝对高度要大于列表那个
if( checkBOXRect[i].absolute > lastCheckRect[r].absolute ){
// 那就检测自己这个是否允许穿透
if( checkBOXRect[i].penetration == 1 ){
// 如果允许穿透.插入进去就完了
lastCheckRect.insert( r , checkBOXRect[i] );
}else{
// 如果不允许穿透.清空列表
if( r == 0 ){
lastCheckRect = [ checkBOXRect[i] ];
}else{
for( var v = r ; v < lastCheckRect.count ; ){ delete lastCheckRect[v]; }
lastCheckRect.add( checkBOXRect[i] );
}
}
break;
}
// 如果当前绝对高度等于列表那个
if( checkBOXRect[i].absolute == lastCheckRect[r].absolute ){
// 这里的大小于跟上面的一样.也是最终判定出了高度不同.
if( checkBOXRect[i].order < lastCheckRect[r].order ){
if( lastCheckRect[r].penetration == 0 ){ break; }
else{
if( r + 1 == lastCheckRect.count ){
lastCheckRect.add( checkBOXRect[i] );
break;
}
continue;
}
}
if( checkBOXRect[i].order > lastCheckRect[r].order ){
if( checkBOXRect[i].penetration == 1 ){
lastCheckRect.insert( r , checkBOXRect[i] );
}else{
if( r == 0 ){
lastCheckRect = [ checkBOXRect[i] ];
}else{
for( var v = r ; v < lastCheckRect.count ; ){ delete lastCheckRect[v]; }
lastCheckRect.add( checkBOXRect[i] );
}
}
break;
}
if( checkBOXRect[i].order == lastCheckRect[r].order ){
// 如果当前区域允许穿透.扔进去
if( checkBOXRect[i].penetration == 1 ){
lastCheckRect.insert( r , checkBOXRect[i] );
break;
}else{
// 到底了.并没有把这个区域踢出去.那就加入
if( r + 1 == lastCheckRect.count ){
lastCheckRect.add( checkBOXRect[i] );
break;
}
// 如果后面那个绝对相对高度都一样还允许穿透.直接结束本次循环
if( lastCheckRect[ r + 1 ].absolute == checkBOXRect[i].absolute &&
lastCheckRect[ r + 1 ].order == checkBOXRect[i].order &&
lastCheckRect[ r + 1 ].penetration == 1
){ continue; }
while(1){
// 当不同的情况下.塞进去
if( lastCheckRect[ r + 1 ].absolute != checkBOXRect[i].absolute ){ break; }
if( lastCheckRect[ r + 1 ].order != checkBOXRect[i].order ){ break; }
if( lastCheckRect[ r + 1 ].penetration == 0 ){ break; }
}
lastCheckRect.insert( r + 1 , checkBOXRect[i] );
break;
}
}
}
}
}else{
if( lastCheckRect.find( checkBOXRect[i] ) != -1 ){
// 如果已经不在范围内.移除
lastCheckRect.erase( lastCheckRect.find( checkBOXRect[i] ) );
i--;
continue;
}
}
}
// 对比两个列表的区别.然后调用对应事件
// 如果当前列表中的区域依然在编辑后的区域内
for( var i = 0 ; i < thisCheckRect.count ; i++ ){
if( lastCheckRect.find( thisCheckRect[i] ) != -1 ){
// 如果依然在列表内.那么调用move
if( typeof( thisCheckRect[i][ "onMouseMove" ] ) == "Object" ){
thisCheckRect[i].onMouseMove(...);
}
}else{
// 如果已经不在列表内.那么调用leave
if( typeof( thisCheckRect[i][ "onMouseLeave" ] ) == "Object" ){
thisCheckRect[i].onMouseLeave(...);
}
}
}
for( var i = 0 ; i < lastCheckRect.count ; i++ ){
if( thisCheckRect.find( lastCheckRect[i] ) == -1 ){
// 如果之前不在列表内.那么调用enter
if( typeof( lastCheckRect[i][ "onMouseEnter" ] ) == "Object" ){
lastCheckRect[i].onMouseEnter(...);
}
}
}
// 将更新后的列表交换回当前使用列表
thisCheckRect = [];
thisCheckRect.assign( lastCheckRect );
if( eventList[ "onMouseMove" ][0] ){ handlerEvent( "onMouseMove" , "back" , Init* ); }
}
因为很长...所以还是单开,它最终的效果是,
高度判定没啥好说的,那么如果允许穿透的话,多个被穿透的区域就会同时收到事件( 当然还是有一些顺序问题 )


  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
// 窗口被单击(完整动作) onClick( X , Y )
addRectEventToObject( "onClick" );
// 窗口被双击 onDoubleClick( X , Y )
addRectEventToObject( "onDoubleClick" );
// 按键按下 onKeyDown( Key , Shift )
addRectEventToObject( "onKeyDown" , "keyMap[ Init[0] ] = 1;" );
// 按键抬起 onKeyUp( Key, Shift )
addRectEventToObject( "onKeyUp" , "keyMap[ Init[0] ] = 0;" );
// 鼠标按下 onMouseDown( X , Y , Button , Shift )
addRectEventToObject( "onMouseDown" , "keyMap[ Init[2] ] = 1;" );
// 鼠标抬起 onMouseUp( X , Y , Button , Shift )
addRectEventToObject( "onMouseUp" , "keyMap[ Init[2] ] = 0;" );
// 鼠标滚轮转动 onMouseWheel( X , Y , Delta , Shift )
addRectEventToObject( "onMouseWheel" );
剩下这些就没啥东西了...之后就是用于添加区域的EventBOX
// 在窗口上挂一个监控区域.以获取事件.但是这东西你需要手动unLoad
// 依赖于WindowManager.因此必须要等Window实例化之后才能使用
class EventBOX extends GlobalRect, EventObject, Object{
// 继承变量enabled.Enabled该属性负责是否处于活动状态.
// 但负责当前区域是否被监测的是下面这个...( 因为当前物件可能被作为一个节点使用.但只用于分发 )
var checkBOX;
// 当前物件所属的上层物件
var parent;
// 当前物件的子区域与子物件.区别是rect是当前类实例.它可以继续向下分发
// 而event则是具体的操作物件.这种往往不需要再往下分发了.不过一定要注意执行顺序
var rectChilren;
var eventChilren;
// 高度及贯穿
var absolute;
var order;
var penetration;
// 初始化完成将自身加入监测列表.在卸载时在列表中卸载自身
function EventBOX( X = 0 , Y = 0 , W = 10 , H = 10 , CheckBOX = 0 , Parent = null , Penetration = 0 , Absolute = 0 , Order = 0 , Init* ){
// 初始化数据
rectChilren = [];
eventChilren = [];
// 是否检测.父物件.绝对高度.相对高度.是否可以穿透这个区域( 当前区域会获取事件 )
checkBOX = CheckBOX;
parent = Parent;
absolute = Absolute;
order = Order;
penetration = Penetration;
// 初始化区域.并将激活与停用事件用当前物件的逻辑挂载( 因为要调用子物件 )
GlobalRect( X , Y , W , H );
addEventToObject( "onActivate" );
addEventToObject( "onDeactivate" );
// 注意一顿操作之后是先调用的Awake和Start
Object( Init* );
// 所有初始化完成.加入检测区域
Window.addCheckBOX( this );
}
function unLoad(){ Window.removeCheckBOX( this ); }
function addRectChildren( RectObject ){ rectChilren.add(...); }
function removeRectChildren( RectObject ){
// 为了不触发析构...
var Index = rectChilren.find(...);
if( Index != -1 ){ rectChilren[ Index ] = void; rectChilren.earse( Index ); }
}
function clearRectChildren(){
}
function addEventChilren( EventObject ){ eventChilren.add( EventObject ); }
function removeEventChilren( EventObject ){
var Index = eventChilren.find(...);
if( Index != -1 ){ eventChilren[ Index ] = void; eventChilren.earse( Index ); }
}
function clearEventChilren(){
}
// 只有这个函数返回true的时候.才会调用事件.如果满足条件调用.请在这里变更条件
function checkCondition( Event ){ return 1; }
// handler会先调用自身.挂在自身下面的处理.而后向后分发事件
// 如果你希望在父物件调用时无视条件.那么将check由handler转移至addEventToObject
function handlerEvent( Event , InitList* ){
if( checkCondition( Event ) ){
global.EventObject.handlerEvent(...);
if( eventChilren.count != 0 ){
for( var i = 0 ; i < eventChilren.count ; i++ ){
eventChilren[i].handlerEvent(...);
}
}
if( rectChilren.count != 0 ){
for( var i = 0 ; i < rectChilren.count ; i++ ){
rectChilren[i].handlerEvent(...);
}
}
}
}
}
懒得封结构,所以参数列表贼长,不过这个东西必要的只有
checkBOX,absolute,order,penetration,function unLoad(){ Window.removeCheckBOX( this ); }来保持正确操作.如果你需要调整它的逻辑,直接改就是了- -
我知道很乱,但是敲一遍基本都知道啥是啥了,最终Win会下发时间给EventBOX,这个BOX本身会执行一次,然后进行下发,至于具体要怎么用...


  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
https://pan.baidu.com/s/1_zd10C2S6bpeXynQCHm3Sg


  • 敬启绝音
  • 小吧主
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
应该没人看了吧,没人看我放一点比较危险但是很好玩的玩应,与之前Object里面向物件中添加属性一样.
在z中.eval和exec的参数列表是(expression, name='', linesof=0, context=global)和(script, name='', linesof=0, context=global)
第一参数没什么好说的就是字符串...第二三参数是负责报错指定,重点是第四参数.在tjsvm中允许你切换执行上下文(危险),而这一点在2中可以完成一部分,但相对来讲比较麻烦一点(expression),(script)2不是不允许你切换上下文的(安全),但它毕竟可以通过eval执行
所以z只是在某些情况下少写了一些乱七八糟的代码而已
那么正题.因为exe中tjsvm的原因.你可以通过eval和exec直接解析tjs代码( 因为是解释型 ),这一点在其它引擎上实际上还是比较麻烦的...(所以我们更愿意在其他引擎上尝试实现kag...)
另外一个原因是在tjs中你能相当容易的拼接字符串和值,但是在其他引擎.....所以这种有点tjs特殊玩法的节奏,慎用
虽然也有直接[].load和拆字符串不用处理编码的原因【......
所以由tjsvm简化了大片的操作之后.现在我们得到的就是eval和exec
Scripts.exec( "property " + Symbol + "{ setter( Value ){ " + ObjectInit[0] + " } getter{ var Return; " + ObjectInit[1] + " return Return; } }" ,,, this );
这只是个最基本的使用方法...但是比如在外面&,这种虽然危险但是毕竟kr允许【
但eval和exec只是个最终步骤而已.kr1的时候我记得kag还是通过tjs解析的...那么实际上也没什么问题,通过搜索标识符,确认语法,完善搜索逻辑,这种东西并不难
两种方法.
一种是在tjs代码中直接插入片段进行解析.并将结果替换为tjs可执行代码,最终执行
一种是kag那种,只能在特定条件下执行tjs代码(获取iscripts与endscripts中间的字符)
上面那种是我现在做的...因为依赖太多我就不放了...
<#mainLabel label< $( inputvValue ) > label< tjsScripts + <#mainLabel label< scripts >> > >
当然尖括号可以用[]...只不过tjs太多[]了不太好用...而kag的话也是
[mainlabel label=value label=mp.value]
也就是说.这种东西实际上就是拆标签和值的玩应...
上面那种是在拆分,调用labels后,变更区间为tjs代码,最终交给eval执行
kag那种是在拆分,调用labels时,将特定子标签交给eval执行( 因为我记得有一些没被eval....... )
所以这里实际上分为两个小部分,一个部分是字符串拆分,一个部分是逻辑解析
虽然很危险但是在tjs里确实挺好用的....
顺带在上面的EventObject里的addEventToObject( Event )也是使用方法之一,这个方法在WindowManager.tjs中被重写,并被加以利用,论为了偷懒【
虽然我知道不会有人看的


  • wzhydd1
  • 小吧主
    12
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
这个时候就要@gjy_管
加一波精


  • wzhydd1
  • 小吧主
    12
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
居然还能把模拟器发到这样的帖子历来


2026-01-01 05:34:40
广告
不感兴趣
开通SVIP免广告
  • 不会堕落到底
  • 庶人
    1
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
看完了,铲


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 1 2 下一页 尾页
  • 34回复贴,共2页
  • ,跳到 页  
<<返回吉里吉里吧
分享到:
©2026 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示