Files
MatchMaster/assets/Script/GuideHand.ts
T

86 lines
3.1 KiB
TypeScript

const { ccclass, property } = cc._decorator;
@ccclass
export default class GuideHand extends cc.Component {
@property(cc.Material)
rippleMaterial: cc.Material = null;
@property
swingAngle: number = 8;
@property
ringWidth: number = 0.1;
@property(cc.Vec2)
tipPosition: cc.Vec2 = cc.v2(-58, 148);
private baseAngle: number = 0;
private elapsed: number = 0;
private rippleDuration: number = 0;
private ripple: cc.Node = null;
private material: cc.Material = null;
onLoad() {
this.baseAngle = this.node.angle;
const ripple = this.ripple = new cc.Node("handRipple");
ripple.active = false;
ripple.parent = this.node.parent;
// 光圈放在手的后面,独立于手旋转,点击位置保持不动。
ripple.setSiblingIndex(this.node.getSiblingIndex());
const sprite = ripple.addComponent(cc.Sprite);
sprite.spriteFrame = this.node.getComponent(cc.Sprite).spriteFrame;
sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM;
ripple.setContentSize(220, 220);
sprite.setMaterial(0, this.rippleMaterial);
this.material = sprite.getMaterial(0);
this.material.setProperty("ringWidth", this.ringWidth);
this.material.setProperty("center", [0.5, 0.5]);
// 对齐 ripple_shrink:第三圈延后 0.6 秒,扩散到半径 0.475 时完全淡出。
this.rippleDuration = 0.6 + 0.475 / Number(this.material.getProperty("waveSpeed", 0));
}
onEnable() {
this.elapsed = 0;
this.node.angle = this.baseAngle;
this.ripple.active = false;
this.material.setProperty("time", 0);
}
update(dt: number) {
const pressDuration = 0.24;
const releaseDuration = 0.32;
const cycleDuration = pressDuration + this.rippleDuration;
const previousTime = this.elapsed;
this.elapsed = (this.elapsed + dt) % cycleDuration;
if (this.elapsed < previousTime) this.ripple.active = false;
const progress = this.elapsed < pressDuration
? this.elapsed / pressDuration
: Math.max(0, 1 - (this.elapsed - pressDuration) / releaseDuration);
this.node.angle = this.baseAngle + this.swingAngle * (1 - Math.cos(progress * Math.PI)) / 2;
if (this.elapsed < pressDuration) {
this.ripple.active = false;
return;
}
if (!this.ripple.active) {
// 按下瞬间的指尖坐标;松手时光圈不跟着移动。
const angle = this.node.angle;
this.node.angle = this.baseAngle + this.swingAngle;
const tip = this.node.convertToWorldSpaceAR(this.tipPosition);
this.ripple.setPosition(this.node.parent.convertToNodeSpaceAR(tip));
this.node.angle = angle;
this.ripple.active = true;
}
this.material.setProperty("time", this.elapsed - pressDuration);
}
onDisable() {
this.node.angle = this.baseAngle;
if (cc.isValid(this.ripple)) this.ripple.active = false;
}
onDestroy() {
if (cc.isValid(this.ripple)) this.ripple.destroy();
}
}