版本:2.4.10
一 显示效果
二 实现原理
三 刮刮卡实现
一 显示效果

二 实现原理
实现是利用一张纯灰色cover图片盖在谢谢惠顾图片上方,将图片cover放在cc.Mask节点下进行遮罩。
将cc.Mask设置为反向遮罩,并设置高宽为0,并使用Mask的cc.Graphcis进行线段绘制,这样有线段的地方灰色图片cover就会透明,露出下方的"谢谢惠顾"。
无遮罩 正常遮罩 反向遮罩

三 刮刮卡实现
创建空节点cc.Node,命名为mask,从右边属性面板选择添加组件-渲染组件-Mask。(直接在cc.Node上右键创建节点-渲染组件-是没有Mask的)

设置mask高宽为0,勾选反向遮罩Inverted,遮罩方式Type选择RECT。

找一张纯灰色图片

将图片放在mask节点下

因为反向遮罩是遮挡的地方才会变透明,当mask高宽为0时啥也没遮挡,这时cover图片是可以全部看见的。

尝试把mask高宽修改成50x50,可以看到会透明了一个50x50的矩形。(实际运行时记得把mask高宽改回成0)

把谢谢惠顾图片放在cover图片下


代码中获取mask的属性_graphics(转换成any才能获取,因为这个属性没有暴露出来)
根据触摸的移动,使用moveTo()和lineTo进行绘制线段,有线段的部分就会露出下方的"谢谢惠顾"。
let graphics: cc.Graphics = (this.mask as any)._graphics; graphics.lineWidth = 20; graphics.lineCap = cc.Graphics.LineCap.ROUND; graphics.lineJoin = cc.Graphics.LineJoin.ROUND; graphics.strokeColor = cc.color(255, 255, 255, 255); graphics.moveTo(pos.x, pos.y); graphics.lineTo(pos.x, pos.y); graphics.stroke();
完整代码:
封装的刮刮卡类, GuaGuaKa.ts:
const { ccclass, property } = cc._decorator;
/**
* 刮刮卡
* @author chenkai 2022.9.27
*/
@ccclass
export default class GuaGuaKa {
/**遮罩 */
private mask: cc.Mask = null;
/**覆盖图片 */
private cover: cc.Node = null;
/**
* 初始化
* @param mask 遮罩
* @param cover 覆盖图片
*/
public init(mask: cc.Mask, cover: cc.Node) {
this.mask = mask;
this.cover = cover;
this.reset();
}
/**开始 */
public begin() {
//设置线段
let graphics: cc.Graphics = (this.mask as any)._graphics;
graphics.lineWidth = 20;
graphics.lineCap = cc.Graphics.LineCap.ROUND;
graphics.lineJoin = cc.Graphics.LineJoin.ROUND;
graphics.strokeColor = cc.color(255, 255, 255, 255);
//触摸事件
this.cover.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
this.cover.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
}
/**停止 */
public stop() {
this.cover.off(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
this.cover.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
}
/**重置 */
public reset() {
let graphics: cc.Graphics = (this.mask as any)._graphics;
graphics.clear();
}
/**触摸开始 */
private onTouchStart(e: cc.Event.EventTouch) {
//记录触摸起始点,将触摸点世界坐标转成cover本地坐标
let pos = this.cover.convertToNodeSpaceAR(e.getLocation());
//将画线起点移动到触摸起始点
let graphics: cc.Graphics = (this.mask as any)._graphics;
graphics.moveTo(pos.x, pos.y);
}
/**触摸移动 */
private onTouchMove(e: cc.Event.EventTouch) {
//将触摸点世界坐标转成cover本地坐标
let pos = this.cover.convertToNodeSpaceAR(e.getLocation());
//画线
let graphics: cc.Graphics = (this.mask as any)._graphics;
graphics.lineTo(pos.x, pos.y);
graphics.stroke();
}
/**销毁 */
public dispose() {
this.stop();
this.mask = null;
this.cover = null;
}
}
主场景 Main.ts:
import GuaGuaKa from "./GuaGuaKa";
const { ccclass, property } = cc._decorator;
/**
* 刮刮卡
* @author chenkai 2022.9.27
*/
@ccclass
export default class MainScene extends cc.Component {
@property({ type: cc.Mask, tooltip: "遮罩" })
mask: cc.Mask = null;
@property({ type: cc.Node, tooltip: "纯灰色图片" })
cover: cc.Node = null;
/**刮刮卡 */
private guaguaKa: GuaGuaKa;
public onLoad() {
this.guaguaKa = new GuaGuaKa();
this.guaguaKa.init(this.mask, this.cover);
this.guaguaKa.begin();
}
}
浙公网安备 33010602011771号