krkr2 中文文档 下载 App

TJS2 深入引擎:Layer、Image、Wave 实战

为什么需要直接调用原生类

KAG 标签覆盖了 80% 的常用场景。当你需要做这些事时,就需要下沉到 TJS2 + 原生类:

Layer 图层操作

获取和创建图层

// 获取当前活动图层(通常是文字框所在图层)
var current = Layer.getCurrent();

// 通过编号获取
var bgLayer = Layer.get(0);
var charaLayer = Layer.get(1);

// 创建新图层(返回图层对象)
var customLayer = Layer.create();
customLayer.number = 10;  // 设置图层编号
customLayer.show();

图层属性

layer.x = 100;         // 左上角 X 坐标
layer.y = 200;         // 左上角 Y 坐标
layer.width = 800;     // 宽度
layer.height = 600;    // 高度
layer.opacity = 128;   // 不透明度 0~255
layer.visible = true;  // 是否可见
layer.z = 5;           // Z 轴(用于 3D 层次,罕见)

图层操作方法

// 加载图片到图层
layer.loadImage("image/bg/school.tlg");

// 在图层上绘制(和上一层合成)
layer.blit(targetLayer, sourceX, sourceY, destX, destY, width, height);

// 清空图层
layer.clear();

// 移动动画
layer.moveTo(500, 300, 1000);  // 1000ms 内移动到目标位置

// 缩放动画
layer.scaleTo(1.5, 1.5, 500);  // 500ms 内放大到 150%

// 淡出
layer.fadeOut(500);

// 淡入
layer.fadeIn(500);

// 销毁图层
layer.destroy();

Image 图片操作

// 加载图片(返回 Image 对象)
var bg = Image.load("image/bg/sky.tlg");
var hero = Image.load("image/chara/hero.png");

// 图片属性
bg.width;       // 宽度
bg.height;      // 高度
hero.hasAlpha;  // 是否有透明通道

// 图片绘制到图层
bgLayer.drawImage(bg, 0, 0);
charaLayer.drawImage(hero, 100, 200);

// 裁剪绘制(只画图片的一部分)
charaLayer.drawImage(hero, 0, 0, 0, 0, 300, 400);
// 参数:图片对象, destX, destY, srcX, srcY, srcWidth, srcHeight

动态生成图片

// 创建空白图片
var canvas = new Image(800, 600);

// 画渐变
for (var i = 0; i < 800; i++) {
    canvas.fillRect(i, 0, 1, 600, RGB(i / 800 * 255, 0, 255 - i / 800 * 255));
}

// 绘制文字
canvas.drawText("标题文字", 400, 300, font, RGB(255, 255, 255));

Wave 音频操作

播放 BGM

// 播放 BGM(循环)
Wave.playBGM("sound/bgm/title.ogg", true);

// 播放 SE(一次)
Wave.playSE("sound/se/click.wav");

// 播放语音
Wave.playVoice("sound/voice/hero_001.wav");

控制播放

// 停止 BGM
Wave.stopBGM();

// 淡出停止
Wave.fadeBGM(500);

// 暂停/恢复
Wave.pauseBGM();
Wave.resumeBGM();

// 设置音量
Wave.setBGMVolume(0.5);  // 0.0 ~ 1.0
Wave.setSEVolume(0.8);

多音频通道

吉里吉里2 支持同时播放多个 BGM:

Wave.playBGM("sound/bgm/main.ogg", true);     // BGM 通道 0
Wave.playBGM2("sound/bgm/sub.ogg", true);     // BGM 通道 1(混音播放)
Wave.setBGMVolume(0.7);
Wave.setBGM2Volume(0.3);

Storage 文件操作

// 检查文件是否存在
Storage.exists("scenario/main.ks");

// 读取文本文件
var content = Storage.readTextFile("scenario/main.ks");

// 写入文本(注意权限和路径)
Storage.writeTextFile("save/custom.txt", "hello");

// 打开 XP3 包
Storage.openArchive("data.xp3");
// 之后直接用 Storage.readTextFile() 就能读包里的文件了

// 关闭归档
Storage.closeArchive();

// 列出目录文件
var files = Storage.listFiles("image/bg/");

Script 动态加载

// 运行时加载额外脚本
Script.load("script/ExtraContent.tjs");

// 从 XP3 包里加载(先 openArchive)
Script.load("data.xp3/script/extra.tjs");

// 动态执行一段代码字符串
Script.eval("var x = 42; Layer.current.message = x;");

用户输入检测

// 键盘检测
Script.onKeyDown = function(key) {
    if (key == 0x0D) {  // Enter 键
        Layer.current.message = "按了回车";
    }
};

// 鼠标位置
Script.onMouseMove = function(x, y) {
    // Layer.current.message = "鼠标: " + x + "," + y;
};

// 鼠标点击
Script.onMouseDown = function(x, y, button) {
    if (button == 0) {  // 左键
        Layer.current.message = "左键点击 @ " + x + "," + y;
    }
};

实战:自定义对话框

// 创建一个带边框和滚动条的对话框
function createMessageBox(x, y, w, h) {
    var box = Layer.create();
    box.number = 20;
    box.x = x; box.y = y;
    box.width = w; box.height = h;
    
    // 画半透明背景
    box.fillRect(0, 0, w, h, RGBA(0, 0, 0, 180));
    
    // 画边框
    box.frameRect(0, 0, w, h, 2, RGB(255, 255, 255));
    
    box.show();
    return box;
}

var msgBox = createMessageBox(50, 400, 700, 150);

注意事项