图像遮罩

本指南讨论如何使用 graphics.newMask() 对单个显示对象或整个显示组进行遮罩。

概述

遮罩是数字设计中的常见做法。使用黑白(或灰度)图像遮罩,您可以根据遮罩的构成来显示/隐藏 显示对象显示组 的部分内容。例如,您可以创建一个带有白色部分和黑色部分的遮罩图像。当应用于目标对象/组时,遮罩的黑色部分将使底层像素完全透明(这在以下示例中由灰色棋盘格表示)。相反,遮罩图像白色部分后面的像素将保持完全可见。

 +   = 

遮罩图像也可以使用灰色区域或渐变创建。在这种情况下,80% 灰度的区域将以 20% 的不透明度渲染底层对象/组中的像素。类似地,10% 灰度的区域将以 90% 的不透明度渲染底层像素。

 +   = 

创建遮罩图像

可以使用任何标准图像编辑程序(如 Photoshop®、GIMPPaint.NET)创建遮罩图像文件。创建图像时,您**必须**遵守以下规则以确保遮罩正常工作。

遮罩图像要求
  • 遮罩图像的宽度和高度尺寸必须**可以被 4 整除**。

  • 遮罩图像的四边必须至少有 **3 像素** 的黑色空间作为边框。您可能需要增加遮罩图像的整体大小以包含此边框。

  • 如果遮罩图像小于目标图像,则遮罩边界外的区域将被完全遮罩(透明)。

应用遮罩

正确准备并保存遮罩文件后,下一步是使用 graphics.newMask() API 创建实际的遮罩。只需将遮罩图像文件的名称提供给函数,如下所示

local mask = graphics.newMask( "maskframe.png" )

接下来,使用 setMask() 函数将遮罩应用于您选择的对象

local mountains = display.newImageRect( "mountains.png", 280, 216 )
mountains.x, mountains.y = 200,160

mountains:setMask( mask )
 → 

如图所示,被黑色遮罩的照片区域不可见,而白色区域保持完全可见。照片和遮罩现在可以视为单个显示对象,并且像任何普通显示对象一样,可以移动、旋转、插入到显示组中等等。

请注意,即使示例照片由于遮罩而显得较小,但被遮罩对象的宽度和高度仍然与未遮罩版本相同。Solar2D 在大小和位置方面遵循原始尺寸。但是,除非您另行声明,否则对象完全遮罩(不可见)区域上的触摸/点击检测将被忽略 — 有关更多信息,请参阅下面的点击遮罩

重要

目前,遮罩图像不会根据设备分辨率动态选择,这与使用 display.newImageRect() 显示的图像不同。因此,如果您的遮罩非常详细,并且您需要为不同的设备选择合适分辨率的遮罩图像,则应检查 display.imageSuffix 并根据其值使用适当的遮罩图像。有关更多详细信息,请参阅 graphics.newMask() 中的示例。

遮罩操作

遮罩始终以 0 度角和 1:1 的比例应用于对象的默认锚点。但是,您可以在设置遮罩后对其进行操作,例如需要旋转/缩放它或更改其相对于图像/组的位置。

以下属性可用于遮罩操作

函数 描述
object.maskX 设置或检索遮罩的 **x** 位置。
object.maskY 设置或检索遮罩的 **y** 位置。
object.maskRotation 设置或检索遮罩的旋转角度。
object.maskScaleX 设置或检索遮罩的 **x** 缩放因子。
object.maskScaleY 设置或检索遮罩的 **y** 缩放因子。

此示例设置遮罩,将其 **x** 位置向左移动 10 像素,将其旋转 20 度,并将其缩小到正常大小的 80%

local mask = graphics.newMask( "maskframe.png" )

local mountains = display.newImageRect( "mountains.png", 280, 216 )
mountains.x, mountains.y = 200,160

mountains:setMask( mask )

mountains.maskX = -10
mountains.maskRotation = 20
mountains.maskScaleX = 0.8
mountains.maskScaleY = 0.8
 → 

组遮罩

如前所述,遮罩可以应用于 显示组 以及单个显示对象。

local group = display.newGroup()

local mask = graphics.newMask( "maskframe.png" )

group:setMask( mask )

group.maskX = group.x
group.maskY = group.y

点击遮罩

遮罩还可以用于防止在对象完全遮罩(不可见)的区域上进行触摸/点击响应。这对于被透明像素包围的标准、未遮罩的显示对象是不可能的。在这种情况下,对象将显示为小于其画布大小,但系统仍将识别透明区域上的用户输入。因此,在处理非常精确的触摸/点击识别时,解决方案是遮罩图像,使用 100% 黑色遮罩**不应**返回触摸或点击响应的区域。

在下面的正常、未遮罩图像中,系统将报告整个画布上的输入响应,包括由灰色棋盘格表示的透明像素。但是,如果您需要将用户输入限制为仅**可见**部分(图标本身),则遮罩是最佳解决方案。在此处显示的遮罩示例中,将在可见区域外忽略触摸/点击响应。

 + 

如果您需要覆盖此行为,但仍需要对对象进行遮罩,则可以通过将 object.isHitTestMasked 属性设置为 false 来指示系统识别遮罩对象**所有**区域上的用户输入

object.isHitTestMasked = false

动态遮罩选择

与图像和图像表单不同,Solar2D 不会根据屏幕分辨率自动加载不同的遮罩文件。遮罩的标准行为是随内容区域一起缩放。这使得基本的遮罩使用非常简单:提供一个遮罩图像文件,它将根据放置它的对象进行缩放。

但是,有时需要精确、清晰的遮罩图像,并且自动缩放在这种情况下并不理想。一种解决方案是使用 display.imageSuffix 检索内部图像后缀,并在创建遮罩时将其附加到文件参数中。有关详细信息,请参阅 graphics.newMask() 中的示例。

移除遮罩

要从对象中移除遮罩,只需调用 object:setMask( nil )。请记住,如果不再使用遮罩的句柄,也要将其设置为 nil

mountains:setMask( nil )
mask = nil