【Laya】Utils 工具类使用说明
Laya.Utils工具类摘要 Laya.Utils是LayaAir引擎提供的实用工具类,主要功能包括: 路径处理:获取文件扩展名(getFileExtension)、获取文件名(getBaseName)、替换扩展名(replaceFileExtension) 角度转换:角度转弧度(toRadian)、弧度转角度(toAngle) 数组操作:复制数组内容(copyArray) 其他实用功能:数值解
Laya.Utils 工具类使用说明
简介
Laya.Utils 是 LayaAir 引擎提供的静态工具类,包含各种实用的辅助方法,涵盖文件路径处理、颜色转换、角度/弧度转换、数组操作、异步任务管理等功能。
目录
路径处理
getFileExtension
获取文件扩展名,自动转换为小写字母。
static getFileExtension(path: string): string
参数:
path: 文件路径字符串
返回值: 文件扩展名(不含点号)
示例:
// 基本用法
let ext1 = Laya.Utils.getFileExtension("image.png"); // "png"
let ext2 = Laya.Utils.getFileExtension("photo.JPG"); // "jpg"
let ext3 = Laya.Utils.getFileExtension("archive.tar.gz"); // "gz"
let ext4 = Laya.Utils.getFileExtension("no_extension"); // ""
let ext5 = Laya.Utils.getFileExtension("path/to/file.png"); // "png"
// 实际应用:根据扩展名判断文件类型
function isImageFile(path: string): boolean {
let ext = Laya.Utils.getFileExtension(path);
return ["png", "jpg", "jpeg", "gif", "webp"].indexOf(ext) >= 0;
}
console.log(isImageFile("avatar.png")); // true
console.log(isImageFile("document.pdf")); // false
getBaseName
获取路径中的文件名,可选择是否包含扩展名。
static getBaseName(path: string, withoutExtension?: boolean): string
参数:
path: 文件路径字符串withoutExtension: 是否去除扩展名,默认false
返回值: 文件名
示例:
// 获取完整文件名(含扩展名)
let name1 = Laya.Utils.getBaseName("path/to/image.png"); // "image.png"
let name2 = Laya.Utils.getBaseName("/assets/sprite.ts"); // "sprite.ts"
let name3 = Laya.Utils.getBaseName("C:\\game\\data.json"); // "data.json"
// 获取不含扩展名的文件名
let name4 = Laya.Utils.getBaseName("path/to/image.png", true); // "image"
let name5 = Laya.Utils.getBaseName("hero.sprite.json", true); // "hero.sprite"
let name6 = Laya.Utils.getBaseName("archive.tar.gz", true); // "archive.tar"
// 实际应用:构建资源路径
function getTexturePath(textureName: string): string {
let baseName = Laya.Utils.getBaseName(textureName, true);
return `resources/textures/${baseName}.png`;
}
console.log(getTexturePath("hero.jpg")); // "resources/textures/hero.png"
replaceFileExtension
更改文件的扩展名。
static replaceFileExtension(path: string, newExt: string, excludeDot?: boolean): string
参数:
path: 原文件路径newExt: 新扩展名excludeDot: 是否排除点号,默认false
返回值: 替换扩展名后的新路径
示例:
// 基本用法
let path1 = Laya.Utils.replaceFileExtension("image.png", "jpg"); // "image.jpg"
let path2 = Laya.Utils.replaceFileExtension("data.json", "txt"); // "data.txt"
let path3 = Laya.Utils.replaceFileExtension("photo.JPG", "webp"); // "photo.webp"
// 使用 excludeDot 参数
let path4 = Laya.Utils.replaceFileExtension("file.txt", "json", true); // "filejson"
let path5 = Laya.Utils.replaceFileExtension("file.txt", "json", false); // "file.json"
// 实际应用:生成缩略图路径
function getThumbnailPath(originalPath: string): string {
return Laya.Utils.replaceFileExtension(originalPath, "thumb.png");
}
console.log(getThumbnailPath("uploads/photo.jpg")); // "uploads/photo.thumb.png"
角度/弧度转换
toRadian
将角度转换为弧度。
static toRadian(angle: number): number
参数:
angle: 角度值
返回值: 弧度值
示例:
// 基本用法
let rad1 = Laya.Utils.toRadian(0); // 0
let rad2 = Laya.Utils.toRadian(90); // Math.PI / 2 ≈ 1.5708
let rad3 = Laya.Utils.toRadian(180); // Math.PI ≈ 3.1416
let rad4 = Laya.Utils.toRadian(360); // Math.PI * 2 ≈ 6.2832
// 实际应用:使用 Math 三角函数计算
function shootBullet(angle: number, speed: number): { x: number; y: number } {
let rad = Laya.Utils.toRadian(angle);
return {
x: Math.cos(rad) * speed,
y: Math.sin(rad) * speed
};
}
let velocity = shootBullet(45, 100);
// velocity.x ≈ 70.71, velocity.y ≈ 70.71
// 注意:Laya.Sprite.rotation 属性直接使用角度,不需要转换
// 只有使用 Math.sin/cos/tan 等三角函数时才需要 toRadian
toAngle
将弧度转换为角度。
static toAngle(radian: number): number
参数:
radian: 弧度值
返回值: 角度值
示例:
// 基本用法
let deg1 = Laya.Utils.toAngle(0); // 0
let deg2 = Laya.Utils.toAngle(Math.PI / 2); // 90
let deg3 = Laya.Utils.toAngle(Math.PI); // 180
let deg4 = Laya.Utils.toAngle(Math.PI * 2); // 360
// 实际应用:显示对象旋转角度
function displayRotation(sprite: Laya.Sprite): string {
let degrees = Laya.Utils.toAngle(sprite.rotation);
return `旋转角度: ${degrees.toFixed(1)}°`;
}
// 计算两点之间的角度
function getAngleBetweenPoints(x1: number, y1: number, x2: number, y2: number): number {
let dx = x2 - x1;
let dy = y2 - y1;
return Laya.Utils.toAngle(Math.atan2(dy, dx));
}
let angle = getAngleBetweenPoints(0, 0, 1, 1); // 约 45 度
数组操作
copyArray
清空源数组,然后将另一个数组的值复制进去。
static copyArray(source: any[], array: any[]): any[]
参数:
source: 被清空并填充的源数组array: 要复制的数组
返回值: 复制后的 source 数组
示例:
// 基本用法
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
Laya.Utils.copyArray(arr1, arr2);
console.log(arr1); // [4, 5, 6]
console.log(arr2); // [4, 5, 6] (原数组不变)
// 实际应用:更新对象池
class GameObjectPool {
private activeObjects: any[] = [];
private inactiveObjects: any[] = [];
updateActive(newObjects: any[]): void {
Laya.Utils.copyArray(this.activeObjects, newObjects);
}
}
// 实际应用:刷新列表数据
class ItemList {
private items: any[] = [];
refreshData(newItems: any[]): void {
Laya.Utils.copyArray(this.items, newItems);
this.updateView();
}
private updateView(): void {
// 更新列表显示...
}
}
数值解析
parseInt
安全地解析字符串为整数,空值或非数字返回 0(而非 NaN)。
static parseInt(str: string, radix?: number): number
参数:
str: 要解析的字符串radix: 进制基数,默认 0
返回值: 解析后的整数,失败返回 0
示例:
// 与原生 parseInt 的对比
console.log(Laya.Utils.parseInt("123")); // 123
console.log(parseInt("123")); // 123
console.log(Laya.Utils.parseInt("")); // 0 (原生返回 NaN)
console.log(parseInt("")); // NaN
console.log(Laya.Utils.parseInt("abc")); // 0 (原生返回 NaN)
console.log(parseInt("abc")); // NaN
console.log(Laya.Utils.parseInt("45.67")); // 45
console.log(Laya.Utils.parseInt("0xFF")); // 255
// 实际应用:解析配置文件
interface GameConfig {
maxLevel: string;
playerCount: string;
difficulty: string;
}
function parseConfig(config: GameConfig): void {
let maxLevel = Laya.Utils.parseInt(config.maxLevel);
let playerCount = Laya.Utils.parseInt(config.playerCount);
let difficulty = Laya.Utils.parseInt(config.difficulty);
console.log(`最大关卡: ${maxLevel}, 玩家数: ${playerCount}, 难度: ${difficulty}`);
}
// 即使配置项缺失也不会导致 NaN
let config: GameConfig = {
maxLevel: "10",
playerCount: "",
difficulty: "abc"
};
parseConfig(config);
// 输出: 最大关卡: 10, 玩家数: 0, 难度: 0
// 实际应用:安全的数值输入处理
function processUserInput(input: string): number {
let value = Laya.Utils.parseInt(input);
if (value <= 0) {
console.warn("无效输入,使用默认值 1");
return 1;
}
return value;
}
异步工具
sleep
异步延迟指定毫秒数。
static sleep(timeout: number): Promise<void>
参数:
timeout: 延迟的毫秒数
返回值: Promise,延迟结束后 resolve
示例:
// 基本用法
async function example1() {
console.log("开始");
await Laya.Utils.sleep(1000);
console.log("1秒后");
}
// 实际应用:动画延迟效果
async function showTitleAnimation(sprite: Laya.Sprite): Promise<void> {
sprite.alpha = 0;
sprite.visible = true;
// 渐入效果
for (let i = 0; i <= 10; i++) {
sprite.alpha = i / 10;
await Laya.Utils.sleep(30);
}
}
// 实际应用:倒计时
async function countdown(seconds: number): Promise<void> {
for (let i = seconds; i > 0; i--) {
console.log(`${i}...`);
await Laya.Utils.sleep(1000);
}
console.log("时间到!");
}
// 实际应用:重试机制
async function fetchWithRetry<T>(
task: () => Promise<T>,
maxRetries: number = 3,
delay: number = 1000
): Promise<T> {
for (let i = 0; i < maxRetries; i++) {
try {
return await task();
} catch (error) {
if (i === maxRetries - 1) throw error;
console.log(`重试 ${i + 1}/${maxRetries}`);
await Laya.Utils.sleep(delay);
}
}
throw new Error("获取失败");
}
until
等待条件函数返回 true,或超时后结束。
static until(predicate: () => boolean, timeout?: number): Promise<void>
参数:
predicate: 判断函数,返回 true 时结束等待timeout: 超时时间(毫秒),可选
返回值: Promise
示例:
// 基本用法:等待资源加载完成
let resourceLoaded = false;
async function loadResource() {
// 模拟异步加载
Laya.timer.once(2000, this, () => {
resourceLoaded = true;
});
}
async function waitForResource() {
await Laya.Utils.until(() => resourceLoaded, 5000);
console.log("资源已加载");
}
// 实际应用:等待对象初始化
class AssetLoader {
private isReady = false;
load(url: string): void {
// 开始加载...
Laya.loader.load(url).then(() => {
this.isReady = true;
});
}
async waitReady(timeout: number = 10000): Promise<boolean> {
try {
await Laya.Utils.until(() => this.isReady, timeout);
return true;
} catch {
return false;
}
}
}
runTasks
并发执行多个任务,可控制并发数量。
static runTasks<T, T2>(
datas: Array<T2>,
numParallelTasks: number,
taskFunc: (data: T2, index: number) => T | Promise<T>
): Promise<T[]>
参数:
datas: 数据数组numParallelTasks: 并发任务数taskFunc: 对每个数据执行的任务函数
返回值: Promise<T[]>,包含所有任务的结果
示例:
// 基本用法:批量加载资源
async function loadImages(urls: string[]): Promise<Laya.Texture2D[]> {
return Laya.Utils.runTasks(
urls,
3, // 最多同时加载 3 个
async (url) => {
return await Laya.loader.load(url, Laya.Texture2D) as Laya.Texture2D;
}
);
}
// 实际应用:批量处理玩家数据
class Player {
async fetchStatsFromServer(): Promise<void> { /* ... */ }
updateUI(): void { /* ... */ }
}
async function updatePlayerStats(players: Player[]): Promise<void> {
await Laya.Utils.runTasks(
players,
5, // 每次处理 5 个玩家
async (player) => {
await player.fetchStatsFromServer();
player.updateUI();
}
);
}
runAllTasks
并发执行所有任务,返回所有任务的结果(包括失败的任务)。
static runAllTasks<T, T2>(
datas: Array<T2>,
numParallelTasks: number,
taskFunc: (data: T2, index: number) => T | Promise<T>
): Promise<PromiseSettledResult<T>[]>
参数:
datas: 数据数组numParallelTasks: 并发任务数taskFunc: 任务函数
返回值: Promise<PromiseSettledResult[]>
示例:
// 基本用法:批量处理,允许部分失败
async function loadAllImages(urls: string[]): Promise<void> {
let results = await Laya.Utils.runAllTasks(
urls,
3,
async (url) => {
return await Laya.loader.load(url, Laya.Texture2D) as Laya.Texture2D;
}
);
// 检查结果
results.forEach((result, index) => {
if (result.status === "fulfilled") {
console.log(`${urls[index]} 加载成功`);
} else {
console.error(`${urls[index]} 加载失败`);
}
});
}
字符串工具
parseTemplate
解析模板字符串,替换占位符为实际值。
static parseTemplate(template: string, vars: Record<string, any>): string
参数:
template: 包含占位符的模板字符串vars: 变量对象
返回值: 替换后的字符串
示例:
// 基本用法
let result1 = Laya.Utils.parseTemplate("Hello {name}!", { name: "World" });
// "Hello World!"
let result2 = Laya.Utils.parseTemplate("{greeting}, {name}!", {
greeting: "你好",
name: "玩家"
});
// "你好, 玩家!"
// 实际应用:生成动态消息
function generateMessage(template: string, data: any): string {
return Laya.Utils.parseTemplate(template, data);
}
let welcomeMsg = generateMessage(
"欢迎 {playerName}! 当前等级: {level}",
{ playerName: "勇者", level: 10 }
);
// "欢迎 勇者! 当前等级: 10"
// 实际应用:格式化日志
function formatLog(template: string, context: any): string {
let timestamp = new Date().toISOString();
return Laya.Utils.parseTemplate(`[${timestamp}] ${template}`, context);
}
console.log(formatLog("玩家 {name} 获得了 {exp} 经验", { name: "张三", exp: 100 }));
compareVersion
比较两个版本号字符串的大小。
static compareVersion(ver1: string, ver2: string): number
参数:
ver1: 版本号 1ver2: 版本号 2
返回值: 负数表示 ver1 < ver2,0 表示相等,正数表示 ver1 > ver2
示例:
// 基本用法
console.log(Laya.Utils.compareVersion("1.0.0", "1.0.1")); // < 0
console.log(Laya.Utils.compareVersion("1.0.1", "1.0.0")); // > 0
console.log(Laya.Utils.compareVersion("1.0.0", "1.0.0")); // 0
console.log(Laya.Utils.compareVersion("2.0.0", "1.9.9")); // > 0
// 实际应用:检查版本更新
class VersionChecker {
private currentVersion = "1.2.0";
needsUpdate(latestVersion: string): boolean {
return Laya.Utils.compareVersion(latestVersion, this.currentVersion) > 0;
}
checkCompatibility(requiredVersion: string): boolean {
return Laya.Utils.compareVersion(this.currentVersion, requiredVersion) >= 0;
}
}
let checker = new VersionChecker();
console.log(checker.needsUpdate("1.3.0")); // true
console.log(checker.checkCompatibility("1.0.0")); // true
isUUID
检查字符串是否为有效的 UUID 格式。
static isUUID(str: string): boolean
参数:
str: 要检查的字符串
返回值: 是否为有效 UUID
示例:
// 基本用法
console.log(Laya.Utils.isUUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8")); // true
console.log(Laya.Utils.isUUID("not-a-uuid")); // false
console.log(Laya.Utils.isUUID("")); // false
几何计算
testPointInPolygon
判断一个点是否在多边形内部。
static testPointInPolygon(x: number, y: number, areaPoints: number[]): boolean
参数:
x: 测试点的 X 坐标y: 测试点的 Y 坐标areaPoints: 多边形顶点坐标数组 [x1, y1, x2, y2, …]
返回值: 点是否在多边形内
示例:
// 定义一个三角形多边形
let triangle = [
100, 100, // 顶点 1
200, 100, // 顶点 2
150, 200 // 顶点 3
];
// 测试点是否在三角形内
console.log(Laya.Utils.testPointInPolygon(150, 150, triangle)); // true (在内部)
console.log(Laya.Utils.testPointInPolygon(50, 50, triangle)); // false (在外部)
// 实际应用:检测玩家是否在区域内
class GameZone {
private bounds: number[];
constructor(bounds: number[]) {
this.bounds = bounds;
}
contains(x: number, y: number): boolean {
return Laya.Utils.testPointInPolygon(x, y, this.bounds);
}
}
// 创建一个不规则游戏区域
let dangerZone = new GameZone([
0, 0, // 左上
300, 0, // 右上
350, 200, // 右中
300, 400, // 右下
0, 400 // 左下
]);
// 检查点是否在危险区域
if (dangerZone.contains(100, 100)) {
console.warn("进入危险区域!");
}
其他工具
getGID
为给定的对象-方法对生成全局唯一 ID。
static getGID(target: Object | null, method?: Function | string): string
参数:
target: 目标对象method: 方法或方法名,可选
返回值: 全局唯一 ID 字符串
示例:
class MyClass {
method1() {}
method2() {}
}
let obj = new MyClass();
let id1 = Laya.Utils.getGID(obj, obj.method1);
let id2 = Laya.Utils.getGID(obj, obj.method2);
console.log(id1); // 唯一 ID
console.log(id2); // 另一个唯一 ID
// 实际应用:事件处理器去重
class EventManager {
private handlerMap = new Map<string, Function>();
addHandler(target: Object, method: Function, callback: Function): void {
let id = Laya.Utils.getGID(target, method);
this.handlerMap.set(id, callback);
}
removeHandler(target: Object, method: Function): void {
let id = Laya.Utils.getGID(target, method);
this.handlerMap.delete(id);
}
}
完整示例
以下是一个综合使用 Laya.Utils 工具类的完整示例:
export async function main() {
await Laya.init( 800, 600 );
// 1. 创建精灵并绘制
let sprite = new Laya.Sprite();
sprite.graphics.drawRect(0, 0, 100, 100, "#ff0000", null, 1);
sprite.pos(350, 250);
Laya.stage.addChild(sprite);
// 2. 使用路径工具
let texturePath = "assets/image.png";
let ext = Laya.Utils.getFileExtension(texturePath);
let baseName = Laya.Utils.getBaseName(texturePath, true);
let newPath = Laya.Utils.replaceFileExtension(texturePath, "json");
console.log("文件名:", baseName, "扩展名:", ext, "新路径:", newPath);
// 3. 旋转动画
let rotation = 0;
let animate = () => {
rotation += 2;
if (rotation >= 360) rotation = 0;
sprite.rotation = rotation; // Sprite.rotation 直接使用角度
Laya.timer.frameOnce(1, null, animate);
};
animate();
// 4. 使用 parseTemplate
let message = Laya.Utils.parseTemplate(
"精灵已旋转 {angle} 度",
{ angle: rotation }
);
console.log(message);
// 5. 使用 parseInt
let level = Laya.Utils.parseInt("10");
console.log("当前等级:", level);
// 6. 测试点是否在多边形内
let polygon = [300, 200, 500, 200, 500, 400, 300, 400];
let isInside = Laya.Utils.testPointInPolygon(400, 300, polygon);
console.log("点在多边形内:", isInside);
// 7. 版本比较
let cmp = Laya.Utils.compareVersion("1.0.0", "1.0.1");
console.log("版本比较结果:", cmp);
}
注意事项
-
静态方法:
Utils类的所有方法都是静态的,不需要实例化即可使用。 -
parseInt 的安全性: 使用
Laya.Utils.parseInt()而非原生parseInt()可以避免 NaN 的问题,更适合处理用户输入或配置文件。 -
异步操作:
sleep(),until(),runTasks()等方法返回 Promise,需要在 async 函数中使用。 -
在调用
Math.sin()、Math.cos()等三角函数时可以用toRadian()转换。 -
版本比较:
compareVersion()期望版本号格式为 “x.y.z” 的点分格式。
更多推荐



所有评论(0)