欢迎光临散文网 会员登陆 & 注册

游戏开奖功能组件《刮刮卡》特效实现

2021-11-09 17:25 作者:unity小能手  | 我要投稿

一、 需求分析

【1】实现手指触摸刮开效果;【2】优化:判断刮开与否(能否正常看到奖项)。

二、 游戏场景可视化编辑

三、 手指触摸刮刮卡动态刮开效果的实现

Mask为反向遮罩节点,必须确保大小和位置为(0,0)。

运用反向遮罩和绘图来实现。 首先为Mask节点添加Mask组件。记得将Inverted(即反向遮罩)勾上。

原理:类似于PS中的遮罩,或者沙画,比如你在玻璃上写了几个字,但是我在你玻璃上铺上了一层灰色的沙子(MaskBg),在沙子上撒了一点特仑苏,留下了“刮奖区”三个字。你想把下面的东西显示出来,只能拿到Mask节点上面的那把刷子,将沙子扫开。

新建GameMgr.js,并挂载到Canvas节点上。代码如下:

onLoad () {

// 获取遮罩子节点,再获取其上面的Mask遮罩组件

this.mask = this.node.getChildByName("Mask").getComponent(cc.Mask);

this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);

this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);

this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);

this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);

},

onTouchStart(e){

this.scratch(e);

},

onTouchMove(e){

this.scratch(e);

},

onTouchEnd(e){

this.scratch(e);

},

onTouchCancel(e){

},

// 刮开操作

scratch(e){

// 【1】获取触摸点相对于当前节点的锚点的坐标

var pos = this.getPos(e);

// 【2】根据触摸点位置刮开图层,添加一个形状

this.addShape(pos);

},

getPos(e){

return this.node.convertToNodeSpaceAR(e.getLocation());

},

addShape(pos){

var graphics = this.mask._graphics;

graphics.fillRect(pos.x, pos.y, 50, 30);

},

四、 随机刮开奖项

在GameMgr.js中增加如下代码即可:

start () {

var res = Math.floor(Math.random()*4);

this.initPrize(res);

},

initPrize(res){

this.prizeInfo = ["一等奖\n胖妞一枚","二等奖\n白鹅一只","三等奖\n小三一位","再来一次!"];

this.prizeItemLabel = cc.find("Canvas/PrizeRoot/PrizeItem").getComponent(cc.Label);

this.prizeItemLabel.string = this.prizeInfo[res];

},

五、 刮开面积计算与刮开结果后的回调处理

增加当擦除到70%的时候所有texture消失,执行回调事件。

本方法是先根据接触点的大小在图片上排列一个点矩阵,每个点矩阵有一个检测范围且只能被检测一次,每次被检测刮开的数都会执行++操作,直到接触点等于目标点(刮开的范围可以自己设置)后,遮罩的图片消失,并执行回调函数。

注:该方法不用设置主节点Mask节点的大小,在代码会改变它的大小的。

1. 初始化遮罩层的记录点数组

properties: {

maskBg:{type:cc.Node, default:null,tooltip:"刮层节点",},

scratchRadiuX:{type:cc.Float, default:20,tooltip:"每次刮开大小的宽度半径"},

scratchRadiuY:{type:cc.Float, default:10,tooltip:"每次刮开大小的高度半径"},

},

initMaskPoints(){

var rows = Math.floor(this.maskBg.height/(this.scratchRadiuY*2));

var cols = Math.floor(this.maskBg.width/(this.scratchRadiuY*2));

rows = Math.ceil(rows/2);

cols = Math.ceil(cols/2);

this.hidePoints = []; // 隐藏的数据点数组

for(let i=-rows; i<=rows; i++){

for(let j=-cols; j<=cols; j++){

this.hidePoints.push({"x":j, "y":i});

}

}

// 隐藏的数据点数量

this.hidePointsNum = this.hidePoints.length;

console.log("this.hidePoints",this.hidePoints,"数量:",this.hidePointsNum);

},

onLoad () {

this.initMaskPoints(); // 初始化遮罩点

2. 刮出面积计算

// 刮开操作

scratch(e){

// 【1】获取触摸点相对于当前节点的锚点的坐标

var pos = this.getPos(e);

// 【2】根据触摸点位置刮开图层,添加一个形状

this.addShape(pos);

// 【3】刮开面积计算

this.calcScratchArea(pos);

},

calcScratchArea(pos){

var x = Math.floor(pos.x/(this.scratchRadiuX));

var y = Math.floor(pos.y/(this.scratchRadiuY));

for(let i=0; i<this.hidePoints.length; i++){

if(x===this.hidePoints[i].x && y===this.hidePoints[i].y){

this.hidePoints.splice(i, 1);

break;

}

}

},

3. 回调处理

添加一个对话框,隐藏,当刮开面积达到一定比例后,说明用户已经刮开奖项了,可以弹出对话框提示领取方式等。

if(this.hidePoints.length/this.hidePointsNum<0.6){

this.showDialog();

}

},

showDialog(){

var prompt = this.resultDialog.getChildByName("bg").getChildByName("info");

prompt.getComponent(cc.Label).string = this.prizeItemLabel.string;

this.resultDialog.active = true;

// 添加对话框动态效果

this.resultDialog.opacity = 0;

this.resultDialog.runAction(cc.fadeTo(0.3, 255));

},

4. 思考:只刮开周边区域没看到文字也弹出不合理

方法一:缩放maskBg即可(如果奖项没有显示在中央则会不合理)

方法二:如下,添加覆盖奖项的节点,调整位置、大小和透明度。

之后,运行结果如下(即使周边全部刮开,内容没显示,也不会弹出兑奖方式):


六、 小结

1、做游戏开发,首先要学会将任务拆解,其次要设计好游戏中的主要算法,考虑好采用的数据结构,之后,逐步实现步步为营。

2、有问题的朋友,可以联系我们获取本节课完整视频。


游戏开奖功能组件《刮刮卡》特效实现的评论 (共 条)

分享到微博请遵守国家法律