刮刮乐(cocoscreator2.4.3)
最终效果
结构
1.num下面放了对应的十个数字
2.一个mask节点,添加mask组件,inverted勾选上,这个界面大小设置为0,否则会影响位置判断
3.mask下面是最上层遮挡数字的图片,即粉红色图片
代码
1.编辑一个Mask脚本,一个是mask节点,一个是刮卡的circle半径大小,还有一个是用来判断是否刮到了目标位置,如果在value范围内则判定为刮到目标位置
positionProgress为目标点是否被刮到,类型为Array,当所有的值全为true时,判定为所有区域全部刮完,显示全部内容
positions存储的是所有目标点的位置,我这里存了十个目标点
此处所定下来的十个点(positions)的位置会因为parent的大小以及位置改变发生变化,需要自己去输出判断具体是哪些位置,对应起来即可!
@property(cc.Node)
myMask: cc.Node = null;
@property({
displayName: "刮卡路径大小",
min: 20
})
size: number = 20;
@property({ tooltip: "分片后阈值:\n结果判断会依赖此值", type: cc.Integer })
value = 40;
protected positionProgress: Boolean[] = null;
protected positions: cc.Vec2[] = null;
2.初始化
监听按钮事件以及存储 positions
下面是十个点的位置,将其存储下来用于计算
positionProgress 的length和positions的长度相对应起来
onLoad() {
this.node.on(cc.Node.EventType.TOUCH_START, this._onTouchBegin, this);
this.node.on(cc.Node.EventType.TOUCH_MOVE, this._onTouchMoved, this);
this.node.on(cc.Node.EventType.TOUCH_END, this._onTouchEnd, this);
//因为我的parent大小为(300,150),位置为y轴 -82,所以 这些点要去 parent一半,四分之一这些位置
let position = this.node.position;
let left_1 = 125;
let left_2 = 65;
let right_1 = 125;
let right_2 = 65;
let up = 125;
let up_1 = 45;
this.positions = [
cc.v2(position.x, position.y + up_1), // 下中
cc.v2(position.x - left_1, position.y + up_1), // 下左1
cc.v2(position.x - left_2, position.y + up_1), // 下左2
cc.v2(position.x + right_1, position.y + up_1), // 下右1
cc.v2(position.x + right_2, position.y + up_1), // 下右2
cc.v2(position.x, position.y + up), // 上中
cc.v2(position.x - left_1, position.y + up), // 上左1
cc.v2(position.x - left_2, position.y + up), // 上左2
cc.v2(position.x + right_1, position.y + up), // 上右1
cc.v2(position.x + right_2, position.y + up), // 上右2
];
this.positionProgress = new Array(this.positions.length);
}
3.处理刮图逻辑
_onTouchBegin(event) {
var point = event.touch.getLocation();
point = this.node.convertToNodeSpaceAR(point);
this._addCircle(point);
}
_onTouchMoved(event) {
var point = event.touch.getLocation();
point = this.node.convertToNodeSpaceAR(point);
this._addCircle(point);
}
_onTouchEnd(event) {
var point = event.touch.getLocation();
point = this.node.convertToNodeSpaceAR(point);
this._addCircle(point);
this._checkProgress();
}
/**绘制函数*/
graphics: cc.Graphics;
_addCircle(point) {
// console.log("point---", point);
this.graphics = this.myMask.getComponent(cc.Mask)._graphics;
this._checkPoint(point);
this.graphics.circle(point.x, point.y, this.size);
this.graphics.fill();
}
4.检查是否刮到了目标点,如果是,将positionProgress中对应的值置为true
private _checkPoint(point: cc.Vec2) {
for (let i = 0; i < 10; i++) {
let p = this.positions[i];
// 此点在关键点附近
if (p.x + this.value > point.x && p.x - this.value < point.x && p.y + this.value > point.y && p.y - this.value < point.y) {
this.positionProgress[i] = true;
}
console.log("p---", i, this.positionProgress[i]);
}
}
当输出p—后,展示效果为,i为1时,对应的是左下1的位置,i为2时对应左下2的位置,可以看到这两个值已经变为true了,下面继续刮图
这是将下面一排全部刮完的输出,可以看到 0-5已经变为true了
全部刮完后,所有的值都变为true,检测的result也已经变为true,在执行挂完以后的奖励就可以了
5.检测是否所有的区域都刮到的代码,positionProgress为true的length等于positions长度的时候即为刮完所有目标点,隐藏mask节点下的遮挡图,显示全部内容
private _checkProgress() {
let result = this.positionProgress.filter((value) => {
return value;
}).length === this.positions.length;
console.log("result---", result);
if (result) {
this.myMask.children[0].active = false;
}
}
Mask所有代码如下,将代码挂在parent上,功能就实现了
const { ccclass, property } = cc._decorator;
@ccclass
export default class NewClass extends cc.Component {
@property(cc.Node)
myMask: cc.Node = null;
@property({
displayName: "刮卡路径大小",
min: 20
})
size: number = 20;
@property({ tooltip: "分片后阈值:\n结果判断会依赖此值", type: cc.Integer })
value = 40;
protected positionProgress: Boolean[] = null;
protected positions: cc.Vec2[] = null;
onLoad() {
this.node.on(cc.Node.EventType.TOUCH_START, this._onTouchBegin, this);
this.node.on(cc.Node.EventType.TOUCH_MOVE, this._onTouchMoved, this);
this.node.on(cc.Node.EventType.TOUCH_END, this._onTouchEnd, this);
let position = this.node.position;
let left_1 = 125;
let left_2 = 65;
let right_1 = 125;
let right_2 = 65;
let up = 125;
let up_1 = 45;
this.positions = [
cc.v2(position.x, position.y + up_1), // 下中
cc.v2(position.x - left_1, position.y + up_1), // 下左1
cc.v2(position.x - left_2, position.y + up_1), // 下左2
cc.v2(position.x + right_1, position.y + up_1), // 下右1
cc.v2(position.x + right_2, position.y + up_1), // 下右2
cc.v2(position.x, position.y + up), // 上中
cc.v2(position.x - left_1, position.y + up), // 上左1
cc.v2(position.x - left_2, position.y + up), // 上左2
cc.v2(position.x + right_1, position.y + up), // 上右1
cc.v2(position.x + right_2, position.y + up), // 上右2
];
this.positionProgress = new Array(this.positions.length);
}
/**鼠标事件 */
_onTouchBegin(event) {
var point = event.touch.getLocation();
point = this.node.convertToNodeSpaceAR(point);
this._addCircle(point);
}
_onTouchMoved(event) {
var point = event.touch.getLocation();
point = this.node.convertToNodeSpaceAR(point);
this._addCircle(point);
}
_onTouchEnd(event) {
var point = event.touch.getLocation();
point = this.node.convertToNodeSpaceAR(point);
this._addCircle(point);
this._checkProgress();
}
/**绘制函数*/
graphics: cc.Graphics;
_addCircle(point) {
// console.log("point---", point);
this.graphics = this.myMask.getComponent(cc.Mask)._graphics;
this._checkPoint(point);
this.graphics.circle(point.x, point.y, this.size);
this.graphics.fill();
}
private _checkPoint(point: cc.Vec2) {
for (let i = 0; i < 10; i++) {
let p = this.positions[i];
// 此点在关键点附近
if (p.x + this.value > point.x && p.x - this.value < point.x && p.y + this.value > point.y && p.y - this.value < point.y) {
this.positionProgress[i] = true;
}
console.log("p---", i, this.positionProgress[i]);
}
}
private _checkProgress() {
let result = this.positionProgress.filter((value) => {
return value;
}).length === this.positions.length;
console.log("result---", result);
if (result) {
this.myMask.children[0].active = false;
}
}
}
结束
整个功能代码不多,就是利用了mask组件中的graphics 属性进行 操作
本人是一枚又菜又爱玩的游戏开发者,如果有问题或者想要demo的可以私信我
好了,到这就say goodbye了,觉得有用的可以点个赞哦!