【CocosCreator】利用遮罩Mask实现单边开门效果

实现思路

首先新建一个新的遮罩节点(全部采用默认属性),将其大小设为门的大小,然后将其摆放到门所在的位置,如下图:

接下来,给该遮罩节点添加一个精灵图子节点,然后将门的精灵图放上去,调整大小和位置,使得锚点和遮罩节点的锚点重合,如下图:

此时,手动改变门精灵图节点 position.x 的值,就可以发现门在左右移动,而且超过了遮罩节点的边界部分被隐藏起来了,基本上是实现了开关门的效果了。

面板属性分析及定义

接下来要通过代码来控制门的开关,给遮罩节点添加一个脚本组件 door-control.ts ,然后思考,想要开关门,我们需要知道门关闭的时候的位置以及门开启的时候的位置,因此我们需要定义两个面板属性openPos和closePos,因为是保存的是门的坐标,所以这俩属性的类型应该是二维向量Vce2类型,然后就是我们要知道门此时的状态是开启还是关闭,因为我们可能会需要根据门的状态不同而执行不同的逻辑,所以还需要一个面板属性isClose,该属性为true的时候表示门处于关闭状态。

即我们需要在 door-control.ts 脚本中定义3个面板属性,如下:

ts 复制代码
@property({ type: CCBoolean, displayName: '是否已关门' })
private isClose: boolean = false

@property({ type: Vec2, displayName: '开门位置' })
private openPos: Vec2 = new Vec2(0, 0)

@property({ type: Vec2, displayName: '关门位置' })
private closePos: Vec2 = new Vec2(0, 0)

然后来到场景编辑器,点击选中遮罩节点,然后看向属性检查器,可以看到刚刚定义的面板属性出来了:

接下来,我们选中遮罩节点中的门精灵图,将其位置改成开门的状态,然后记录其位置,因为一开始我们是让遮罩和精灵图的锚点重合了,所以开门位置基本上都应该是 xy(0,0) 点,然后移动x轴,将其改变成关门状态,记录精灵图此时的位置,然后填写到遮罩节点的关门位置属性上,还是因为一开始的锚点重合,正常来说,关门也只有x轴的值改变,因此关门位置的值应该是 xy(x1,0) 点;

开关门逻辑

接下来回到脚本组件 door-control.ts 中,定义两个方法 closeDooropenDoor,分别控制关门和开门的逻辑。

当然,在此之前,我们还需要定义一个私有属性doorSprite,用来保存遮罩节点下的门精灵图节点,这一段逻辑写在组件的start生命周期中,如下:

ts 复制代码
start() {
	this.doorSprite = this.node.getComponentInChildren(Sprite)
}

注意,通过getComponentInChildren方法获取门精灵图节点的话,要求遮罩节点下只能存在一个门精灵图节点,如果是双开门的,需要其他获取逻辑,但是保存节点这一步是为了后面改变节点的位置,只要理解了这个就行了。

开关门的逻辑整体基本相同,都是通过cocosCreator内置的tween来改变节点的位置。

closeDoor

ts 复制代码
closeTheDoor() {
	tween(this.doorSprite.node)
		.to(0.5, { position: new Vec3(this.openPos.x, 0, 0) })
		.call(() => this.isClose = true)
		.start()
}

openDoor

ts 复制代码
openTheDoor() {
	tween(this.doorSprite.node)
		.to(0.5, { position: new Vec3(this.closePos.x, 0, 0) })
		.call(() => this.isClose = false)
		.start()
}

效果展示

为了看到效果,可以在start生命周期中,通过定时器根据当前门的开闭状态,每秒执行一次开门或者关门操作,如下:

ts 复制代码
this.schedule(() => {
	if (this.isClose) {
		this.openTheDoor()
	} else {
		this.closeTheDoor()
	}
}, 1)

实际效果如下:

扩展

上面实现的是单门往右边开(其实是左右开都行),然后还有一种门上下开的情况,这个时候我们要做的就是在tween中改变y轴的位置即可。

然后单门之后还有双门,单门就是获取一个门精灵图节点,然后改变其位置,双门就是获取两个,然后分别将其往左和往右移动即可,或者也可以看成是两个单门,方向不同即可。

相关推荐
To_OC4 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic5 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy5 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志5 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble6 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯7 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜8 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司8 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
kaiking_g9 小时前
vue项目中,静态导入 vs 动态导入 详解
前端·javascript·vue.js
江华森9 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http