You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
315 lines
11 KiB
315 lines
11 KiB
import { _decorator, BlockInputEvents, Component, EventTouch, Label, Layout, Node, ScrollView, tween, UITransform, v3, Vec2, Vec3 } from "cc";
|
|
import { EGlobalEvent } from "../MesEvent/EGlobalEvent";
|
|
import { CameraCon } from "../CComEx/CameraCon";
|
|
import MesMgr from "../MesEvent/MesMgr";
|
|
|
|
//#region 引导UI视图
|
|
|
|
// 该脚本主要处理 引导是遮罩移动与遮罩聚焦 设置按钮点击时的处理
|
|
|
|
//#endregion
|
|
|
|
|
|
|
|
const { ccclass, property, menu } = _decorator;
|
|
@ccclass
|
|
@menu("引导/GuideUIView")
|
|
export default class GuideUIView extends Component {
|
|
@property(Node)
|
|
mGuidNode: Node;
|
|
@property(Node)
|
|
mGuideMask: Node;
|
|
@property(Node)
|
|
mBlackMask: Node;
|
|
@property(Node)
|
|
mTounch: Node;
|
|
@property(Node)
|
|
mClickSpine: Node;
|
|
@property(Node)
|
|
mSay_tips: Node;
|
|
@property(Label)
|
|
mtips: Label;
|
|
|
|
/**引导节点的原始父节点 */
|
|
private orgParent: Node = null;
|
|
|
|
/**目标遮罩与 目标节点的间隙 */
|
|
readonly offw = 8;
|
|
/**滑动组件列表 */
|
|
private mPrantScrollView: ScrollView[] = [];
|
|
/**目标节点 */
|
|
private targetNode: Node;
|
|
/**引导节点 事件屏蔽组件 */
|
|
private _GuidNodeBlockInputEvents: BlockInputEvents;
|
|
/**引导节点 */
|
|
private _GuidNodeUITransform: UITransform;
|
|
/*引导 遮罩节点 */
|
|
private _GuideMask: UITransform;
|
|
/**辅助属性 */
|
|
private _pos: Vec3;
|
|
/**点击次数 */
|
|
private _clickNum: number = 0;
|
|
/**提示文本 */
|
|
private _des: string = null;
|
|
/**节点宽度 */
|
|
private _GuideNodeWidth: number = 0;
|
|
/**节点高度 */
|
|
private _GuideNodeHight: number = 0;
|
|
/**按钮模式下的坐标偏移 */
|
|
private _btnOffset: Vec2 = new Vec2(0, 0);
|
|
|
|
private static _ins: GuideUIView;
|
|
public static get ins(): GuideUIView {
|
|
if (!this._ins) {
|
|
//director.getScene().addChild(ResLoad.GetRes(EResUrls.UIPrefabs("GuideCanvas"), EBundleName.Presets));
|
|
}
|
|
return this._ins;
|
|
}
|
|
|
|
protected onLoad() {
|
|
// MesMgr.on(EGlobalEvent.GUIDE_SHOW_FINGER, this.showFinger, this);
|
|
MesMgr.on(EGlobalEvent.GUIDE_HIDE_FINGER, this.hideFinger, this);
|
|
GuideUIView._ins = this.node.getComponent(GuideUIView);
|
|
this.orgParent = this.mGuidNode.parent;
|
|
this._init();
|
|
}
|
|
|
|
protected onDestroy(): void {
|
|
GuideUIView._ins = null;
|
|
// MesMgr.off(EGlobalEvent.GUIDE_SHOW_FINGER, this.showFinger, this);
|
|
MesMgr.off(EGlobalEvent.GUIDE_HIDE_FINGER, this.hideFinger, this);
|
|
}
|
|
|
|
/**初始化节点 */
|
|
private _init() {
|
|
this._pos = new Vec3();
|
|
this._GuidNodeBlockInputEvents = this.mGuidNode.getComponent(BlockInputEvents);
|
|
this._GuidNodeUITransform = this.mGuidNode.getComponent(UITransform);
|
|
this._GuideMask = this.mGuideMask.getComponent(UITransform);
|
|
let guidUITransform = this.mGuidNode.getComponent(UITransform);
|
|
this._GuideNodeHight = guidUITransform.height;
|
|
this._GuideNodeWidth = guidUITransform.width;
|
|
this.mGuidNode.setSiblingIndex(100);
|
|
this._hideGuideMask();
|
|
}
|
|
|
|
/**强行显示手指 */
|
|
showFinger(parent:Node, tNode: Node, des:string = "", offsetx:number = 0, offsety:number = 0){
|
|
let pos = v3();
|
|
this._GuidNodeUITransform.convertToNodeSpaceAR(tNode.getWorldPosition(), pos);
|
|
this.mClickSpine.setPosition(pos.x + offsetx, pos.y + offsety);
|
|
this.mClickSpine.active = true;
|
|
if(des.length > 0){
|
|
this._des = des;
|
|
this.showDes();
|
|
}
|
|
this.setGuideParent(parent);
|
|
}
|
|
/**强行隐藏手指 */
|
|
hideFinger(){
|
|
if(this.mClickSpine.active){
|
|
this.mClickSpine.active = false;
|
|
this.mSay_tips.active = false;
|
|
this.setGuideOrgParent();
|
|
}
|
|
}
|
|
|
|
/**设置引导节点的父节点,参数是兄弟节点 */
|
|
public setGuideParent(parent: Node) {
|
|
// this.mGuidNode.removeFromParent();
|
|
parent.addChild(this.mGuidNode);
|
|
}
|
|
|
|
/**还原引导节点的父节点 */
|
|
public setGuideOrgParent() {
|
|
// this.mGuidNode.removeFromParent();
|
|
this.orgParent.addChild(this.mGuidNode);
|
|
}
|
|
|
|
/**隐藏引导遮罩层级 */
|
|
private _hideGuideMask() {
|
|
this.mSay_tips.active = false;
|
|
this.mGuideMask.active = false;
|
|
this._GuidNodeBlockInputEvents.enabled = false;
|
|
this.mClickSpine.active = false;
|
|
}
|
|
|
|
/**显示引导遮罩层级 */
|
|
private _showGuideMask() {
|
|
this.mGuideMask.active = true;
|
|
this._GuidNodeBlockInputEvents.enabled = true;
|
|
}
|
|
|
|
/**移动并聚焦遮罩 */
|
|
private moveGuideMask(_pos: Vec3, time: number, width: number, height: number, callBack: Function) {
|
|
tween(this.mBlackMask).to(time, { position: new Vec3(-this._pos.x, -this._pos.y, this._pos.z) }).start();
|
|
tween(this.mGuideMask).to(time, { position: this._pos }).call(() => {
|
|
callBack();
|
|
}).start();
|
|
tween(this._GuideMask).to(time, { width: width, height: height }).start();
|
|
this.mClickSpine.setPosition(this._pos.x + this._btnOffset.x, this._pos.y + this._btnOffset.y);
|
|
}
|
|
|
|
/**移动遮罩结束 */
|
|
private moveEnd() {
|
|
this.freeze_ScrollView();
|
|
this.showDes();
|
|
this.scheduleOnce(() => {
|
|
this._GuidNodeBlockInputEvents.enabled = false;
|
|
this.targetNode.on(Node.EventType.TOUCH_END, this.onClick_GuideNode, this);
|
|
//this.targetNode.on('click',this.onClick_GuideNode,this);
|
|
/**播放手指动画 */
|
|
this.mClickSpine.active = true;
|
|
});
|
|
}
|
|
|
|
/**显示文本提示 为聚焦目标点添加提示 */
|
|
private showDes() {
|
|
if (this._des) {
|
|
this.mSay_tips.active = true;
|
|
CNodeUtils.switchText(this.mtips, this._des, true);
|
|
this.mSay_tips.getComponent(Layout)?.updateLayout();
|
|
let tempPosY = -30;
|
|
let sayUITransform = this.mSay_tips.getComponent(UITransform)
|
|
let tY = this._pos.y - tempPosY - sayUITransform.height / 2;
|
|
if (tY < (-this._GuideNodeHight / 2)) {
|
|
tY = this._pos.y + tempPosY;
|
|
} else {
|
|
tY = this._pos.y - tempPosY;
|
|
}
|
|
let tX = this._pos.x;
|
|
tX = Math.max(-(this._GuideNodeWidth / 2 - sayUITransform.width / 2) + 20, tX);
|
|
tX = Math.min(this._GuideNodeWidth / 2 - sayUITransform.width / 2 - 20, tX);
|
|
// this.mSay_tips.setPosition(tX, tY);
|
|
}
|
|
}
|
|
|
|
/**触发了目标节点 点击事件*/
|
|
private onClick_GuideNode() {
|
|
this._clickNum--;
|
|
if (this._clickNum <= 0) {
|
|
this.targetNode.off(Node.EventType.TOUCH_END, this.onClick_GuideNode, this);
|
|
this.unfreeze_ScrollView();
|
|
this._hideGuideMask();
|
|
MesMgr.event(EGlobalEvent.E_GUIDE_TO_NEXT);
|
|
}
|
|
ConsoleEx.Log("点击目标节点");
|
|
}
|
|
|
|
/**重置节点坐标与大小 */
|
|
private resetInitPos() {
|
|
this.mBlackMask.setPosition(0, 0)
|
|
this.mGuideMask.setPosition(0, 0);
|
|
let tUITransform: UITransform = this.node.getComponent(UITransform)
|
|
this._GuideMask.width = tUITransform.width;
|
|
this._GuideMask.height = tUITransform.height;
|
|
}
|
|
/**
|
|
* 设置引导目标节点
|
|
* @param tNode 目标节点
|
|
* @param clicknum 点击次数
|
|
* @param des 提示文本
|
|
* @param Opacity 设置遮罩的透明度 默认是 180
|
|
* @param time 遮罩聚焦时间
|
|
*/
|
|
setGuideNode(tNode: Node, clicknum: number = 1, des: string = null, Opacity: number = 180, offsetx:number = 0, offsety:number = 0, time: number = 0.38) {
|
|
this.targetNode = tNode;
|
|
this._clickNum = clicknum;
|
|
this._des = des;
|
|
this._btnOffset.x = offsetx;
|
|
this._btnOffset.y = offsety;
|
|
/**重置坐标 */
|
|
this.resetInitPos();
|
|
/**显示遮罩 */
|
|
this._showGuideMask();
|
|
/**显示 */
|
|
this.mGuideMask.active = true;
|
|
if (Opacity) {
|
|
CNodeUtils.setOpacity(this.mBlackMask, Opacity);
|
|
} else {
|
|
CNodeUtils.setOpacity(this.mBlackMask, 180);
|
|
}
|
|
this.tryGetScrollViewList(tNode);
|
|
this.scheduleOnce(() => {
|
|
this._GuidNodeUITransform.convertToNodeSpaceAR(tNode.getWorldPosition(), this._pos);
|
|
let tTransform: UITransform = tNode.getComponent(UITransform);
|
|
this.moveGuideMask(this._pos, time, tTransform.width + this.offw, tTransform.height + this.offw, this.moveEnd.bind(this));
|
|
}, 0.3);
|
|
}
|
|
/**
|
|
* 设置引导的目标世界坐标 请注意 目标一定要在屏幕内
|
|
* @param WordPos 世界坐标
|
|
* @param des 提示文本
|
|
*/
|
|
setGuidePos(WordPos: Vec3, des: string = null) {
|
|
this._des = des;
|
|
/**重置坐标 */
|
|
this.resetInitPos();
|
|
/**显示遮罩 */
|
|
this._showGuideMask();
|
|
this.mPrantScrollView = [];
|
|
/**显示 */
|
|
this.mGuideMask.active = true;
|
|
CNodeUtils.setOpacity(this.mBlackMask, 180);
|
|
this._pos = CameraCon.Ins.m_Camera.convertToUINode(WordPos, this.mGuidNode, this._pos);
|
|
this.moveGuideMask(this._pos, 0.38, 100, 100, () => {
|
|
this.showDes();
|
|
CNodeUtils.setActive(this.mTounch, true)
|
|
this.mTounch.on(Node.EventType.TOUCH_END, this.onClickBlackMask, this);
|
|
});
|
|
}
|
|
|
|
/**触发了遮罩层点击事件 */
|
|
onClickBlackMask() {
|
|
this.mTounch.off(Node.EventType.TOUCH_END, this.onClickBlackMask, this);
|
|
CNodeUtils.setActive(this.mTounch, false)
|
|
this.unfreeze_ScrollView();
|
|
this._hideGuideMask();
|
|
MesMgr.event(EGlobalEvent.E_GUIDE_TO_NEXT);
|
|
}
|
|
|
|
|
|
//#region 父节点组件处理
|
|
|
|
/**冻结滑动组件 */
|
|
private freeze_ScrollView() {
|
|
this.mPrantScrollView.forEach((value, index) => {
|
|
value["tmep_vertical"] = value.vertical;
|
|
value["tmep_horizontal"] = value.horizontal;
|
|
value.vertical = false;
|
|
value.horizontal = false;
|
|
});
|
|
}
|
|
|
|
/**解冻滑动组件 */
|
|
private unfreeze_ScrollView() {
|
|
this.mPrantScrollView.forEach((value, index) => {
|
|
value.vertical = value["tmep_vertical"];
|
|
value.horizontal = value["tmep_horizontal"];
|
|
});
|
|
this.mPrantScrollView = [];
|
|
}
|
|
|
|
/**尝试获取目标节点上方 所有滑动列表 */
|
|
private tryGetScrollViewList(tNode: Node) {
|
|
let list = this.findCom(tNode) as ScrollView[];
|
|
this.mPrantScrollView = list;
|
|
}
|
|
|
|
/**查找 滑动列表组件 */
|
|
private findCom(tNode: Node): ScrollView[] {
|
|
let arr: ScrollView[] = [];
|
|
let parent = tNode.parent;
|
|
if (parent) {
|
|
let com = parent.getComponent(ScrollView);
|
|
if (com && parent.activeInHierarchy && (com.vertical || com.horizontal)) {
|
|
arr.push(com)
|
|
}
|
|
arr = arr.concat(this.findCom(parent));
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
//#endregion
|
|
|
|
}
|