【Laya】经典UI Sprite介绍
Sprite是LayaAir引擎的核心2D显示对象类,支持图形绘制、变换操作和容器功能。主要特性包括:通过graphics绘制矢量图、支持旋转/缩放/位移等变换、可作为容器添加子节点、具备渲染优化和鼠标交互功能。常用属性涵盖位置尺寸(x,y,width,height)、锚点轴心(pivotX/Y,anchorX/Y)、变换(scaleX/Y,rotation)、显示(visible,alpha)等
·
经典UI Sprite介绍
一、概述
Sprite(精灵)是 LayaAir 引擎中基本的显示图形的显示列表节点。它是2D游戏开发中最核心的显示对象类,所有2D UI节点对象都继承自 Sprite 类。
主要特性
- 显示图形:通过
graphics可以绘制图片或者矢量图 - 变换操作:支持旋转、缩放、位移、倾斜等操作
- 容器功能:可作为容器添加多个子节点
- 渲染优化:针对不同场景做了渲染优化,保证丰富功能的同时实现高性能
- 鼠标交互:支持完整的鼠标事件系统
类继承关系
Node
└─ Sprite
├─ Scene
├─ Box
├─ Image
├─ Label
├─ Button
└─ ... (其他2D显示对象)
二、属性详解
2.1 位置与尺寸属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
x |
number | 0 | 相对于父容器的X轴坐标值 |
y |
number | 0 | 相对于父容器的Y轴坐标值 |
width |
number | 0 | 节点的宽度(像素) |
height |
number | 0 | 节点的高度(像素) |
displayWidth |
number | - | 对象的显示宽度,包含X轴缩放(只读) |
displayHeight |
number | - | 对象的显示高度,包含Y轴缩放(只读) |
// 设置位置
sprite.x = 100;
sprite.y = 200;
// 或者使用链式调用
sprite.pos(100, 200);
// 设置尺寸
sprite.width = 512;
sprite.height = 256;
// 或者使用链式调用
sprite.size(512, 256);
2.2 锚点与轴心点
**轴心点(Pivot)和锚点(Anchor)**是控制精灵变换中心的重要属性。
| 属性 | 类型 | 说明 |
|---|---|---|
pivotX |
number | X轴轴心点位置(像素),默认为0 |
pivotY |
number | Y轴轴心点位置(像素),默认为0 |
anchorX |
number | X轴锚点,取值范围0-1 |
anchorY |
number | Y轴锚点,取值范围0-1 |
// 设置轴心点(以像素为单位)
sprite.pivotX = 100;
sprite.pivotY = 50;
// 或使用链式调用
sprite.pivot(100, 50);
// 设置锚点(相对于宽高的比例,0-1)
sprite.anchorX = 0.5; // 水平中心
sprite.anchorY = 0.5; // 垂直中心
// 或使用链式调用
sprite.anchor(0.5, 0.5);
注意:修改锚点
anchor会自动修改轴心点pivot,是改变轴心点的便捷方式。
2.3 变换属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
scaleX |
number | 1 | X轴缩放比例,负数可实现水平翻转 |
scaleY |
number | 1 | Y轴缩放比例,负数可实现垂直翻转 |
rotation |
number | 0 | 旋转角度(度),正数顺时针 |
skewX |
number | 0 | 水平倾斜角度(度) |
skewY |
number | 0 | 垂直倾斜角度(度) |
transform |
Matrix | - | 变换矩阵信息 |
// 设置缩放
sprite.scaleX = 2;
sprite.scaleY = 2;
// 或链式调用
sprite.scale(2, 2);
// 设置旋转
sprite.rotation = 45; // 顺时针旋转45度
// 设置倾斜
sprite.skewX = 5;
sprite.skewY = 5;
// 或链式调用
sprite.skew(5, 5);
// 水平翻转
sprite.scaleX = -1;
// 垂直翻转
sprite.scaleY = -1;
2.4 显示属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
visible |
boolean | true | 对象是否可见 |
alpha |
number | 1 | 透明度,0-1,1为不透明 |
blendMode |
BlendMode | null | 混合模式,常用值为 “lighter” |
// 设置可见性
sprite.visible = true;
// 设置透明度
sprite.alpha = 0.5;
// 设置混合模式(颜色叠加)
sprite.blendMode = "lighter";
2.5 渲染与内容属性
| 属性 | 类型 | 说明 |
|---|---|---|
texture |
Texture | 纹理对象,设置后显示图片 |
graphics |
Graphics | 绘图对象,用于绘制矢量图形 |
material |
Material | 2D精灵材质 |
// 方式1:设置纹理
sprite.texture = texture;
// 方式2:从URL加载图片
sprite.loadImage("resources/image.png");
// 方式3:使用Graphics绘制
sprite.graphics.drawRect(0, 0, 100, 100, "#FF0000");
2.6 缓存与性能优化属性
| 属性 | 类型 | 说明 |
|---|---|---|
cacheAs |
string | 缓存模式:无/“none”、正常/“normal”、位图/“bitmap” |
drawCallOptimize |
boolean | 是否自动优化DrawCall |
autoSize |
boolean | 是否自动计算宽高 |
// 缓存为位图(减少DrawCall,增加内存)
sprite.cacheAs = "bitmap";
// 开启DrawCall优化
sprite.drawCallOptimize = true;
// 自动计算宽高
sprite.autoSize = true;
2.7 交互属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
mouseEnabled |
boolean | false | 是否接受鼠标事件 |
mouseThrough |
boolean | false | 空白区域是否可穿透 |
hitTestPrior |
boolean | false | 是否优先检测自身 |
hitArea |
IHitArea | null | 自定义点击区域 |
// 启用鼠标事件
sprite.mouseEnabled = true;
// 空白区域可穿透
sprite.mouseThrough = true;
// 优先检测自身
sprite.hitTestPrior = true;
// 设置自定义点击区域
let hitArea = new Laya.HitArea();
hitArea.hit.drawRect(0, 0, 100, 100, "#00ff00");
sprite.hitArea = hitArea;
2.8 层级属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
zOrder |
number | 0 | Z排序,值越大越靠前 |
zIndex |
number | 0 | 渲染排序 |
layer |
number | - | 遮罩层 |
// 设置显示层级
sprite.zOrder = 10;
2.9 其他属性
| 属性 | 类型 | 说明 |
|---|---|---|
mask |
Sprite | 遮罩对象 |
scrollRect |
Rectangle | 滚动矩形范围(带裁剪效果) |
filters |
Filter[] | 滤镜集合(已废弃,使用postProcess) |
postProcess |
PostProcess2D | 后处理效果 |
三、方法详解
3.1 对象管理方法
// 销毁精灵
sprite.destroy(destroyChild?: boolean): void;
// 获取父节点
sprite.parent: Sprite;
// 获取所属场景
sprite.scene: Scene;
3.2 位置设置方法(链式调用)
// 设置位置
sprite.pos(x: number, y: number): this;
// 设置轴心点
sprite.pivot(x: number, y: number): this;
// 设置锚点
sprite.anchor(x: number, y: number): this;
// 设置尺寸
sprite.size(width: number, height: number): this;
// 设置缩放
sprite.scale(x: number, y: number): this;
// 设置倾斜
sprite.skew(x: number, y: number): this;
// 链式调用示例
sprite.pos(100, 100)
.size(200, 200)
.scale(2, 2)
.rotation = 45;
3.3 绘图相关方法
// 加载并显示图片
sprite.loadImage(url: string, complete?: Handler): this;
// 静态方法:根据图片URL创建Sprite
Laya.Sprite.fromImage(url: string): Sprite;
// 设置Graphics对象
sprite.setGraphics(value: Graphics, transferOwnership?: boolean): void;
3.4 坐标转换方法
// 本地坐标转全局坐标
sprite.localToGlobal(point: Point, createNewPoint?: boolean, globalNode?: Sprite): Point;
// 全局坐标转本地坐标
sprite.globalToLocal(point: Point, createNewPoint?: boolean, globalNode?: Sprite): Point;
// 本地坐标转父容器坐标
sprite.toParentPoint(point: Point): Point;
// 父容器坐标转本地坐标
sprite.fromParentPoint(point: Point): Point;
3.5 边界获取方法
// 获取在父容器坐标系的矩形显示区域
sprite.getBounds(out?: Rectangle): Rectangle;
// 获取在自己坐标系的矩形显示区域
sprite.getSelfBounds(out?: Rectangle, recursive?: boolean): Rectangle;
// 获取绘制内容的矩形区域
sprite.getGraphicBounds(realSize?: boolean, out?: Rectangle): Rectangle;
// 设置对象边界(提高性能)
sprite.setSelfBounds(bound: Rectangle): void;
3.6 碰撞检测方法
// 检测点是否在对象内
sprite.hitTestPoint(x: number, y: number): boolean;
// 获取鼠标在对象上的坐标
sprite.getMousePoint(): Readonly<Point>;
sprite.mouseX: number;
sprite.mouseY: number;
3.7 缓存刷新方法
// 刷新缓存(在cacheAs启用时)
sprite.reCache(): void;
// 重新绘制
sprite.repaint(flag?: number): void;
// 清除重绘标志
sprite.clearRepaint(): void;
3.8 拖拽方法
// 开始拖拽
sprite.startDrag(
area?: Rectangle, // 拖动区域
hasInertia?: boolean, // 是否有惯性
elasticDistance?: number, // 橡皮筋效果距离
elasticBackTime?: number, // 回弹时间(毫秒)
data?: any, // 携带的数据
ratio?: number // 惯性阻尼系数
): void;
// 停止拖拽
sprite.stopDrag(): void;
3.9 渲染方法
// 绘制到RenderTexture2D(推荐使用)
sprite.drawToRenderTexture2D(
canvasWidth: number,
canvasHeight: number,
offsetX: number,
offsetY: number,
rt?: RenderTexture2D,
isDrawRenderRect?: boolean,
flipY?: boolean,
clearColor?: Color,
renderScaleX?: number,
renderScaleY?: number
): RenderTexture2D;
// 静态方法:绘制指定Sprite
Laya.Sprite.drawToRenderTexture2D(
sprite: Sprite,
canvasWidth: number,
canvasHeight: number,
...
): RenderTexture2D;
四、事件列表
Sprite 支持以下鼠标事件:
| 事件名 | 说明 |
|---|---|
Event.MOUSE_DOWN |
鼠标按下 |
Event.MOUSE_UP |
鼠标抬起 |
Event.MOUSE_MOVE |
鼠标移动 |
Event.MOUSE_OVER |
鼠标移入 |
Event.MOUSE_OUT |
鼠标移出 |
Event.MOUSE_DRAG |
鼠标拖拽 |
Event.MOUSE_DRAG_END |
拖拽结束 |
Event.CLICK |
点击 |
Event.RIGHT_MOUSE_DOWN |
右键按下 |
Event.RIGHT_MOUSE_UP |
右键抬起 |
Event.RIGHT_CLICK |
右键点击 |
Event.DOUBLE_CLICK |
双击 |
Event.DRAG_START |
开始拖拽 |
Event.DRAG_MOVE |
拖拽移动 |
Event.DRAG_END |
拖拽结束 |
Event.DROP |
放置 |
Event.TRANSFORM_CHANGED |
变换改变 |
// 事件监听示例
sprite.on(Laya.Event.CLICK, this, () => {
console.log("Sprite被点击");
});
sprite.on(Laya.Event.MOUSE_DOWN, this, (e: Laya.Event) => {
console.log("鼠标位置:", e.stageX, e.stageY);
});
五、使用示例
5.1 创建并显示精灵
// 创建精灵实例
let sprite = new Laya.Sprite();
// 添加到舞台
Laya.stage.addChild(sprite);
// 加载图片
sprite.loadImage("resources/image.png");
// 设置位置
sprite.pos(Laya.stage.width / 2, Laya.stage.height / 2);
5.2 使用纹理显示图片
// 先加载资源
Laya.loader.load("resources/image.png").then(() => {
let sprite = new Laya.Sprite();
// 获取已加载的纹理
let texture = Laya.loader.getRes("resources/image.png");
sprite.texture = texture;
// 设置位置并添加到舞台
sprite.pos(100, 100);
Laya.stage.addChild(sprite);
});
5.3 绘制矢量图形
let sprite = new Laya.Sprite();
// 绘制矩形
sprite.graphics.drawRect(0, 0, 100, 100, "#FF0000");
// 绘制圆形
sprite.graphics.drawCircle(150, 50, 30, "#00FF00");
// 绘制线条
sprite.graphics.drawLine(200, 0, 200, 100, "#0000FF", 2);
Laya.stage.addChild(sprite);
5.4 设置遮罩
let sprite = new Laya.Sprite();
sprite.loadImage("resources/image.png");
Laya.stage.addChild(sprite);
// 创建遮罩(圆形)
let mask = new Laya.Sprite();
mask.graphics.drawCircle(50, 50, 50, "#FFFFFF");
sprite.addChild(mask);
// 应用遮罩
sprite.mask = mask;
5.5 链式调用示例
let sprite = new Laya.Sprite();
// 链式设置多个属性
sprite.pos(200, 200)
.size(100, 100)
.pivot(50, 50)
.scale(2, 2)
.skew(5, 5);
Laya.stage.addChild(sprite);
5.6 拖拽功能
let sprite = new Laya.Sprite();
sprite.loadImage("resources/image.png");
Laya.stage.addChild(sprite);
// 设置拖拽区域(整个屏幕)
let dragArea = new Laya.Rectangle(0, 0, Laya.stage.width, Laya.stage.height);
// 开始拖拽
sprite.startDrag(dragArea, true, 100, 300);
5.7 自定义点击区域
let sprite = new Laya.Sprite();
sprite.loadImage("resources/image.png");
// 创建自定义点击区域
let hitArea = new Laya.HitArea();
hitArea.hit.drawCircle(50, 50, 50, "#00ff00"); // 可点击区域(圆形)
hitArea.unHit.drawRect(30, 30, 40, 40, "#ff0000"); // 不可点击区域
sprite.hitArea = hitArea;
sprite.mouseEnabled = true;
// 监听点击事件
sprite.on(Laya.Event.CLICK, this, () => {
console.log("点击了有效区域");
});
Laya.stage.addChild(sprite);
六、性能优化建议
6.1 使用 cacheAs 优化
// 对于不常变化的复杂UI,使用cacheAs="bitmap"
sprite.cacheAs = "bitmap";
- “none”:不缓存,默认值
- “normal”:命令缓存,减少遍历开销
- “bitmap”:位图缓存,大幅减少DrawCall,增加内存开销
6.2 使用 DrawCall 优化
// 自动合并同图集图片
sprite.drawCallOptimize = true;
注意:元素数量过大(>500)时会消耗较多CPU性能。
6.3 合理使用 hitArea
// 对于非矩形点击区域,使用hitArea代替宽高检测
sprite.hitArea = customHitArea;
6.4 避免频繁计算边界
// 设置固定边界,避免getBounds计算
sprite.setSelfBounds(new Laya.Rectangle(0, 0, 100, 100));
七、注意事项
-
mouseEnabled 自动设置:监听鼠标事件时会自动将对象及父节点的
mouseEnabled设为true -
cacheAs 位图限制:
- 缓存位图最大尺寸为 2048×2048
- 频繁重绘会增加 CPU 开销
-
纹理 vs Graphics:
- 显示单个图片时,使用
texture性能最高 - 矢量图形使用
graphics绘制
- 显示单个图片时,使用
-
遮罩使用:
- 遮罩对象需是显示对象的子节点
- 只有
Sprite的texture属性支持设置 RenderTexture
-
坐标系统:
- 原点在左上角
- X轴向右为正
- Y轴向下为正
八、相关类图
Sprite (laya.display.Sprite)
├── 属性
│ ├── x, y 位置
│ ├── width, height 尺寸
│ ├── pivotX, pivotY 轴心点
│ ├── anchorX, anchorY 锚点
│ ├── scaleX, scaleY 缩放
│ ├── rotation 旋转
│ ├── skewX, skewY 倾斜
│ ├── alpha 透明度
│ ├── visible 可见性
│ ├── texture 纹理
│ ├── graphics 绘图对象
│ ├── cacheAs 缓存
│ └── mask 遮罩
├── 方法
│ ├── pos() 设置位置
│ ├── size() 设置尺寸
│ ├── scale() 设置缩放
│ ├── pivot() 设置轴心点
│ ├── anchor() 设置锚点
│ ├── loadImage() 加载图片
│ ├── localToGlobal() 坐标转换
│ ├── getBounds() 获取边界
│ ├── startDrag() 开始拖拽
│ └── reCache() 刷新缓存
└── 事件
├── CLICK 点击
├── MOUSE_DOWN 鼠标按下
├── MOUSE_UP 鼠标抬起
├── MOUSE_OVER 鼠标移入
├── MOUSE_OUT 鼠标移出
└── ...
参考文档
更多推荐


所有评论(0)